aboutsummaryrefslogtreecommitdiffstats
path: root/test/handlers
AgeCommit message (Collapse)Author
2025-02-11Improve the set_resp_headers_list testLoïc Hoguin
2025-02-11Add support for lists in cowboy_req:set_resp_headersLoïc Hoguin
This is meant to be used with clients such as Gun to simplify proxying and similar operations. The set-cookie header must not be set this way so there is still some extra processing to be done to fully translate a Gun response into a Cowboy response.
2025-02-09Detect invalid content_types_provided return values earlierLoïc Hoguin
Before this change invalid return values would be detected via unhelpful error messages such as [1] and the closing of the connection. [1] Bad value on output port 'tcp_inet'
2025-02-08Properly handle external exits of request processesLoïc Hoguin
Because the exit reason doesn't include the stacktrace they were ignored. Now they are properly handled. The error message was changed slightly to accomodate.
2025-02-05Implement dynamic socket buffer sizesLoïc Hoguin
Cowboy will set the socket's buffer size dynamically to better fit the current workload. When the incoming data is small, a low buffer size reduces the memory footprint and improves responsiveness and therefore performance. When the incoming data is large, such as large HTTP request bodies, a larger buffer size helps us avoid doing too many binary appends and related allocations. Setting a large buffer size for all use cases is sub-optimal because allocating more than needed necessarily results in a performance hit (not just increased memory usage). By default Cowboy starts with a buffer size of 8192 bytes. It then doubles or halves the buffer size depending on the size of the data it receives from the socket. It stops decreasing at 8192 and increasing at 131072 by default. To keep track of the size of the incoming data Cowboy maintains a moving average. It allows Cowboy to avoid changing the buffer too often but still react quickly when necessary. Cowboy will increase the buffer size when the moving average is above 90% of the current buffer size, and decrease when the moving average is below 40% of the current buffer size. The current buffer size and moving average are propagated when switching protocols. The dynamic buffer is implemented in HTTP/1, HTTP/2 and HTTP/1 Websocket. HTTP/2 Websocket has it disabled because it doesn't interact directly with the socket; in that case it is HTTP/2 that has a dynamic buffer. The dynamic buffer provides a very large performance improvement in many scenarios, at minimal cost for others. Because it largely depend on the underlying protocol the improvements are no all equal. TLS and compression also impact the results. The improvement when reading a large request body, with the requests repeated in a fast loop are: * HTTP: 6x to 20x faster * HTTPS: 2x to 6x faster * H2: 4x to 5x faster * H2C: 20x to 40x faster I am not sure why H2C's performance was so bad, especially compared to H2, when using default buffer sizes. Dynamic buffers make H2C a lot more viable with default settings. The performance impact on "hello world" type requests is minimal, it goes from -5% to +5% roughly. Websocket improvements vary again depending on the protocol, but also depending on whether compression is enabled: * HTTP echo: roughly 2x faster * HTTP send: roughly 4x faster * H2C echo: roughly 2x faster * H2C send: 3x to 4x faster In the echo test we reply back, and Gun doesn't have the dynamic buffer optimisation, so that probably explains the x2 difference. With compression however there isn't much improvement. The results are roughly within -10% to +10% of each other. Zlib compression seems to be a bottleneck, or at least to modify the performance profile to such an extent that the size of the buffer does not matter. This happens to randomly generated binary data as well so it is probably not caused by the test data.
2025-01-24Add initial http_perf_SUITELoïc Hoguin
2025-01-16Websocket: Allow setting the max_frame_size option dynamicallyLoïc Hoguin
This can be used to limit the maximum frame size before some authentication or other validation is completed.
2024-03-26Initial HTTP/3 implementationhttp3Loïc Hoguin
This includes Websocket over HTTP/3. Since quicer, which provides the QUIC implementation, is a NIF, Cowboy cannot depend directly on it. In order to enable QUIC and HTTP/3, users have to set the COWBOY_QUICER environment variable: export COWBOY_QUICER=1 In order to run the test suites, the same must be done for Gun: export GUN_QUICER=1 HTTP/3 support is currently not available on Windows due to compilation issues of quicer which have yet to be looked at or resolved. HTTP/3 support is also unavailable on the upcoming OTP-27 due to compilation errors in quicer dependencies. Once resolved HTTP/3 should work on OTP-27. Because of how QUIC currently works, it's possible that streams that get reset after sending a response do not receive that response. The test suite was modified to accomodate for that. A future extension to QUIC will allow us to gracefully reset streams. This also updates Erlang.mk.
2024-01-23Fix match_qs with constraints when key is not presentgeeksilva97
Original fix by Ali Farhadi <[email protected]>.
2024-01-16REST: Allow generate_etag to return undefinedLoïc Hoguin
This allows conditionally generating an etag.
2024-01-16Confirm Websocket pong frames are received by handlersLoïc Hoguin
2024-01-15Reject responses with explicit set-cookie headergeeksilva97
LH: The tests received a lot of fixes and tweaking. I also reworded the error message to be more concise.
2024-01-09Better error message when trying to reply twiceLoïc Hoguin
Also crash if trying to push after a reply was sent.
2024-01-09Improve the error when trying to send a 204/304 with a bodyLoïc Hoguin
2024-01-08Document body reading in auto modeLoïc Hoguin
It is now tested both via cowboy_req:read_body and via cowboy_req:cast. Removes a bad example from the guide of body reading with period of infinity, which does not work.
2024-01-08Ensure HTTP/1.1 Websocket resets the trap_exit flagLoïc Hoguin
While we are identified as a supervisor in the tree, we no longer manage children processes at that point, so do not need to trap exit signals. Users can still enable trap_exit if they prefer to.
2024-01-05Don't automatically compress when response has etagLoïc Hoguin
In the cowboy_compress_h stream handler. Otherwise this could cause issues with caching, with the etag being the same for compressed/uncompressed content. Users that wish to send etags AND compress will have to do it manually for the time being.
2024-01-04Rework and improve the decompress stream handlerLoïc Hoguin
The read buffer was changed into an iovec to avoid doing too many binary concatenations and allocations. Decompression happens transparently: when decoding gzip, the content-encoding header is removed (we only decode when "gzip" is the only encoding so nothing remains). We always add a content_decoded key to the Req object. This key contains a list of codings that were decoded, in the reverse order in which they were. Currently it can only be empty or contain <<"gzip">> but future improvements or user handlers may see it contain more values. The option to disable decompression was renamed to decompress_enabled and defaults to true. It is no longer possible to enable/disable decompression in the middle of reading the body: this ensures that the data we pass forward is always valid. Various smaller improvements were made to the code, tests and manual pages.
2023-12-21Add cowboy_decompress_h stream handlerjdamanalo
2023-12-21Optionally reset the idle timeout when sending dataRobert J. Macomber
A new option reset_idle_timeout_on_send has been added. When set to 'true', the idle timeout is reset not only when data is received, but also when data is sent. This allows sending large responses without having to worry about timeouts triggering. The default is currently unchanged but might change in a future release. LH: Greatly reworked the implementation so that the timeout gets reset on almost all socket writes. This essentially completely supersets the original work. Tests are mostly the same although I refactored a bit to avoid test code duplication. This commit also changes HTTP/2 behavior a little when data is received: Cowboy will not attempt to update the window before running stream handler commands to avoid sending WINDOW_UPDATE frames twice. Now it has some small heuristic to ensure they can only be sent once at most.
2023-12-15Increase loop_handler_timeout timeoutsLoïc Hoguin
It seems that macOS GH runners don't do timeouts well.
2023-12-15Add timeout to cowboy_loopjdamanalo
LH: I have added a test that does both hibernate and timeout and fixed a related issue. I also tweaked the docs and tests.
2023-12-14Change send_timeout_close test to accomodate macOSLoïc Hoguin
2023-12-12Handle socket errors in HTTP/1.1 and HTTP/2Loïc Hoguin
Doing so will let us notice when the connection is gone instead of waiting for timeouts, at least in the cases where the remote socket was closed properly. Timeouts are still needed in case of TCP half-open problems. This change means that the order of stream handler commands is more important than before because socket errors may occur during the processing of commands.
2023-12-12Add test for send_timeout_closeSergei Shuvatov
LH: I reworked the test a little and added the same test for HTTP/2 so that both HTTP/1.1 and HTTP/2 get the issue fixed.
2020-11-27AcceptCallback may now return created/see_other tuples for POSTMartin Björklund
They replace and deprecate the {true,URI} return value.
2020-11-27Graceful shutdownViktor Söderqvist
Note: This commit makes cowboy depend on cowlib master. Graceful shutdown for HTTP/2: 1. A GOAWAY frame with the last stream id set to 2^31-1 is sent and a timer is started (goaway_initial_timeout, default 1000ms), to wait for any in-flight requests sent by the client, and the status is set to 'closing_initiated'. If the client responds with GOAWAY and closes the connection, we're done. 2. A second GOAWAY frame is sent with the actual last stream id and the status is set to 'closing'. If no streams exist, the connection terminates. Otherwise a second timer (goaway_complete_timeout, default 3000ms) is started, to wait for the streams to complete. New streams are not accepted when status is 'closing'. 3. If all streams haven't completed after the second timeout, the connection is forcefully terminated. Graceful shutdown for HTTP/1.x: 1. If a request is currently being handled, it is waited for and the response is sent back to the client with the header "Connection: close". Then, the connection is closed. 2. If the current request handler is not finished within the time configured in transport option 'shutdown' (default 5000ms), the connection process is killed by its supervisor (ranch). Implemented for HTTP/1.x and HTTP/2 in the following scenarios: * When receiving exit signal 'shutdown' from the supervisor (e.g. when cowboy:stop_listener/3 is called). * When a connection process is requested to terminate using sys:terminate/2,3. LH: Edited tests a bit and added todos for useful tests to add.
2020-05-20204 and 304 responses must not include a bodyLoïc Hoguin
When calling cowboy_req:reply/4 with a body a crash will occur resulting in a 500 response. When calling cowboy_req:stream_reply/2,3 and then attempting to send a body a crash will occur.
2020-02-07Fix HTTP/1.1 bug when a flow command is returned after finLoïc Hoguin
This resulted in a badarith error due to the current flow being set to infinity when the body has been fully read. A test case has been added reproducing the issue.
2020-02-05Add a test confirming push requests have no bodyLoïc Hoguin
2019-12-31Test trailers bug when there are data frames in queueTony Han
2019-10-10Add shutdown_reason Websocket commandLoïc Hoguin
This allows changing the normal exit reason of Websocket processes, providing a way to signal other processes of why the exit occurred.
2019-10-07Add cowboy_req:cast/2Loïc Hoguin
Better than sending messages manually.
2019-10-06Document the commands based Websocket interfaceLoïc Hoguin
The old interface with ok|reply|stop tuples is deprecated.
2019-10-05Add Websocket option validate_utf8Loïc Hoguin
This allows disabling the UTF-8 validation check for text and close frames.
2019-10-05Add cowboy_req:filter_cookies/2Loïc Hoguin
2019-10-04Make cowboy_compress_h add vary: accept-encodingLoïc Hoguin
2019-10-03Document media type wildcard in content_types_acceptedLoïc Hoguin
2019-10-03Add HTTP/2 tests with responses with HTTP/1.1 specific headersLoïc Hoguin
2019-10-02Ensure we can stream the response body from any processLoïc Hoguin
2019-10-02Ensure we can read the request body from any processLoïc Hoguin
2019-10-02Add {set_options, #{metrics_user_data := Map}}Loïc Hoguin
This allows giving custom metadata to the metrics stream handler. This can be useful to for example provide the name of the module handling the request which is only known after routing. But any user data is allowed. When called multiple times the user data maps are merged.
2019-09-14Implement backpressure on cowboy_req:stream_bodyLoïc Hoguin
This should limit the amount of memory that Cowboy is using when a handler is sending data much faster than the network. The new max_stream_buffer_size is a soft limit and only has an effect when the cowboy_stream_h handler is used.
2019-09-06Fix using custom fields in ReqLoïc Hoguin
2019-07-16Data received after RST_STREAM counts toward windowTony Han
2018-11-22Move the final old HTTP suite tests and remove itLoïc Hoguin
2018-11-21Move many old HTTP test cases to the rest_handler test suiteLoïc Hoguin
A bug was fixed in cowboy_rest where when content_types_provided returned a media type with a wildcard as first in the list, and a request comes in without an accept header, then the media_type value in the Req object would contain '*' instead of [] for the parameters.
2018-11-21Move another test from the old HTTP test suiteLoïc Hoguin
2018-11-18Add the chunked option for HTTP/1.1Loïc Hoguin
It allows disabling the chunked transfer-encoding. It can also be disabled on a per-request basis, although it will be ignored for responses that are not streamed.
2018-11-16Add the set_options Websocket commandLoïc Hoguin
It allows overriding the idle_timeout option only for now.