@@ -14,38 +14,8 @@ HTTP/1.1 and HTTP/2 support. Pure Erlang. Zero dependencies.
1414
1515Fast. Small API. Proper HTTP/1.1 and HTTP/2 support. Works with both protocols transparently.
1616
17- Built to replace ` httpc ` with better performance and cleaner code.
18-
19- ## HTTP/2 Compliance
20-
21- ** 156 tests** covering RFC 7540 (HTTP/2) and RFC 7541 (HPACK). All frame types, stream states, flow control, priority handling, HPACK compression, and error conditions.
22-
23- Tested against [ h2-client-test-harness] ( https://github.com/nomadlabsinc/h2-client-test-harness ) . ** 100% pass rate** .
24-
2517## Quick Start
2618
27- ``` erlang
28- % % HTTP/1.1
29- {ok , Conn } = gen_http :connect (http , " httpbin.org" , 80 ),
30- {ok , Conn2 , Ref } = gen_http :request (Conn , <<" GET" >>, <<" /get" >>, [], <<>>),
31-
32- % % Collect response in active mode (default)
33- receive
34- Msg ->
35- case gen_http :stream (Conn2 , Msg ) of
36- {ok , Conn3 , [{status , Ref , 200 }, {headers , Ref , Headers }, {data , Ref , Body }, {done , Ref }]} ->
37- io :format (" Body: ~s~n " , [Body ])
38- end
39- end .
40-
41- % % HTTP/2 (automatic via ALPN)
42- {ok , Conn } = gen_http :connect (https , " google.com" , 443 ),
43- {ok , Conn2 , Ref } = gen_http :request (Conn , <<" GET" >>, <<" /" >>, [], <<>>),
44- % % Same API, different protocol
45- ```
46-
47- ## Installation
48-
4919Add to your ` rebar.config ` :
5020
5121``` erlang
@@ -54,86 +24,44 @@ Add to your `rebar.config`:
5424]}.
5525```
5626
57- ## Examples
58-
59- ### Simple GET Request
27+ Send a request:
6028
6129``` erlang
6230{ok , Conn } = gen_http :connect (http , " httpbin.org" , 80 ),
6331{ok , Conn2 , Ref } = gen_http :request (Conn , <<" GET" >>, <<" /get" >>, [], <<>>),
6432
65- % % Active mode - receive messages
66- receive Msg ->
67- {ok , Conn3 , Responses } = gen_http :stream (Conn2 , Msg ),
68- io :format (" Responses: ~p~n " , [Responses ])
33+ receive
34+ Msg ->
35+ case gen_http :stream (Conn2 , Msg ) of
36+ {ok , Conn3 , [{status , Ref , 200 }, {headers , Ref , Headers }, {data , Ref , Body }, {done , Ref }]} ->
37+ io :format (" Body: ~s~n " , [Body ])
38+ end
6939end .
7040```
7141
72- ### POST with Body
73-
74- ``` erlang
75- {ok , Conn } = gen_http :connect (http , " httpbin.org" , 80 ),
76-
77- Headers = [{<<" content-type" >>, <<" application/json" >>}],
78- Body = <<" {\" hello\" : \" world\" }" >>,
79-
80- {ok , Conn2 , Ref } = gen_http :request (Conn , <<" POST" >>, <<" /post" >>, Headers , Body ).
81- ```
82-
83- ### HTTPS with HTTP/2
42+ HTTPS with automatic HTTP/2 negotiation:
8443
8544``` erlang
86- % % ALPN automatically negotiates HTTP/2 if available
8745{ok , Conn } = gen_http :connect (https , " www.google.com" , 443 ),
8846{ok , Conn2 , Ref } = gen_http :request (Conn , <<" GET" >>, <<" /" >>, [], <<>>).
47+ % % Same API, different protocol
8948```
9049
91- ### Passive Mode (Blocking)
92-
93- ``` erlang
94- {ok , Conn } = gen_http :connect (http , " httpbin.org" , 80 , #{mode => passive }),
95- {ok , Conn2 , Ref } = gen_http :request (Conn , <<" GET" >>, <<" /get" >>, [], <<>>),
96-
97- % % Blocking receive
98- {ok , Conn3 , Responses } = gen_http :recv (Conn2 , 0 , 5000 ),
99- io :format (" Responses: ~p~n " , [Responses ]).
100- ```
101-
102- ### Connection Reuse
50+ See the [ Getting Started] ( docs/getting-started.md ) guide for POST requests, passive mode, response collection loops, and more.
10351
104- ``` erlang
105- {ok , Conn } = gen_http :connect (http , " httpbin.org" , 80 ),
106-
107- % % First request
108- {ok , Conn2 , Ref1 } = gen_http :request (Conn , <<" GET" >>, <<" /get" >>, [], <<>>),
109- % % ... handle response ...
52+ ## HTTP/2 Compliance
11053
111- % % Second request on same connection
112- {ok , Conn3 , Ref2 } = gen_http :request (Conn2 , <<" GET" >>, <<" /headers" >>, [], <<>>),
113- % % ... handle response ...
54+ ** 156 tests** covering RFC 7540 (HTTP/2) and RFC 7541 (HPACK). All frame types, stream states, flow control, priority handling, HPACK compression, and error conditions.
11455
115- {ok , _ } = gen_http :close (Conn3 ).
116- ```
56+ Tested against [ h2-client-test-harness] ( https://github.com/nomadlabsinc/h2-client-test-harness ) . ** 100% pass rate** .
11757
118- ### Error Handling
58+ ## Documentation
11959
120- ``` erlang
121- case gen_http :connect (http , " example.com" , 80 ) of
122- {ok , Conn } ->
123- case gen_http :request (Conn , <<" GET" >>, <<" /" >>, [], <<>>) of
124- {ok , Conn2 , Ref } ->
125- handle_success (Conn2 , Ref );
126- {error , Conn2 , Reason } ->
127- % % Structured errors: {transport_error, _}, {protocol_error, _}, {application_error, _}
128- case gen_http :is_retriable_error (Reason ) of
129- true -> retry_request ();
130- false -> handle_permanent_error (Reason )
131- end
132- end ;
133- {error , Reason } ->
134- io :format (" Connection failed: ~p~n " , [Reason ])
135- end .
136- ```
60+ - [ Getting Started] ( docs/getting-started.md ) -- installation, first request, collecting responses
61+ - [ Architecture] ( docs/architecture.md ) -- process-less design, module layout, protocol negotiation
62+ - [ Active and Passive Modes] ( docs/active-and-passive-modes.md ) -- choosing the right I/O model
63+ - [ Error Handling] ( docs/error-handling.md ) -- structured errors, retries, pattern matching
64+ - [ SSL Certificates] ( docs/ssl-certificates.md ) -- TLS config, custom CAs, ALPN
13765
13866## Testing
13967
@@ -156,12 +84,6 @@ rebar3 ct --suite=h2_compliance_SUITE
15684
15785Early development. API may change.
15886
159- ## Inspiration
160-
161- - [ Mint] ( https://github.com/elixir-mint/mint ) - HTTP client for Elixir
162- - [ httpcore] ( https://github.com/encode/httpcore ) - Minimal HTTP client for Python
163- - [ gun] ( https://github.com/ninenines/gun ) - HTTP client for Erlang
164-
16587## License
16688
16789Apache 2.0
0 commit comments