aboutsummaryrefslogtreecommitdiffstats
path: root/src/gun_http.erl
AgeCommit message (Collapse)Author
2021-02-07Initial commit for Gun poolsLoïc Hoguin
The approach taken here is very similar to what browsers are doing. A separate pool is created for each host/port/scope. The authority (host header) is used to determine which pool will execute requests. A connection process is semi-randomly chosen, from the connections that have capacity. Maximum capacity is determined by the protocol (the HTTP/2 setting set by the server is used, for example). Multiple processes can process requests/responses on the same connection concurrently. There is no need to "give back" the response to the pool, the number of ongoing streams is maintained via an event handler. The implementation is currently not strict, there may be more attempts to create requests than there is capacity. I'm not sure if it should be made strict or if Gun should just wait before sending requests (it only matters in the HTTP/2 case at the moment). When there is no connection with capacity available in the pool (because they have too many streams, or are reconnecting, or any other reason), checking out fails. There is no timeout to wait for a connection to be available. On the other hand the checkout_retry option allows setting multiple timeouts to retry checking out a connection. Each retry attempt's wait time can have a different value. The initial implementation of this work was sponsored by Kobil and made at the suggestion of Ilya Khaprov.
2020-11-12Fix a low hanging fruit todoLoïc Hoguin
2020-11-12Fail fast while closing if reconnect is offViktor Söderqvist
If a request/headers/connect/ws_upgrade is created when a connection is in state 'closing', such as after receiving an HTTP/2 GOAWAY frame or an HTTP/1.1 "Connection: close" header, an error message is sent back to the caller immediately, if reconnect is off (that is if the option retry is set to 0). This allows an application to retry the request on another connection without waiting for all streams on the current connection to complete.
2020-11-12Update copyright yearsLoïc Hoguin
2020-11-12Review and remove many todosLoïc Hoguin
HTTP/1.1 Upgrade to HTTP/2 will not be implemented. There are discussions for this functionality to be removed from the HTTP/2 spec. HTTP/1.1 Upgrade to TLS will most likely not be implemented.
2020-11-06Make CONNECT responses produce a response_end eventLoïc Hoguin
While the stream has not ended, the response has.
2020-11-02Initial implementation of Websocket over HTTP/2http2-websocketLoïc Hoguin
2020-10-21Fix cookie handling when tunnel and origin schemes mismatchLoïc Hoguin
The cookie_ignore_informational has been moved to http_opts and http2_opts. Also fix an issue when using 'protocols' in gun:open. When connecting via TLS the protocol's options were discarded.
2020-10-19Fix cookies for tunnelsLoïc Hoguin
There are still small issues left to fix. In particular the set_cookie command should be replaced with doing the same in the protocol itself so that the scheme is correct. So CookieStore must be propagated to all callbacks.
2020-10-16Add or fix events inside or related to CONNECT tunnelsLoïc Hoguin
2020-10-03Fix test suites failing due to previous breaking changesLoïc Hoguin
2020-10-03Add tunnel_SUITE testing all 3-layer combinationsLoïc Hoguin
The test suite is 216 tests with a tunnel created via two proxies leading to one origin server. The tests are for example socks5_h2_https where socks5 identifies the first SOCKS5 proxy, h2 the second HTTP/2 CONNECT proxy and https the secure HTTP/1.1 origin server. The test not only sets up the tunnel and does a request (or sends/receives data in the case of raw origin servers) but also confirms that the stream_info and info data is correct.
2020-09-21Initial success for h2 CONNECT -> https CONNECT -> httpsLoïc Hoguin
2020-09-21Add a gun:stream_ref() type and fix DialyzerLoïc Hoguin
2020-09-21Refactor protocol handling via gun_protocolsLoïc Hoguin
2020-09-21Replace gun_tunnel_up/3 message with /4 variantLoïc Hoguin
Also fixes all the tests. Lots of work remain around protocols (how best to pass the base stream_ref to them? maybe the current solution, maybe a new argument to Protocol:init) and strengthen the concept of stream_ref, at least with its own type.
2020-09-21Rename the 3-arity gun_socks_up to gun_tunnel_upLoïc Hoguin
2020-09-21Add HTTP/2 CONNECT tests with Cowboy as originLoïc Hoguin
2020-09-21Add the base_stream_ref to gun_http/gun_http2Loïc Hoguin
2020-09-21Make gun:stream_info/2 return intermediaries for HTTP/2 CONNECTLoïc Hoguin
2020-04-16Empty the commands queue when returningLoïc Hoguin
2020-03-25Fix host/:authority header when connecting to an IPv6 addressLoïc Hoguin
2020-03-12Make Gun use the cookie store when configured toLoïc Hoguin
2019-10-01Don't try upgrading 101 responses with no/bad Upgrade headerLoïc Hoguin
Also rework the different handle_head scenarios in separate functions.
2019-09-26Remove UnprocessedStreams from the gun_down messageLoïc Hoguin
2019-09-26Add reply_to option to ws_upgrade; remove notowner entirelyLoïc Hoguin
The reply_to option is also propagated when we switch protocols.
2019-09-24Add auto-ping to Websocket and a silence_pings optionLoïc Hoguin
The auto-ping will at regular interval send a ping frame. The silence_pings option defaults to true. It can be set to false when the user needs to receive ping/pong frames.
2019-09-24Initial support for raw send/recv operationsLoïc Hoguin
Gun can now be used to send or receive arbitrary data in the following scenarios: * Directly after connecting to a server (this is not terribly useful but it works nevertheless due to the Gun architecture) * After connecting through one or more Socks and/or HTTP proxies. This allows using Gun's proxy capabilities to access servers located beyond firewalls. * After performing an HTTP/1.1 Upgrade. This allows using Gun to implement custom protocols that require upgrading from an HTTP/1.1 connection. As there is still no support for HTTP/2 CONNECT for the time being, there are no relevant streams attached to those use cases and therefore the raw protocol currently expects users to use 'undefined' as the StreamRef value. This is not a final decision and will most likely produce a Dialyzer warning at this time.
2019-09-23Properly error out on HTTP/1.0 Websocket upgrade attemptsLoïc Hoguin
2019-09-23Reduce the #http_state sizeLoïc Hoguin
The version is still kept in the state even if it's an option because it's useful to have there and it's just a tiny atom.
2019-09-22Document Socks supportLoïc Hoguin
Also correct various Socks related types. This commit also adds a new gun:protocols/0 type as a simpler way of describing preferred protocols. The protocol/opts tuple is also documented. This commit also fixes an issue with the default value for the preferred protocols when using CONNECT over TLS. It was mistakenly not enabling http2 by default.
2019-09-22Add more tests with two Socks5 proxiesLoïc Hoguin
We now properly support TCP across two TLS proxies, and TLS across two TCP/TLS proxies.
2019-09-22Always switch_protocolLoïc Hoguin
When doing a CONNECT from http to http or from socks to socks we may want to use different configuration options. Switching the protocol explicitly helps us achieve that. It will also signal through events that a protocol switch occurred.
2019-09-22Rework state transitions resulting from from protocol changesLoïc Hoguin
2019-09-22Improve retrieval of keepalive optionLoïc Hoguin
2019-09-22Supports going through multiple Socks proxiesLoïc Hoguin
This commit also reworks the switch_protocol command. The `P | {P, Opts}` type is used here as well. This allows us to remove the code specific to Websocket. In addition a few new protocol functions allow us to declare what's the name of the options key for the protocol and what the capabilities are with regard to keepalive.
2019-09-22Simplify HandshakeEventLoïc Hoguin
2019-09-22Move and merge all TLS handshakes to the main Gun codeLoïc Hoguin
There's now an initial_tls_handshake state for the initial connection with handshake, and tls_handshake state for any subsequent TLS handshakes. The Socks5 code will be able to reuse this tls_handshake state to perform its own transport switches.
2019-09-05Implement graceful shutdownLoïc Hoguin
The graceful shutdown is implemented through a new 'closing' state. This state is entered under different circumstances depending on the protocol. The gun:shutdown/1 function is now implemented and documented. It allows shutting down the connection gracefully regardless of the current state of the connection and for all protocols. The behavior is entirely dependent on the protocol. For HTTP/1.1 the connection stays up only until after the current stream is complete; other streams are immediately canceled. For HTTP/2 a GOAWAY frame is sent and existing streams continue to be processed. The connection is closed after all streams are processed and the server's GOAWAY frame is received. For Websocket a close frame is sent. The connection is closed when receiving the server's close frame. In all cases the closing_timeout option defines how long we wait, as a maximum, before closing the connection after the graceful shutdown was started. The graceful shutdown is also initiated when the owner process goes away; when sending an HTTP/1.1 request with the connection: close header; when receiving an HTTP/1.1 response with the connection: close header; when receiving an HTTP/1.0 response without a connection header; when the server sends a GOAWAY HTTP/2 frame; or when we send or receive a Websocket close frame. Along with these changes, the gun:ws_send/2 function now accepts a list of frames as argument. Those frames may include a close frame that initiates the graceful shutdown.
2019-08-05Add flow controlLoïc Hoguin
Flow control is disabled by default. The initial flow value must be set to enable it (either for the entire connection or on a per-request basis). Flow applies to all HTTP streams as well as Websocket. HTTP/2 pushed streams receive the same value as their originating stream.
2019-07-26Add tls_handshake events for CONNECT through TLS proxiesLoïc Hoguin
2019-07-25Add tls_handshake events for CONNECT through TCP proxiesLoïc Hoguin
2019-07-25Fix missing response_end event for HTTP/1.0 body_closeLoïc Hoguin
2019-07-24Add the cancel event for local/remote stream cancellationLoïc Hoguin
2019-07-15Add Websocket frames related eventsLoïc Hoguin
2019-07-13Add ws_upgrade/protocol_changed eventsLoïc Hoguin
And ensure that Websocket triggers all the request/response events.
2019-07-03Add the response_trailers eventLoïc Hoguin
2019-07-03Add the response_start eventLoïc Hoguin
Thought it needed cow_http2_machine changes but everything was available. For HTTP/1.1 it is triggered when receiving data while expecting headers. For HTTP/2 it is triggered after we have received a HEADERS frame for streams in idle state.
2019-07-02Add response_inform/response_headers/response_end eventsLoïc Hoguin
This covers many scenarios but more need to be added.
2019-06-02Add request_start, request_headers and request_end eventsLoïc Hoguin