aboutsummaryrefslogtreecommitdiff
path: root/src/http/v2/ngx_http_v2.c
Commit message (Collapse)AuthorAge
...
* HTTP/2: refactored ngx_http_v2_send_output_queue().Valentin Bartenev2016-07-19
| | | | Now it returns NGX_AGAIN if there's still data to be sent.
* HTTP/2: fixed send timer handling.Valentin Bartenev2016-07-19
| | | | | | | | | | Checking for return value of c->send_chain() isn't sufficient since there are data can be left in the SSL buffer. Now the wew->ready flag is used instead. In particular, this fixed a connection leak in cases when all streams were closed, but there's still some data to be sent in the SSL buffer and the client forgot about the connection.
* HTTP/2: avoid sending output queue if there's nothing to send.Valentin Bartenev2016-07-19
| | | | | | | | | Particularly this fixes alerts on OS X and NetBSD systems when HTTP/2 is configured over plain TCP sockets. On these systems calling writev() with no data leads to EINVAL errors being logged as "writev() failed (22: Invalid argument) while processing HTTP/2 connection".
* HTTP/2: always send GOAWAY while worker is shutting down.Valentin Bartenev2016-07-19
| | | | | Previously, if the worker process exited, GOAWAY was sent to connections in idle state, but connections with active streams were closed without GOAWAY.
* HTTP/2: fixed the "http request count is zero" alert.Valentin Bartenev2016-06-16
| | | | | | | | | | | | | | | | When the stream is terminated the HEADERS frame can still wait in the output queue. This frame can't be removed and must be sent to the client anyway, since HTTP/2 uses stateful compression for headers. So in order to postpone closing and freeing memory of such stream the special close stream handler is set to the write event. After the HEADERS frame is sent the write event is called and the stream will be finally closed. Some events like receiving a RST_STREAM can trigger the read handler of such stream in closing state and cause unexpected processing that can result in another attempt to finalize the request. To prevent it the read handler is now set to ngx_http_empty_handler. Thanks to Amazon.
* HTTP/2: avoid adding Content-Length for requests without body.Valentin Bartenev2016-06-16
| | | | | | | There is no reason to add the "Content-Length: 0" header to a proxied request without body if the header isn't presented in the original request. Thanks to Amazon.
* HTTP/2: prevented double termination of a stream.Valentin Bartenev2016-06-16
| | | | | | | According to RFC 7540, an endpoint should not send more than one RST_STREAM frame for any stream. Also, now all the data frames will be skipped while termination.
* HTTP/2: fixed a segfault while processing unbuffered upload.Valentin Bartenev2016-06-16
| | | | | | | The ngx_http_v2_finalize_connection() closes current stream, but that is an invalid operation while processing unbuffered upload. This results in access to already freed memory, since the upstream module sets a cleanup handler that also finalizes the request.
* HTTP/2: unbreak build on MSVC.Valentin Bartenev2016-05-24
|
* HTTP/2: implemented preread buffer for request body (closes #959).Valentin Bartenev2016-05-24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously, the stream's window was kept zero in order to prevent a client from sending the request body before it was requested (see 887cca40ba6a for details). Until such initial window was acknowledged all requests with data were rejected (see 0aa07850922f for details). That approach revealed a number of problems: 1. Some clients (notably MS IE/Edge, Safari, iOS applications) show an error or even crash if a stream is rejected; 2. This requires at least one RTT for every request with body before the client receives window update and able to send data. To overcome these problems the new directive "http2_body_preread_size" is introduced. It sets the initial window and configures a special per stream preread buffer that is used to save all incoming data before the body is requested and processed. If the directive's value is lower than the default initial window (65535), as previously, all streams with data will be rejected until the new window is acknowledged. Otherwise, no special processing is used and all requests with data are welcome right from the connection start. The default value is chosen to be 64k, which is bigger than the default initial window. Setting it to zero is fully complaint to the previous behavior.
* HTTP/2: send the output queue after emitting WINDOW_UPDATE.Valentin Bartenev2016-04-19
| | | | | | | | The WINDOW_UPDATE frame could be left in the output queue for an indefinite period of time resulting in the request timeout. This might happen if reading of the body was triggered by an event unrelated to client connection, e.g. by the limit_req timer.
* HTTP/2: skip data frames in case of internal errors.Valentin Bartenev2016-04-19
| | | | | | This prevents possible processing of such frames and triggering rb->post_handler if an error occurred during r->request_body initialization.
* HTTP/2: don't send WINDOW_UPDATE for an empty request body.Valentin Bartenev2016-04-19
| | | | | | | Particularly this prevents sending WINDOW_UPDATE with zero delta which can result in PROTOCOL_ERROR. Also removed surplus setting of no_flow_control to 0.
* HTTP/2: write logs when refusing streams with data.Maxim Dounin2016-04-18
| | | | | | Refusing streams is known to be incorrectly handled at least by IE, Edge and Safari. Make sure to provide appropriate logging to simplify fixing this in the affected browsers.
* HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.Valentin Bartenev2016-04-14
| | | | | | | | | | | | | | | | | After the 92464ebace8e change, it has been discovered that not all clients follow the RFC and handle RST_STREAM with NO_ERROR properly. Notably, Chrome currently interprets it as INTERNAL_ERROR and discards the response. As a workaround, instead of RST_STREAM the maximum stream window update will be sent, which will let client to send up to 2 GB of a request body data before getting stuck on flow control. All the received data will be silently discarded. See for details: http://mailman.nginx.org/pipermail/nginx-devel/2016-April/008143.html https://bugs.chromium.org/p/chromium/issues/detail?id=603182
* HTTP/2: refuse streams with data until SETTINGS is acknowledged.Valentin Bartenev2016-04-14
| | | | | | | | | A client is allowed to send requests before receiving and acknowledging the SETTINGS frame. Such a client having a wrong idea about the stream's could send the request body that nginx isn't ready to process. The previous behavior was to send RST_STREAM with FLOW_CONTROL_ERROR in such case, but it didn't allow retrying requests that have been rejected.
* HTTP/2: deduplicated some code in ngx_http_v2_state_headers().Valentin Bartenev2016-04-14
| | | | No functional changes.
* HTTP/2: support for unbuffered upload of request body.Valentin Bartenev2016-04-01
|
* HTTP/2: rewritten handling of request body.Valentin Bartenev2016-04-01
| | | | | | | | | | | | | There are two improvements: 1. Support for request body filters; 2. Receiving of request body is started only after the ngx_http_read_client_request_body() call. The last one fixes the problem when the client_max_body_size value might not be respected from the right location if the location was changed either during the process of receiving body or after the whole body had been received.
* HTTP/2: sending RST_STREAM with NO_ERROR to discard request body.Valentin Bartenev2016-04-01
| | | | | | | | | | | | | | RFC 7540 states that "A server can send a complete response prior to the client sending an entire request if the response does not depend on any portion of the request that has not been sent and received. When this is true, a server MAY request that the client abort transmission of a request without error by sending a RST_STREAM with an error code of NO_ERROR after sending a complete response (i.e., a frame with the END_STREAM flag)." This should prevent a client from blocking on the stream window, since it isn't maintained for closed streams. Currently, quite big initial stream windows are used, so such blocking is very unlikly, but that will be changed in the further patches.
* Fixed logging.Sergey Kandaurov2016-03-31
|
* HTTP/2: improved debugging of sending control frames.Valentin Bartenev2016-03-21
|
* HTTP/2: implemented per request timeouts (closes #626).Valentin Bartenev2016-02-24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously, there were only three timeouts used globally for the whole HTTP/2 connection: 1. Idle timeout for inactivity when there are no streams in processing (the "http2_idle_timeout" directive); 2. Receive timeout for incomplete frames when there are no streams in processing (the "http2_recv_timeout" directive); 3. Send timeout when there are frames waiting in the output queue (the "send_timeout" directive on a server level). Reaching one of these timeouts leads to HTTP/2 connection close. This left a number of scenarios when a connection can get stuck without any processing and timeouts: 1. A client has sent the headers block partially so nginx starts processing a new stream but cannot continue without the rest of HEADERS and/or CONTINUATION frames; 2. When nginx waits for the request body; 3. All streams are stuck on exhausted connection or stream windows. The first idea that was rejected was to detect when the whole connection gets stuck because of these situations and set the global receive timeout. The disadvantage of such approach would be inconsistent behaviour in some typical use cases. For example, if a user never replies to the browser's question about where to save the downloaded file, the stream will be eventually closed by a timeout. On the other hand, this will not happen if there's some activity in other concurrent streams. Now almost all the request timeouts work like in HTTP/1.x connections, so the "client_header_timeout", "client_body_timeout", and "send_timeout" are respected. These timeouts close the request. The global timeouts work as before. Previously, the c->write->delayed flag was abused to avoid setting timeouts on stream events. Now, the "active" and "ready" flags are manipulated instead to control the processing of individual streams.
* HTTP/2: always use temporary pool for processing headers.Valentin Bartenev2016-02-24
| | | | | | | | | | | | | | | | | | This is required for implementing per request timeouts. Previously, the temporary pool was used only during skipping of headers and the request pool was used otherwise. That required switching of pools if the request was closed while parsing. It wasn't a problem since the request could be closed only after the validation of the fully parsed header. With the per request timeouts, the request can be closed at any moment, and switching of pools in the middle of parsing header name or value becomes a problem. To overcome this, the temporary pool is now always created and used. Special checks are added to keep it when either the stream is being processed or until header block is fully parsed.
* HTTP/2: cleaned up state while closing stream.Valentin Bartenev2016-02-24
| | | | Without this the state might keep pointing to already closed stream.
* HTTP/2: fixed padding handling in HEADERS frame with CONTINUATION.Valentin Bartenev2016-02-02
|
* HTTP/2: fixed request length accounting.Valentin Bartenev2016-02-02
| | | | | Now it includes not only the received body size, but the size of headers block as well.
* HTTP/2: fixed excessive memory allocation for pool cleanup.Valentin Bartenev2016-02-02
|
* Stop emulating a space character after r->method_name.Ruslan Ermilov2015-11-30
| | | | | | | This is an API change. The proxy module was modified to not depend on this in 44122bddd9a1. No known third-party modules seem to depend on this.
* HTTP/2: fixed invalid headers handling (ticket #831).Valentin Bartenev2015-11-13
| | | | | | The r->invalid_header flag wasn't reset once an invalid header appeared in a request, resulting in all subsequent headers in the request were also marked as invalid.
* HTTP/2: backed out 16905ecbb49e (ticket #822).Valentin Bartenev2015-11-05
| | | | | | | | | | | It caused inconsistency between setting "in_closed" flag and the moment when the last DATA frame was actually read. As a result, the body buffer might not be initialized properly in ngx_http_v2_init_request_body(), which led to a segmentation fault in ngx_http_v2_state_read_data(). Also it might cause start processing of incomplete body. This issue could be triggered when the processing of a request was delayed, e.g. in the limit_req or auth_request modules.
* HTTP/2: changed behavior of the "http2_max_field_size" directive.Valentin Bartenev2015-10-27
| | | | | | Now it limits only the maximum length of literal string (either raw or compressed) in HPACK request header fields. It's easier to understand and to describe in the documentation.
* HTTP/2: fixed spelling.Valentin Bartenev2015-10-27
|
* HTTP/2: simplified checking the END_STREAM flag.Valentin Bartenev2015-10-26
| | | | No functional changes.
* HTTP/2: fix handling of connection errors.Piotr Sikora2015-10-01
| | | | | | | | | Previously, nginx worker would crash because of a double free if client disconnected or timed out before sending all headers. Found with afl-fuzz. Signed-off-by: Piotr Sikora <piotrsikora@google.com>
* HTTP/2: fix indirect reprioritization.Piotr Sikora2015-10-01
| | | | | | | | | | | | | | | Previously, streams that were indirectly reprioritized (either because of a new exclusive dependency on their parent or because of removal of their parent from the dependency tree), didn't have their pointer to the parent node updated. This broke detection of circular dependencies and, as a result, nginx worker would crash due to stack overflow whenever such dependency was introduced. Found with afl-fuzz. Signed-off-by: Piotr Sikora <piotrsikora@google.com>
* HTTP/2: reject self-dependent streams.Piotr Sikora2015-10-01
| | | | | | | | | | | | Per RFC7540, a stream cannot depend on itself. Previously, this requirement was enforced on PRIORITY frames, but not on HEADERS frames and due to the implementation details nginx worker would crash (stack overflow) while opening self-dependent stream. Found with afl-fuzz. Signed-off-by: Piotr Sikora <piotrsikora@google.com>
* HTTP/2: improved error handling while parsing integers.Valentin Bartenev2015-10-20
| | | | | The case when an integer is out of frame bounds should be checked first as a more accurate error.
* HTTP/2: improved HPACK integer parsing code readability.Ruslan Ermilov2015-10-20
| | | | No functional changes.
* HTTP/2: fixed parsing of literal header fields without indexing.Valentin Bartenev2015-10-19
|
* HTTP/2: fixed $server_protocol value (ticket #800).Valentin Bartenev2015-09-28
|
* HTTP/2: fixed header block parsing with CONTINUATION frames (#792).Valentin Bartenev2015-09-22
| | | | | It appears that the CONTINUATION frames don't need to be aligned to bounds of individual headers.
* HTTP/2: fixed HPACK header field parsing.Valentin Bartenev2015-09-22
|
* The HTTP/2 implementation (RFC 7240, 7241).Valentin Bartenev2015-09-11
The SPDY support is removed, as it's incompatible with the new module.