aboutsummaryrefslogtreecommitdiff
path: root/src/http/v2/ngx_http_v2.c
Commit message (Collapse)AuthorAge
...
* HTTP/2: discard remaining request body after redirect.Sergey Kandaurov2019-08-19
| | | | | | | | | | | | | | | | | | | | | Previously, if unbuffered request body reading wasn't finished before the request was redirected to a different location using error_page or X-Accel-Redirect, and the request body is read again, this could lead to disastrous effects, such as a duplicate post_handler call or "http request count is zero" alert followed by a segmentation fault. This happened in the following configuration (ticket #1819): location / { proxy_request_buffering off; proxy_pass http://bad; proxy_intercept_errors on; error_page 502 = /error; } location /error { proxy_pass http://backend; }
* HTTP/2: limited number of PRIORITY frames.Ruslan Ermilov2019-08-13
| | | | | Fixed excessive CPU usage caused by a peer that continuously shuffles priority of streams. Fix is to limit the number of PRIORITY frames.
* HTTP/2: limited number of DATA frames.Ruslan Ermilov2019-08-13
| | | | | | Fixed excessive memory growth and CPU usage if stream windows are manipulated in a way that results in generating many small DATA frames. Fix is to limit the number of simultaneously allocated DATA frames.
* HTTP/2: reject zero length headers with PROTOCOL_ERROR.Sergey Kandaurov2019-08-13
| | | | | | Fixed uncontrolled memory growth if peer sends a stream of headers with a 0-length header name and 0-length header value. Fix is to reject headers with zero name length.
* HTTP/2: limit the number of idle state switches.Ruslan Ermilov2018-11-06
| | | | | | | | | | | | | | An attack that continuously switches HTTP/2 connection between idle and active states can result in excessive CPU usage. This is because when a connection switches to the idle state, all of its memory pool caches are freed. This change limits the maximum allowed number of idle state switches to 10 * http2_max_requests (i.e., 10000 by default). This limits possible CPU usage in one connection, and also imposes a limit on the maximum lifetime of a connection. Initially reported by Gal Goldshtein from F5 Networks.
* HTTP/2: flood detection.Ruslan Ermilov2018-11-06
| | | | | | Fixed uncontrolled memory growth in case peer is flooding us with some frames (e.g., SETTINGS and PING) and doesn't read data. Fix is to limit the number of allocated control frames.
* Fixed socket leak with "return 444" in error_page (ticket #274).Maxim Dounin2018-09-21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Socket leak was observed in the following configuration: error_page 400 = /close; location = /close { return 444; } The problem is that "return 444" triggers termination of the request, and due to error_page termination thinks that it needs to use a posted request to clear stack. But at the early request processing where 400 errors are generated there are no ngx_http_run_posted_requests() calls, so the request is only terminated after an external event. Variants of the problem include "error_page 497" instead (ticket #695) and various other errors generated during early request processing (405, 414, 421, 494, 495, 496, 501, 505). The same problem can be also triggered with "return 499" and "return 408" as both codes trigger ngx_http_terminate_request(), much like "return 444". To fix this, the patch adds ngx_http_run_posted_requests() calls to ngx_http_process_request_line() and ngx_http_process_request_headers() functions, and to ngx_http_v2_run_request() and ngx_http_v2_push_stream() functions in HTTP/2. Since the ngx_http_process_request() function is now only called via other functions which call ngx_http_run_posted_requests(), the call there is no longer needed and was removed.
* HTTP/2: workaround for clients which fail on table size updates.Maxim Dounin2018-08-09
| | | | | | | | | | | There are clients which cannot handle HPACK's dynamic table size updates as added in 12cadc4669a7 (1.13.6). Notably, old versions of OkHttp library are known to fail on it (ticket #1397). This change makes it possible to work with such clients by only sending dynamic table size updates in response to SETTINGS_HEADER_TABLE_SIZE. As a downside, clients which do not use SETTINGS_HEADER_TABLE_SIZE will continue to maintain default 4k table.
* HTTP/2: use scheme from original request for pushes (closes #1549).Ruslan Ermilov2018-06-07
| | | | | | Instead of the connection scheme, use scheme from the original request. This fixes pushes when SSL is terminated by a proxy server in front of nginx.
* Added r->schema.Ruslan Ermilov2018-06-07
| | | | | For HTTP/1, it keeps scheme from the absolute form of URI. For HTTP/2, the :scheme request pseudo-header field value.
* HTTP/2: validate client request scheme.Ruslan Ermilov2018-06-07
| | | | The scheme is validated as per RFC 3986, Section 3.1.
* HTTP/2: improved frame info debugging.Ruslan Ermilov2018-03-19
|
* HTTP/2: externalized various constants and interfaces.Maxim Dounin2018-03-17
|
* HTTP/2: unknown frames now logged at info level.Maxim Dounin2018-03-05
|
* HTTP/2: style.Ruslan Ermilov2018-02-22
| | | | Unified the style of validity checks in ngx_http_v2_validate_header().
* HTTP/2: precalculate hash for "Cookie".Maxim Dounin2018-02-15
| | | | | | There is no need to calculate hashes of static strings at runtime. The ngx_hash() macro can be used to do it during compilation instead, similarly to how it is done in ngx_http_proxy_module.c for "Server" and "Date" headers.
* HTTP/2: fixed ngx_http_v2_push_stream() allocation error handling.Ruslan Ermilov2018-02-15
| | | | | | In particular, if a stream object allocation failed, and a client sent the PRIORITY frame for this stream, ngx_http_v2_set_dependency() could dereference a null pointer while trying to re-parent a dependency node.
* HTTP/2: push additional request headers (closes #1478).Ruslan Ermilov2018-02-15
| | | | | The Accept-Encoding, Accept-Language, and User-Agent header fields are now copied from the original request to pushed requests.
* HTTP/2: style.Sergey Kandaurov2018-02-15
|
* HTTP/2: server push.Ruslan Ermilov2018-02-08
| | | | | | | | | | | | | | Resources to be pushed are configured with the "http2_push" directive. Also, preload links from the Link response headers, as described in https://www.w3.org/TR/preload/#server-push-http-2, can be pushed, if enabled with the "http2_push_preload" directive. Only relative URIs with absolute paths can be pushed. The number of concurrent pushes is normally limited by a client, but cannot exceed a hard limit set by the "http2_max_concurrent_pushes" directive.
* HTTP/2: changed prototypes of request pseudo-headers parsers.Ruslan Ermilov2018-02-08
| | | | No functional changes.
* HTTP/2: finalize request as bad if parsing of pseudo-headers fails.Ruslan Ermilov2018-01-30
| | | | | This is in line when the required pseudo-headers are missing, and avoids spurious zero statuses in access.log.
* HTTP/2: more style, comments, and debugging.Ruslan Ermilov2018-01-29
|
* HTTP/2: handle duplicate INITIAL_WINDOW_SIZE settings.Ruslan Ermilov2018-01-29
|
* HTTP/2: enforce writing the sync request body buffer to file.Valentin Bartenev2017-10-04
| | | | | | | | | | | | | | | | | The sync flag of HTTP/2 request body buffer is used when the size of request body is unknown or bigger than configured "client_body_buffer_size". In this case the buffer points to body data inside the global receive buffer that is used for reading all HTTP/2 connections in the worker process. Thus, when the sync flag is set, the buffer must be flushed to a temporary file, otherwise the request body data can be overwritten. Previously, the sync buffer wasn't flushed to a temporary file if the whole body was received in one DATA frame with the END_STREAM flag and wasn't copied into the HTTP/2 body preread buffer. As a result, the request body might be corrupted (ticket #1384). Now, setting r->request_body_in_file_only enforces writing the sync buffer to a temporary file in all cases.
* HTTP/2: shortened some debug log messages.Maxim Dounin2017-09-14
| | | | | This ensures slightly more readable debug logs on 80-character-wide terminals.
* HTTP/2: added logging of 400 (Bad Request) reasons.Maxim Dounin2017-09-14
|
* HTTP/2: signal 0-byte HPACK's dynamic table size.Piotr Sikora2017-08-30
| | | | | | | | | | | | | | This change lets NGINX talk to clients with SETTINGS_HEADER_TABLE_SIZE smaller than the default 4KB. Previously, NGINX would ACK the SETTINGS frame with a small dynamic table size, but it would never send dynamic table size update, leading to a connection-level COMPRESSION_ERROR. Also, it allows clients to release 4KB of memory per connection, since NGINX doesn't use HPACK's dynamic table when encoding headers, however clients had to maintain it, since NGINX never signaled that it doesn't use it. Signed-off-by: Piotr Sikora <piotrsikora@google.com>
* HTTP/2: reject HTTP/2 requests without ":scheme" pseudo-header.Piotr Sikora2017-06-13
| | | | Signed-off-by: Piotr Sikora <piotrsikora@google.com>
* HTTP/2: don't send SETTINGS ACK before already queued DATA frames.Piotr Sikora2017-06-02
| | | | | | | | | | | | | Previously, SETTINGS ACK was sent immediately upon receipt of SETTINGS frame, before already queued DATA frames created using old SETTINGS. This incorrect behavior was source of interoperability issues, because peers rely on the fact that new SETTINGS are in effect after receiving SETTINGS ACK. Reported by Feng Li. Signed-off-by: Piotr Sikora <piotrsikora@google.com>
* HTTP/2: make SETTINGS ACK frame reusable.Piotr Sikora2017-06-02
| | | | Signed-off-by: Piotr Sikora <piotrsikora@google.com>
* HTTP/2: send SETTINGS ACK after applying all SETTINGS params.Piotr Sikora2017-06-02
| | | | | | This avoids sending unnecessary SETTINGS ACK in case of PROTOCOL_ERROR. Signed-off-by: Piotr Sikora <piotrsikora@google.com>
* HTTP/2: emit new frames only after applying all SETTINGS params.Piotr Sikora2017-06-02
| | | | | | | Previously, new frames could be emitted in the middle of applying new (and already acknowledged) SETTINGS params, which is illegal. Signed-off-by: Piotr Sikora <piotrsikora@google.com>
* HTTP/2: add debug logging of pseudo-headers and cookies.Piotr Sikora2017-05-30
| | | | Signed-off-by: Piotr Sikora <piotrsikora@google.com>
* Introduced ngx_tcp_nodelay().Ruslan Ermilov2017-05-26
|
* HTTP/2: reduced difference to HTTP/1.x in reading request body.Valentin Bartenev2017-04-24
| | | | | | | Particularly, this eliminates difference in behavior for requests without body and deduplicates code. Prodded by Piotr Sikora.
* HTTP/2: rejecting zero WINDOW_UPDATE with PROTOCOL_ERROR.Valentin Bartenev2017-04-24
| | | | | | | It's required by RFC 7540. While there is no real harm from such frames, that should help to detect broken clients. Based on a patch by Piotr Sikora.
* HTTP/2: style and typos.Piotr Sikora2017-03-26
| | | | Signed-off-by: Piotr Sikora <piotrsikora@google.com>
* HTTP/2: fixed connection finalization.Valentin Bartenev2017-03-29
| | | | | | | | | | | | | | | | | | | | | | All streams in connection must be finalized before the connection itself can be finalized and all related memory is freed. That's not always possible on the current event loop iteration. Thus when the last stream is finalized, it sets the special read event handler ngx_http_v2_handle_connection_handler() and posts the event. Previously, this handler didn't check the connection state and could call the regular event handler on a connection that was already in finalization stage. In the worst case that could lead to a segmentation fault, since some data structures aren't supposed to be used during connection finalization. Particularly, the waiting queue can contain already freed streams, so the WINDOW_UPDATE frame received by that moment could trigger accessing to these freed streams. Now, the connection error flag is explicitly checked in ngx_http_v2_handle_connection_handler().
* HTTP/2: fixed stream finalization.Valentin Bartenev2017-03-29
| | | | | | | | | | In order to finalize stream the error flag is set on fake connection and either "write" or "read" event handler is called. The read events of fake connections are always ready, but it's not the case with the write events. When the ready flag isn't set, the error flag can be not checked in some cases and as a result stream isn't finalized. Now the ready flag is explicilty set on write events for proper finalization in all cases.
* HTTP/2: emit PROTOCOL_ERROR on padding errors.Piotr Sikora2017-03-26
| | | | Signed-off-by: Piotr Sikora <piotrsikora@google.com>
* HTTP/2: fix flow control with padded DATA frames.Piotr Sikora2017-03-26
| | | | | | | | | Previously, flow control didn't account for padding in DATA frames, which meant that its view of the world could drift from peer's view by up to 256 bytes per received padded DATA frame, which could lead to a deadlock. Signed-off-by: Piotr Sikora <piotrsikora@google.com>
* HTTP/2: prevented creating temp files for requests without body.Valentin Bartenev2016-12-10
| | | | The problem was introduced by 52bd8cc17f34.
* HTTP/2: fixed posted streams handling.Valentin Bartenev2016-11-28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A bug was introduced by 82efcedb310b that could lead to timing out of responses or segmentation fault, when accept_mutex was enabled. The output queue in HTTP/2 can contain frames from different streams. When the queue is sent, all related write handlers need to be called. In order to do so, the streams were added to the h2c->posted queue after handling sent frames. Then this queue was processed in ngx_http_v2_write_handler(). If accept_mutex is enabled, the event's "ready" flag is set but its handler is not called immediately. Instead, the event is added to the ngx_posted_events queue. At the same time in this queue can be events from upstream connections. Such events can result in sending output queue before ngx_http_v2_write_handler() is triggered. And at the time ngx_http_v2_write_handler() is called, the output queue can be already empty with some streams added to h2c->posted. But after 82efcedb310b, these streams weren't processed if all frames have already been sent and the output queue was empty. This might lead to a situation when a number of streams were get stuck in h2c->posted queue for a long time. Eventually these streams might get closed by the send timeout. In the worst case this might also lead to a segmentation fault, if already freed stream was left in the h2c->posted queue. This could happen if one of the streams was terminated but wasn't closed, due to the HEADERS frame or a partially sent DATA frame left in the output queue. If this happened the ngx_http_v2_filter_cleanup() handler removed the stream from the h2c->waiting or h2c->posted queue on termination stage, before the frame has been sent, and the stream was again added to the h2c->posted queue after the frame was sent. In order to fix all these problems and simplify the code, write events of fake stream connections are now added to ngx_posted_events instead of using a custom h2c->posted queue.
* HTTP/2: fixed saving preread buffer to temp file (ticket #1143).Valentin Bartenev2016-11-28
| | | | | | | Previously, a request body bigger than "client_body_buffer_size" wasn't written into a temporary file if it has been pre-read entirely. The preread buffer is freed after processing, thus subsequent use of it might result in sending corrupted body or cause a segfault.
* HTTP/2: slightly improved debugging.Ruslan Ermilov2016-10-31
|
* HTTP/2: limited maximum number of requests in connection.Valentin Bartenev2016-10-31
| | | | | | The new directive "http2_max_requests" is introduced. From users point of view it works quite similar to "keepalive_requests" but has significantly bigger default value that is more suitable for HTTP/2.
* HTTP/2: graceful shutdown of active connections (closes #1106).Valentin Bartenev2016-10-20
| | | | | | | | | | | Previously, while shutting down gracefully, the HTTP/2 connections were closed in transition to idle state after all active streams have been processed. That might never happen if the client continued opening new streams. Now, nginx sends GOAWAY to all HTTP/2 connections and ignores further attempts to open new streams. A worker process will quit as soon as processing of already opened streams is finished.
* Allowed '-' in method names.Maxim Dounin2016-10-10
| | | | | | It is used at least by SOAP (M-POST method, defined by RFC 2774) and by WebDAV versioning (VERSION-CONTROL and BASELINE-CONTROL methods, defined by RFC 3253).
* HTTP/2: flushing of the SSL buffer in transition to the idle state.Valentin Bartenev2016-07-19
| | | | | | | It fixes potential connection leak if some unsent data was left in the SSL buffer. Particularly, that could happen when a client canceled the stream after the HEADERS frame has already been created. In this case no other frames might be produced and the HEADERS frame alone didn't flush the buffer.