aboutsummaryrefslogtreecommitdiffstats
path: root/src/cowboy_stream_h.erl
AgeCommit message (Collapse)Author
2020-01-06Use active,NLoïc Hoguin
This reduces the number of times we need to ask for more packets, and as a result we get a fairly large boost in performance, especially with HTTP/1.1. Unfortunately this makes Cowboy require at least Erlang/OTP 21.3+ because the ssl application did not have active,N. For simplicity the version required will be Erlang/OTP 22+. In addition this change improves hibernate handling in cowboy_websocket. Hibernate will now work for HTTP/2 transport as well, and stray or unrelated messages will no longer cancel hibernate (the process will handle the message and go back into hibernation). Thanks go to Stressgrid for benchmarking an early version of this commit: https://stressgrid.com/blog/cowboy_performance_part_2/
2019-12-31No longer use erlang:get_stacktrace/0Loïc Hoguin
It has been deprecated in OTP and the new way is available on all supported OTP versions.
2019-10-10Fix a number of low hanging todosLoï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-02Fix HTTP/2 CVEsLoïc Hoguin
A number of HTTP/2 CVEs were documented recently: https://www.kb.cert.org/vuls/id/605641/ This commit, along with a few changes and additions in Cowlib, fix or improve protection against all of them. For CVE-2019-9511, also known as Data Dribble, the new option stream_window_data_threshold can be used to control how little the DATA frames that Cowboy sends can get. For CVE-2019-9516, also known as 0-Length Headers Leak, Cowboy will now simply reject streams containing 0-length header names. For CVE-2019-9517, also known as Internal Data Buffering, the backpressure changes were already pretty good at preventing this issue, but a new option max_connection_buffer_size was added for even better control over how much memory we are willing to allocate. For CVE-2019-9512, also known as Ping Flood; CVE-2019-9515, also known as Settings Flood; CVE-2019-9518, also known as Empty Frame Flooding; and similar undocumented scenarios, a frame rate limiting mechanism was added. By default Cowboy will now allow 1000 frames every 10 seconds. This can be configured via max_received_frame_rate. For CVE-2019-9514, also known as Reset Flood, another rate limiting mechanism was added and can be configured via max_reset_stream_rate. By default Cowboy will do up to 10 stream resets every 10 seconds. Finally, nothing was done for CVE-2019-9513, also known as Resource Loop, because Cowboy does not currently implement the HTTP/2 priority mechanism (in parts because these issues were well known from the start). Tests were added for all cases except Internal Data Buffering, which I'm not sure how to test, and Resource Loop, which is not currently relevant.
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.
2018-11-15Add the set_options stream handler commandLoïc Hoguin
The first two options to benefit from this are the cowboy_compress_h options.
2018-06-28Introduce undocumented option loggerLoïc Hoguin
This commit reworks the logging that Cowboy does via error_logger to make the module that will do the actual logging configurable. The logger module interface must be the same as logger and lager: a separate function per log level with the same log levels they support. The default behavior remains to call error_logger, although some messages were downgraded to warnings instead of errors. Since error_logger only supports three different log levels, some messages may get downgraded/upgraded depending on what the original log level was to make them compatible with error_logger. The {log, Level, Format, Args} command was also added to stream handlers. Stream handlers should use this command to log messages because it allows writing a stream handler to intercept some of those messages and extract information or block them as necessary. The logger option only applies to Cowboy itself, not to the messages Ranch logs, so more work remains to be done in that area.
2018-06-27Make sure cowboy_stream_h calls subsequent stream handlersLoïc Hoguin
2018-06-27Disable warnings for erlang:get_stacktrace/0 in OTP-21+Loïc Hoguin
2018-05-18Don't send transfer-encoding when streaming 204 responsesLoïc Hoguin
2018-04-04Add initial implementation of Websocket over HTTP/2Loïc Hoguin
Using the current draft: https://tools.ietf.org/html/draft-ietf-httpbis-h2-websockets-01
2017-11-15Add preliminary support for trailers in responsesLoïc Hoguin
This depends on changes in Cowlib that are only available on master.
2017-10-31Add some todosLoïc Hoguin
2017-10-30Handle expect: 100-continue request headersLoïc Hoguin
The 100 continue response will only be sent if the client has not sent the body yet (at all), if the connection is HTTP/1.1 or above and if the user has not sent it yet. The 100 continue response is sent when the user calls read_body and it is cowboy_stream_h's responsibility to send it. This means projects that don't use the cowboy_stream_h stream handler will need to handle the expect header themselves (but that's okay because they might have different considerations than normal Cowboy).
2017-10-29Add cowboy_req:inform/2,3Loïc Hoguin
User code can now send as many 1xx responses as necessary.
2017-09-25Move body length count to cowboy_stream_h instead of protocolsLoïc Hoguin
The documentation was correct, the code was not. This should make it easier to implement new protocols. Note that for HTTP/2 we will need to add some form of counting later on to check for malformed requests, but we can do simpler and just reduce from the expected length and then check if that's 0 when IsFin=fin.
2017-09-14Fix propagating the stacktrace on errors for OTP 19Loïc Hoguin
2017-09-14Rework the proc_lib_hackLoïc Hoguin
It is completely removed for connection processes, because assuming Cowboy is written properly this should bring us nothing anymore in 2.0. It is reworked for request processes, there we want to always propagate the stacktrace (including for exits) because we will print a report to help with debugging and proc_lib doesn't propagate it for exits. At the same time the initial callback for connection and request processes has been changed to connection_process and request_process, which should help with identifying processes when inspecting.
2017-09-14Improve how we detect request errorsLoïc Hoguin
When the request process exits with a {request_error, Reason, Human} exit reason, Cowboy will return a 400 status code instead of 500. Cowboy may also return a more specific status code depending on the error. Currently it may also return 408 or 413. This should prove to be more solid that looking inside the stack trace.
2017-07-12Catch more 400 errorsLoïc Hoguin
2017-05-05Add inactivity_timeout and other options improvementsLoïc Hoguin
2017-03-27Add the early_error cowboy_stream callbackLoïc Hoguin
This callback is called when an error occurs before the request (including headers, excluding body) was fully received. The init/3 callback will not be called. The callback receives the partial Req object (possibly empty), the reason for the error and the response command that the server will send. It allows you to be aware of the error and possibly modify the response before it is sent.
2017-02-19Remove another useless todoLoïc Hoguin
2017-02-05Remove or fix a small number of todo commentsLoïc Hoguin
One had the todo text fixed, another had the task to do done.
2017-01-20Fix error responses not including a content-lengthLoïc Hoguin
This would prevent the client from knowing whether the request was received fully without the connection closing first.
2017-01-16Add support for multiple stream handlersLoïc Hoguin
The stream handlers can be specified using the protocol option 'stream_handlers'. It defaults to [cowboy_stream_h]. The cowboy_stream_h module currently does not forward the calls to further stream handlers. It feels like an edge case; usually we'd want to put our own handlers between the protocol code and the request process. I am therefore going to focus on other things for now. The various types and specifications for stream handlers have been updated and the cowboy_stream module can now be safely used as a behavior. The interface might change a little more, though. This commit does not include tests or documentation. They will follow separately.
2017-01-02Welcome to 2017Loïc Hoguin
2017-01-02Numerous Dialyzer fixesLoïc Hoguin
2016-08-10Let the stream handler take care of crash handling and loggingLoïc Hoguin
2016-08-10Make reply functions return ReqLoïc Hoguin
2016-08-10Add a lot of todosLoïc Hoguin
2016-08-10Add tests for responses and request body readingLoïc Hoguin
This is a large commit. The cowboy_req interface has largely changed, and will change a little more. It's possible that some examples or tests have not been converted to the new interface yet. The documentation has not yet been updated. All of this will be fixed in smaller subsequent commits. Gotta start somewhere...
2016-06-06Report request process crashesLoïc Hoguin
2016-03-05Initial commit with connection/streamsLoïc Hoguin
Breaking changes with previous commit. This is a very large change, and I am giving up on making a single commit that fixes everything. More commits will follow slowly adding back features, introducing new tests and fixing the documentation. This change contains most of the work toward unifying the interface for handling both HTTP/1.1 and HTTP/2. HTTP/1.1 connections are now no longer 1 process per connection; instead by default 1 process per request is also created. This has a number of pros and cons. Because it has cons, we also allow users to use a lower-level API that acts on "streams" (requests/responses) directly at the connection process-level. If performance is a concern, one can always write a stream handler. The performance in this case will be even greater than with Cowboy 1, although all the special handlers are unavailable. When switching to Websocket, after the handler returns from init/2, Cowboy stops the stream and the Websocket protocol takes over the connection process. Websocket then calls websocket_init/2 for any additional initialization such as timers, because the process is different in init/2 and websocket_*/* functions. This however would allow us to use websocket_init/2 for sending messages on connect, instead of sending ourselves a message and be subject to races. Note that websocket_init/2 is optional. This is all a big change and while most of the tests pass, some functionality currently doesn't. SPDY is broken and will be removed soon in favor of HTTP/2. Automatic compression is currently disabled. The cowboy_req interface probably still have a few functions that need to be updated. The docs and examples do not refer the current functionality anymore. Everything will be fixed over time. Feedback is more than welcome. Open a ticket!