Commit Graph

37 Commits

Author SHA1 Message Date
Roman Arutyunyan
6f3c821d1f HTTP/3: refactored request body parser.
The change reduces diff to the default branch for
src/http/ngx_http_request_body.c.

Also, client Content-Length, if present, is now checked against the real body
size sent by client.
2021-01-25 16:16:47 +03:00
Roman Arutyunyan
cd62534300 HTTP/3: call ngx_handle_read_event() from client header handler.
This function should be called at the end of an event handler to prepare the
event for the next handler call.  Particularly, the "active" flag is set or
cleared depending on data availability.

With this call missing in one code path, read handler was not called again
after handling the initial part of the client request, if the request was too
big to fit into a single STREAM frame.

Now ngx_handle_read_event() is called in this code path.  Also, read timer is
restarted.
2021-01-29 19:42:47 +03:00
Roman Arutyunyan
7bac596afb HTTP/3: client header validation.
A header with the name containing null, CR, LF, colon or uppercase characters,
is now considered an error.  A header with the value containing null, CR or LF,
is also considered an error.

Also, header is considered invalid unless its name only contains lowercase
characters, digits, minus and optionally underscore.  Such header can be
optionally ignored.
2021-01-18 13:43:36 +03:00
Roman Arutyunyan
4e312daa7e HTTP/3: client pseudo-headers restrictions.
- :method, :path and :scheme are expected exactly once and not empty
- :method and :scheme character validation is added
- :authority cannot appear more than once
2021-01-22 15:57:41 +03:00
Roman Arutyunyan
9e489d208f HTTP/3: refactored request parser.
The change reduces diff to the default branch for
src/http/ngx_http_request.c and src/http/ngx_http_parse.c.
2021-01-22 16:34:06 +03:00
Sergey Kandaurov
c3714a8089 HTTP/3: staticize ngx_http_v3_methods. 2020-12-16 12:47:38 +00:00
Roman Arutyunyan
4b440cbf97 HTTP/3: introduced ngx_http_v3_filter.
The filter is responsible for creating HTTP/3 response header and body.

The change removes differences to the default branch for
ngx_http_chunked_filter_module and ngx_http_header_filter_module.
2020-11-27 17:46:21 +00:00
Roman Arutyunyan
7cfc5eb11f HTTP/3: eliminated r->method_start.
The field was introduced to ease parsing HTTP/3 requests.

The change reduces diff to the default branch.
2020-11-25 17:57:43 +00:00
Roman Arutyunyan
2fd31c8959 QUIC: renamed c->qs to c->quic. 2020-11-10 19:40:00 +00:00
Roman Arutyunyan
d294369915 HTTP/3: skip unknown frames on request stream.
As per HTTP/3 draft 29, section 4.1:

   Frames of unknown types (Section 9), including reserved frames
   (Section 7.2.8) MAY be sent on a request or push stream before,
   after, or interleaved with other frames described in this section.

Also, trailers frame is now used as an indication of the request body end.
2020-08-24 09:56:36 +03:00
Roman Arutyunyan
46173bd4b4 HTTP/3: fixed handling request body eof.
While for HTTP/1 unexpected eof always means an error, for HTTP/3 an eof right
after a DATA frame end means the end of the request body.  For this reason,
since adding HTTP/3 support, eof no longer produced an error right after recv()
but was passed to filters which would make a decision.  This decision was made
in ngx_http_parse_chunked() and ngx_http_v3_parse_request_body() based on the
b->last_buf flag.

Now that since 0f7f1a509113 (1.19.2) rb->chunked->length is a lower threshold
for the expected number of bytes, it can be set to zero to indicate that more
bytes may or may not follow.  Now it's possible to move the check for eof from
parser functions to ngx_http_request_body_chunked_filter() and clean up the
parsing code.

Also, in the default branch, in case of eof, the following three things
happened, which were replaced with returning NGX_ERROR while implementing
HTTP/3:

- "client prematurely closed connection" message was logged
- c->error flag was set
- NGX_HTTP_BAD_REQUEST was returned

The change brings back this behavior for HTTP/1 as well as HTTP/3.
2020-09-16 18:59:25 +01:00
Sergey Kandaurov
9a0fb643bf HTTP/3: fixed context storage in request body parser. 2020-08-18 17:11:32 +03:00
Roman Arutyunyan
6d064c94e0 HTTP/3: server pushes.
New directives are added:
- http3_max_concurrent_pushes
- http3_push
- http3_push_preload
2020-07-23 13:41:24 +03:00
Roman Arutyunyan
5e036a6bef HTTP/3: support $server_protocol variable.
Now it holds "HTTP/3.0".  Previously it was empty.
2020-07-14 16:52:44 +03:00
Roman Arutyunyan
6d7ddb5471 HTTP/3: encode frame ids with ngx_http_v3_encode_varlen_int().
Even though typically frame ids fit into a single byte, calling
ngx_http_v3_encode_varlen_int() adds to the code clarity.
2020-07-13 12:33:00 +03:00
Roman Arutyunyan
fc5a7234b4 HTTP/3: generate Location response header for absolute redirects. 2020-07-23 12:31:40 +03:00
Roman Arutyunyan
04b2a169a4 HTTP/3: header encoding functions. 2020-07-13 16:00:00 +03:00
Roman Arutyunyan
707117276e HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Previously errors led only to closing streams.

To simplify closing QUIC connection from a QUIC stream context, new macro
ngx_http_v3_finalize_connection() is introduced.  It calls
ngx_quic_finalize_connection() for the parent connection.
2020-07-02 16:47:51 +03:00
Roman Arutyunyan
a687d08062 HTTP/3: refactored dynamic table implementation.
Previously dynamic table was not functional because of zero limit on its size
set by default.  Now the following changes enable it:

- new directives to set SETTINGS_QPACK_MAX_TABLE_CAPACITY and
  SETTINGS_QPACK_BLOCKED_STREAMS
- send settings with SETTINGS_QPACK_MAX_TABLE_CAPACITY and
  SETTINGS_QPACK_BLOCKED_STREAMS to the client
- send Insert Count Increment to the client
- send Header Acknowledgement to the client
- evict old dynamic table entries on overflow
- decode Required Insert Count from client
- block stream if Required Insert Count is not reached
2020-07-02 15:34:05 +03:00
Roman Arutyunyan
690e1bc50c HTTP/3: fixed dropping first non-pseudo header. 2020-06-26 10:05:28 +03:00
Sergey Kandaurov
3168f58306 HTTP/3: do not emit a DATA frame header for header_only responses.
This resulted in the frame error due to the invalid DATA frame length.
2020-06-25 20:31:13 +03:00
Roman Arutyunyan
94764fda6e Fixed client buffer reallocation for HTTP/3.
Preserving pointers within the client buffer is not needed for HTTP/3 because
all data is either allocated from pool or static.  Unlike with HTTP/1, data
typically cannot be referenced directly within the client buffer.  Trying to
preserve NULLs or external pointers lead to broken pointers.

Also, reverted changes in ngx_http_alloc_large_header_buffer() not relevant
for HTTP/3 to minimize diff to mainstream.
2020-05-19 16:20:33 +03:00
Roman Arutyunyan
d6b6b6dfc5 Fixed $request_length for HTTP/3.
New field r->parse_start is introduced to substitute r->request_start and
r->header_name_start for request length accounting.  These fields only work for
this purpose in HTTP/1 because HTTP/1 request line and header line start with
these values.

Also, error logging is now fixed to output the right part of the request.
2020-05-19 15:47:37 +03:00
Roman Arutyunyan
d25937c2b5 HTTP/3: restricted symbols in header names.
As per HTTP/3 draft 27, a request or response containing uppercase header
field names MUST be treated as malformed.  Also, existing rules applied
when parsing HTTP/1 header names are also applied to HTTP/3 header names:

- null character is not allowed
- underscore character may or may not be treated as invalid depending on the
  value of "underscores_in_headers"
- all non-alphanumeric characters with the exception of '-' are treated as
  invalid

Also, the r->locase_header field is now filled while parsing an HTTP/3
header.

Error logging for invalid headers is fixed as well.
2020-05-19 15:34:00 +03:00
Roman Arutyunyan
6abb50658f HTTP/3: split header parser in two functions.
The first one parses pseudo-headers and is analagous to the request line
parser in HTTP/1.  The second one parses regular headers and is analogous to
the header parser in HTTP/1.

Additionally, error handling of client passing malformed uri is now fixed.
2020-05-19 15:29:10 +03:00
Sergey Kandaurov
51e4e31a8d Assorted fixes.
Found by Clang Static Analyzer.
2020-05-20 15:36:24 +03:00
Roman Arutyunyan
b77fd3dc58 HTTP/3: fixed reading request body. 2020-04-13 17:54:23 +03:00
Roman Arutyunyan
fa1e1beadc Parsing HTTP/3 request body. 2020-03-27 19:41:06 +03:00
Roman Arutyunyan
80a38580bd Chunked response body in HTTP/3. 2020-03-27 19:46:54 +03:00
Roman Arutyunyan
81f7cff632 Fixed buffer overflow. 2020-03-27 15:50:42 +03:00
Roman Arutyunyan
0f77eac8af Removed unused variable. 2020-03-20 23:49:42 +03:00
Roman Arutyunyan
8ad2707d4f Fixed header creation for header_only responses in HTTP/3. 2020-03-19 15:03:09 +03:00
Roman Arutyunyan
e63accd7bd HTTP/3 $request_line variable. 2020-03-18 20:22:16 +03:00
Roman Arutyunyan
04d037b239 Fixed pointer increment while parsing HTTP/3 header. 2020-03-18 15:28:20 +03:00
Roman Arutyunyan
01dc7445f0 Refactored HTTP/3 parser. 2020-03-18 13:46:35 +03:00
Roman Arutyunyan
5399670fcc Temporary fix for header null-termination in HTTP/3. 2020-03-14 13:18:55 +03:00
Roman Arutyunyan
7739b6073b HTTP/3. 2020-03-13 19:36:33 +03:00