Mercurial > hg > nginx
annotate src/http/v3/ngx_http_v3_request.c @ 8452:a6675a976560 quic
HTTP/3: fixed dropping first non-pseudo header.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Fri, 26 Jun 2020 10:05:28 +0300 |
parents | 908cae4f3078 |
children | c9538aef3211 |
rev | line source |
---|---|
8215 | 1 |
2 /* | |
3 * Copyright (C) Roman Arutyunyan | |
4 * Copyright (C) Nginx, Inc. | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
13 static ngx_int_t ngx_http_v3_process_pseudo_header(ngx_http_request_t *r, | |
14 ngx_str_t *name, ngx_str_t *value); | |
15 | |
16 | |
17 struct { | |
18 ngx_str_t name; | |
19 ngx_uint_t method; | |
20 } ngx_http_v3_methods[] = { | |
21 | |
22 { ngx_string("GET"), NGX_HTTP_GET }, | |
23 { ngx_string("POST"), NGX_HTTP_POST }, | |
24 { ngx_string("HEAD"), NGX_HTTP_HEAD }, | |
25 { ngx_string("OPTIONS"), NGX_HTTP_OPTIONS }, | |
26 { ngx_string("PROPFIND"), NGX_HTTP_PROPFIND }, | |
27 { ngx_string("PUT"), NGX_HTTP_PUT }, | |
28 { ngx_string("MKCOL"), NGX_HTTP_MKCOL }, | |
29 { ngx_string("DELETE"), NGX_HTTP_DELETE }, | |
30 { ngx_string("COPY"), NGX_HTTP_COPY }, | |
31 { ngx_string("MOVE"), NGX_HTTP_MOVE }, | |
32 { ngx_string("PROPPATCH"), NGX_HTTP_PROPPATCH }, | |
33 { ngx_string("LOCK"), NGX_HTTP_LOCK }, | |
34 { ngx_string("UNLOCK"), NGX_HTTP_UNLOCK }, | |
35 { ngx_string("PATCH"), NGX_HTTP_PATCH }, | |
36 { ngx_string("TRACE"), NGX_HTTP_TRACE } | |
37 }; | |
38 | |
39 | |
40 ngx_int_t | |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
41 ngx_http_v3_parse_request(ngx_http_request_t *r, ngx_buf_t *b) |
8226
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
42 { |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
43 size_t len; |
8233
1e45c02f6376
HTTP/3 $request_line variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8230
diff
changeset
|
44 u_char *p; |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
45 ngx_int_t rc, n; |
8226
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
46 ngx_str_t *name, *value; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
47 ngx_connection_t *c; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
48 ngx_http_v3_parse_headers_t *st; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
49 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
50 c = r->connection; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
51 st = r->h3_parse; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
52 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
53 if (st == NULL) { |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
54 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header"); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
55 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
56 st = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_parse_headers_t)); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
57 if (st == NULL) { |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
58 goto failed; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
59 } |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
60 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
61 r->h3_parse = st; |
8407
d6feece1288a
Fixed $request_length for HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8406
diff
changeset
|
62 r->parse_start = b->pos; |
8408
5b367070cc9c
Fixed client buffer reallocation for HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8407
diff
changeset
|
63 r->state = 1; |
8226
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
64 } |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
65 |
8230
31f7c697b6d9
Fixed pointer increment while parsing HTTP/3 header.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
66 while (b->pos < b->last) { |
31f7c697b6d9
Fixed pointer increment while parsing HTTP/3 header.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
67 rc = ngx_http_v3_parse_headers(c, st, *b->pos++); |
8226
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
68 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
69 if (rc == NGX_ERROR) { |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
70 goto failed; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
71 } |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
72 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
73 if (rc == NGX_AGAIN) { |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
74 continue; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
75 } |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
76 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
77 name = &st->header_rep.header.name; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
78 value = &st->header_rep.header.value; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
79 |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
80 n = ngx_http_v3_process_pseudo_header(r, name, value); |
8233
1e45c02f6376
HTTP/3 $request_line variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8230
diff
changeset
|
81 |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
82 if (n == NGX_ERROR) { |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
83 goto failed; |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
84 } |
8233
1e45c02f6376
HTTP/3 $request_line variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8230
diff
changeset
|
85 |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
86 if (n == NGX_OK && rc == NGX_OK) { |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
87 continue; |
8226
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
88 } |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
89 |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
90 len = (r->method_end - r->method_start) + 1 |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
91 + (r->uri_end - r->uri_start) + 1 |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
92 + sizeof("HTTP/3") - 1; |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
93 |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
94 p = ngx_pnalloc(c->pool, len); |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
95 if (p == NULL) { |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
96 goto failed; |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
97 } |
8226
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
98 |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
99 r->request_start = p; |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
100 |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
101 p = ngx_cpymem(p, r->method_start, r->method_end - r->method_start); |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
102 *p++ = ' '; |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
103 p = ngx_cpymem(p, r->uri_start, r->uri_end - r->uri_start); |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
104 *p++ = ' '; |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
105 p = ngx_cpymem(p, "HTTP/3", sizeof("HTTP/3") - 1); |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
106 |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
107 r->request_end = p; |
8452
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
108 r->state = 0; |
8226
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
109 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
110 return NGX_OK; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
111 } |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
112 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
113 return NGX_AGAIN; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
114 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
115 failed: |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
116 |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
117 return NGX_HTTP_PARSE_INVALID_REQUEST; |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
118 } |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
119 |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
120 |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
121 ngx_int_t |
8406
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
122 ngx_http_v3_parse_header(ngx_http_request_t *r, ngx_buf_t *b, |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
123 ngx_uint_t allow_underscores) |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
124 { |
8406
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
125 u_char ch; |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
126 ngx_int_t rc; |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
127 ngx_str_t *name, *value; |
8406
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
128 ngx_uint_t hash, i, n; |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
129 ngx_connection_t *c; |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
130 ngx_http_v3_parse_headers_t *st; |
8452
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
131 enum { |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
132 sw_start = 0, |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
133 sw_done, |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
134 sw_next, |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
135 sw_header |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
136 }; |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
137 |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
138 c = r->connection; |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
139 st = r->h3_parse; |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
140 |
8452
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
141 switch (r->state) { |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
142 |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
143 case sw_start: |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
144 r->parse_start = b->pos; |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
145 |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
146 if (st->state) { |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
147 r->state = sw_next; |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
148 goto done; |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
149 } |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
150 |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
151 name = &st->header_rep.header.name; |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
152 |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
153 if (name->len && name->data[0] != ':') { |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
154 r->state = sw_done; |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
155 goto done; |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
156 } |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
157 |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
158 /* fall through */ |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
159 |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
160 case sw_done: |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
161 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
162 "http3 parse header done"); |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
163 return NGX_HTTP_PARSE_HEADER_DONE; |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
164 |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
165 case sw_next: |
8407
d6feece1288a
Fixed $request_length for HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8406
diff
changeset
|
166 r->parse_start = b->pos; |
8406
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
167 r->invalid_header = 0; |
8452
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
168 break; |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
169 |
8452
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
170 case sw_header: |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
171 break; |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
172 } |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
173 |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
174 while (b->pos < b->last) { |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
175 rc = ngx_http_v3_parse_headers(c, st, *b->pos++); |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
176 |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
177 if (rc == NGX_ERROR) { |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
178 return NGX_HTTP_PARSE_INVALID_HEADER; |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
179 } |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
180 |
8452
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
181 if (rc == NGX_DONE) { |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
182 r->state = sw_done; |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
183 goto done; |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
184 } |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
185 |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
186 if (rc == NGX_OK) { |
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
187 r->state = sw_next; |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
188 goto done; |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
189 } |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
190 } |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
191 |
8452
a6675a976560
HTTP/3: fixed dropping first non-pseudo header.
Roman Arutyunyan <arut@nginx.com>
parents:
8451
diff
changeset
|
192 r->state = sw_header; |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
193 return NGX_AGAIN; |
8226
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
194 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
195 done: |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
196 |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
197 name = &st->header_rep.header.name; |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
198 value = &st->header_rep.header.value; |
8226
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
199 |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
200 r->header_name_start = name->data; |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
201 r->header_name_end = name->data + name->len; |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
202 r->header_start = value->data; |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
203 r->header_end = value->data + value->len; |
8406
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
204 |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
205 hash = 0; |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
206 i = 0; |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
207 |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
208 for (n = 0; n < name->len; n++) { |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
209 ch = name->data[n]; |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
210 |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
211 if (ch >= 'A' && ch <= 'Z') { |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
212 /* |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
213 * A request or response containing uppercase |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
214 * header field names MUST be treated as malformed |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
215 */ |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
216 return NGX_HTTP_PARSE_INVALID_HEADER; |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
217 } |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
218 |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
219 if (ch == '\0') { |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
220 return NGX_HTTP_PARSE_INVALID_HEADER; |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
221 } |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
222 |
8406
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
223 if (ch == '_' && !allow_underscores) { |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
224 r->invalid_header = 1; |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
225 continue; |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
226 } |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
227 |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
228 if ((ch < 'a' || ch > 'z') |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
229 && (ch < '0' || ch > '9') |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
230 && ch != '-' && ch != '_') |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
231 { |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
232 r->invalid_header = 1; |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
233 continue; |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
234 } |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
235 |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
236 hash = ngx_hash(hash, ch); |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
237 r->lowcase_header[i++] = ch; |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
238 i &= (NGX_HTTP_LC_HEADER_LEN - 1); |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
239 } |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
240 |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
241 r->header_hash = hash; |
66feab03d9b7
HTTP/3: restricted symbols in header names.
Roman Arutyunyan <arut@nginx.com>
parents:
8405
diff
changeset
|
242 r->lowcase_index = i; |
8405
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
243 |
d2759e4cc437
HTTP/3: split header parser in two functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8394
diff
changeset
|
244 return NGX_OK; |
8226
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
245 } |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
246 |
8215 | 247 |
248 static ngx_int_t | |
249 ngx_http_v3_process_pseudo_header(ngx_http_request_t *r, ngx_str_t *name, | |
250 ngx_str_t *value) | |
251 { | |
252 ngx_uint_t i; | |
253 ngx_connection_t *c; | |
254 | |
8226
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
255 if (name->len == 0 || name->data[0] != ':') { |
8233
1e45c02f6376
HTTP/3 $request_line variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8230
diff
changeset
|
256 return NGX_DONE; |
8226
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
257 } |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
258 |
8215 | 259 c = r->connection; |
260 | |
261 if (name->len == 7 && ngx_strncmp(name->data, ":method", 7) == 0) { | |
262 r->method_start = value->data; | |
263 r->method_end = value->data + value->len; | |
264 | |
265 for (i = 0; i < sizeof(ngx_http_v3_methods) | |
266 / sizeof(ngx_http_v3_methods[0]); i++) | |
267 { | |
268 if (value->len == ngx_http_v3_methods[i].name.len | |
269 && ngx_strncmp(value->data, ngx_http_v3_methods[i].name.data, | |
270 value->len) == 0) | |
271 { | |
272 r->method = ngx_http_v3_methods[i].method; | |
273 break; | |
274 } | |
275 } | |
276 | |
277 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
278 "http3 method \"%V\" %ui", value, r->method); | |
279 return NGX_OK; | |
280 } | |
281 | |
282 if (name->len == 5 && ngx_strncmp(name->data, ":path", 5) == 0) { | |
283 r->uri_start = value->data; | |
284 r->uri_end = value->data + value->len; | |
285 | |
286 if (ngx_http_parse_uri(r) != NGX_OK) { | |
287 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
288 "client sent invalid :path header: \"%V\"", value); | |
289 return NGX_ERROR; | |
290 } | |
291 | |
292 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
293 "http3 path \"%V\"", value); | |
294 | |
295 return NGX_OK; | |
296 } | |
297 | |
298 if (name->len == 7 && ngx_strncmp(name->data, ":scheme", 7) == 0) { | |
299 r->schema_start = value->data; | |
300 r->schema_end = value->data + value->len; | |
301 | |
302 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
303 "http3 schema \"%V\"", value); | |
304 | |
305 return NGX_OK; | |
306 } | |
307 | |
308 if (name->len == 10 && ngx_strncmp(name->data, ":authority", 10) == 0) { | |
309 r->host_start = value->data; | |
310 r->host_end = value->data + value->len; | |
311 | |
312 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
313 "http3 authority \"%V\"", value); | |
314 | |
315 return NGX_OK; | |
316 } | |
317 | |
8226
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
318 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
319 "http3 unknown pseudo header \"%V\" \"%V\"", name, value); |
8215 | 320 |
8226
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
321 return NGX_OK; |
8215 | 322 } |
323 | |
324 | |
8295
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
325 ngx_int_t |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
326 ngx_http_v3_parse_request_body(ngx_http_request_t *r, ngx_buf_t *b, |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
327 ngx_http_chunked_t *ctx) |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
328 { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
329 ngx_int_t rc; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
330 ngx_connection_t *c; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
331 ngx_http_v3_parse_data_t *st; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
332 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
333 c = r->connection; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
334 st = ctx->h3_parse; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
335 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
336 if (st == NULL) { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
337 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
338 "http3 parse request body"); |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
339 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
340 st = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_parse_data_t)); |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
341 if (st == NULL) { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
342 goto failed; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
343 } |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
344 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
345 r->h3_parse = st; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
346 } |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
347 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
348 if (ctx->size) { |
8329
7bd334b8d91a
HTTP/3: fixed reading request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8295
diff
changeset
|
349 ctx->length = ctx->size + 1; |
7bd334b8d91a
HTTP/3: fixed reading request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8295
diff
changeset
|
350 return (b->pos == b->last) ? NGX_AGAIN : NGX_OK; |
8295
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
351 } |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
352 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
353 while (b->pos < b->last) { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
354 rc = ngx_http_v3_parse_data(c, st, *b->pos++); |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
355 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
356 if (rc == NGX_ERROR) { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
357 goto failed; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
358 } |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
359 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
360 if (rc == NGX_AGAIN) { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
361 continue; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
362 } |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
363 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
364 /* rc == NGX_DONE */ |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
365 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
366 ctx->size = st->length; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
367 return NGX_OK; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
368 } |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
369 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
370 if (!b->last_buf) { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
371 ctx->length = 1; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
372 return NGX_AGAIN; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
373 } |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
374 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
375 if (st->state) { |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
376 goto failed; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
377 } |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
378 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
379 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse header done"); |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
380 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
381 return NGX_DONE; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
382 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
383 failed: |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
384 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
385 return NGX_ERROR; |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
386 } |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
387 |
5649079a41f4
Parsing HTTP/3 request body.
Roman Arutyunyan <arut@nginx.com>
parents:
8292
diff
changeset
|
388 |
8215 | 389 ngx_chain_t * |
390 ngx_http_v3_create_header(ngx_http_request_t *r) | |
391 { | |
392 u_char *p; | |
8253
69365c7bb07f
Removed unused variable.
Roman Arutyunyan <arut@nginx.com>
parents:
8238
diff
changeset
|
393 size_t len, n; |
8215 | 394 ngx_buf_t *b; |
395 ngx_uint_t i, j; | |
396 ngx_chain_t *hl, *cl, *bl; | |
397 ngx_list_part_t *part; | |
398 ngx_table_elt_t *header; | |
399 ngx_connection_t *c; | |
400 ngx_http_core_loc_conf_t *clcf; | |
401 | |
402 c = r->connection; | |
403 | |
404 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 create header"); | |
405 | |
8291 | 406 len = 2; |
8215 | 407 |
408 if (r->headers_out.status == NGX_HTTP_OK) { | |
409 len += ngx_http_v3_encode_prefix_int(NULL, 25, 6); | |
410 | |
411 } else { | |
412 len += 3 + ngx_http_v3_encode_prefix_int(NULL, 25, 4) | |
413 + ngx_http_v3_encode_prefix_int(NULL, 3, 7); | |
414 } | |
415 | |
416 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
417 | |
418 if (r->headers_out.server == NULL) { | |
419 if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) { | |
420 n = sizeof(NGINX_VER) - 1; | |
421 | |
422 } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) { | |
423 n = sizeof(NGINX_VER_BUILD) - 1; | |
424 | |
425 } else { | |
426 n = sizeof("nginx") - 1; | |
427 } | |
428 | |
429 len += ngx_http_v3_encode_prefix_int(NULL, 92, 4) | |
430 + ngx_http_v3_encode_prefix_int(NULL, n, 7) + n; | |
431 } | |
432 | |
433 if (r->headers_out.date == NULL) { | |
434 len += ngx_http_v3_encode_prefix_int(NULL, 6, 4) | |
435 + ngx_http_v3_encode_prefix_int(NULL, ngx_cached_http_time.len, | |
436 7) | |
437 + ngx_cached_http_time.len; | |
438 } | |
439 | |
440 if (r->headers_out.content_type.len) { | |
441 n = r->headers_out.content_type.len; | |
442 | |
443 if (r->headers_out.content_type_len == r->headers_out.content_type.len | |
444 && r->headers_out.charset.len) | |
445 { | |
446 n += sizeof("; charset=") - 1 + r->headers_out.charset.len; | |
447 } | |
448 | |
449 len += ngx_http_v3_encode_prefix_int(NULL, 53, 4) | |
450 + ngx_http_v3_encode_prefix_int(NULL, n, 7) + n; | |
451 } | |
452 | |
8238
a3257a725b3d
Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8233
diff
changeset
|
453 if (r->headers_out.content_length_n > 0) { |
a3257a725b3d
Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8233
diff
changeset
|
454 len += ngx_http_v3_encode_prefix_int(NULL, 4, 4) + 1 + NGX_OFF_T_LEN; |
8215 | 455 |
8238
a3257a725b3d
Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8233
diff
changeset
|
456 } else if (r->headers_out.content_length_n == 0) { |
a3257a725b3d
Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8233
diff
changeset
|
457 len += ngx_http_v3_encode_prefix_int(NULL, 4, 6); |
8215 | 458 } |
459 | |
460 if (r->headers_out.last_modified == NULL | |
461 && r->headers_out.last_modified_time != -1) | |
462 { | |
463 len += ngx_http_v3_encode_prefix_int(NULL, 10, 4) + 1 | |
464 + sizeof("Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT"); | |
465 } | |
466 | |
467 /* XXX location */ | |
468 | |
469 #if (NGX_HTTP_GZIP) | |
470 if (r->gzip_vary) { | |
471 if (clcf->gzip_vary) { | |
472 /* Vary: Accept-Encoding */ | |
473 len += ngx_http_v3_encode_prefix_int(NULL, 59, 6); | |
474 | |
475 } else { | |
476 r->gzip_vary = 0; | |
477 } | |
478 } | |
479 #endif | |
480 | |
481 part = &r->headers_out.headers.part; | |
482 header = part->elts; | |
483 | |
484 for (i = 0; /* void */; i++) { | |
485 | |
486 if (i >= part->nelts) { | |
487 if (part->next == NULL) { | |
488 break; | |
489 } | |
490 | |
491 part = part->next; | |
492 header = part->elts; | |
493 i = 0; | |
494 } | |
495 | |
496 if (header[i].hash == 0) { | |
497 continue; | |
498 } | |
499 | |
500 len += ngx_http_v3_encode_prefix_int(NULL, header[i].key.len, 3) | |
501 + header[i].key.len | |
502 + ngx_http_v3_encode_prefix_int(NULL, header[i].value.len, 7 ) | |
503 + header[i].value.len; | |
504 } | |
505 | |
506 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 header len:%uz", len); | |
507 | |
508 b = ngx_create_temp_buf(r->pool, len); | |
509 if (b == NULL) { | |
510 return NULL; | |
511 } | |
512 | |
513 *b->last++ = 0; | |
514 *b->last++ = 0; | |
515 | |
516 if (r->headers_out.status == NGX_HTTP_OK) { | |
517 /* :status: 200 */ | |
518 *b->last = 0xc0; | |
519 b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, 25, 6); | |
520 | |
521 } else { | |
522 /* :status: 200 */ | |
523 *b->last = 0x70; | |
524 b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, 25, 4); | |
525 *b->last = 0; | |
526 b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, 3, 7); | |
8226
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
8219
diff
changeset
|
527 b->last = ngx_sprintf(b->last, "%03ui", r->headers_out.status); |
8215 | 528 } |
529 | |
530 if (r->headers_out.server == NULL) { | |
531 if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) { | |
532 p = (u_char *) NGINX_VER; | |
533 n = sizeof(NGINX_VER) - 1; | |
534 | |
535 } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) { | |
536 p = (u_char *) NGINX_VER_BUILD; | |
537 n = sizeof(NGINX_VER_BUILD) - 1; | |
538 | |
539 } else { | |
540 p = (u_char *) "nginx"; | |
541 n = sizeof("nginx") - 1; | |
542 } | |
543 | |
544 /* server */ | |
545 *b->last = 0x70; | |
546 b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, 92, 4); | |
547 *b->last = 0; | |
548 b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, n, 7); | |
549 b->last = ngx_cpymem(b->last, p, n); | |
550 } | |
551 | |
552 if (r->headers_out.date == NULL) { | |
553 /* date */ | |
554 *b->last = 0x70; | |
555 b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, 6, 4); | |
556 *b->last = 0; | |
557 b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, | |
558 ngx_cached_http_time.len, 7); | |
559 b->last = ngx_cpymem(b->last, ngx_cached_http_time.data, | |
560 ngx_cached_http_time.len); | |
561 } | |
562 | |
563 if (r->headers_out.content_type.len) { | |
564 n = r->headers_out.content_type.len; | |
565 | |
566 if (r->headers_out.content_type_len == r->headers_out.content_type.len | |
567 && r->headers_out.charset.len) | |
568 { | |
569 n += sizeof("; charset=") - 1 + r->headers_out.charset.len; | |
570 } | |
571 | |
572 /* content-type: text/plain */ | |
573 *b->last = 0x70; | |
574 b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, 53, 4); | |
575 *b->last = 0; | |
576 b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, n, 7); | |
577 | |
578 p = b->last; | |
579 b->last = ngx_copy(b->last, r->headers_out.content_type.data, | |
580 r->headers_out.content_type.len); | |
581 | |
582 if (r->headers_out.content_type_len == r->headers_out.content_type.len | |
583 && r->headers_out.charset.len) | |
584 { | |
585 b->last = ngx_cpymem(b->last, "; charset=", | |
586 sizeof("; charset=") - 1); | |
587 b->last = ngx_copy(b->last, r->headers_out.charset.data, | |
588 r->headers_out.charset.len); | |
589 | |
590 /* update r->headers_out.content_type for possible logging */ | |
591 | |
592 r->headers_out.content_type.len = b->last - p; | |
593 r->headers_out.content_type.data = p; | |
594 } | |
595 } | |
596 | |
8238
a3257a725b3d
Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8233
diff
changeset
|
597 if (r->headers_out.content_length_n > 0) { |
8215 | 598 /* content-length: 0 */ |
599 *b->last = 0x70; | |
600 b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, 4, 4); | |
601 p = b->last++; | |
602 b->last = ngx_sprintf(b->last, "%O", r->headers_out.content_length_n); | |
603 *p = b->last - p - 1; | |
8238
a3257a725b3d
Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8233
diff
changeset
|
604 |
a3257a725b3d
Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8233
diff
changeset
|
605 } else if (r->headers_out.content_length_n == 0) { |
a3257a725b3d
Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8233
diff
changeset
|
606 /* content-length: 0 */ |
a3257a725b3d
Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8233
diff
changeset
|
607 *b->last = 0xc0; |
a3257a725b3d
Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8233
diff
changeset
|
608 b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, 4, 6); |
8215 | 609 } |
610 | |
611 if (r->headers_out.last_modified == NULL | |
612 && r->headers_out.last_modified_time != -1) | |
613 { | |
614 /* last-modified */ | |
615 *b->last = 0x70; | |
616 b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, 10, 4); | |
617 p = b->last++; | |
618 b->last = ngx_http_time(b->last, r->headers_out.last_modified_time); | |
619 *p = b->last - p - 1; | |
620 } | |
621 | |
622 #if (NGX_HTTP_GZIP) | |
623 if (r->gzip_vary) { | |
624 /* vary: accept-encoding */ | |
625 *b->last = 0xc0; | |
626 b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, 59, 6); | |
627 } | |
628 #endif | |
629 | |
630 part = &r->headers_out.headers.part; | |
631 header = part->elts; | |
632 | |
633 for (i = 0; /* void */; i++) { | |
634 | |
635 if (i >= part->nelts) { | |
636 if (part->next == NULL) { | |
637 break; | |
638 } | |
639 | |
640 part = part->next; | |
641 header = part->elts; | |
642 i = 0; | |
643 } | |
644 | |
645 if (header[i].hash == 0) { | |
646 continue; | |
647 } | |
648 | |
649 *b->last = 0x30; | |
650 b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, | |
651 header[i].key.len, | |
652 3); | |
653 for (j = 0; j < header[i].key.len; j++) { | |
654 *b->last++ = ngx_tolower(header[i].key.data[j]); | |
655 } | |
656 | |
657 *b->last = 0; | |
658 b->last = (u_char *) ngx_http_v3_encode_prefix_int(b->last, | |
659 header[i].value.len, | |
660 7); | |
661 b->last = ngx_copy(b->last, header[i].value.data, header[i].value.len); | |
662 } | |
663 | |
8238
a3257a725b3d
Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8233
diff
changeset
|
664 if (r->header_only) { |
a3257a725b3d
Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8233
diff
changeset
|
665 b->last_buf = 1; |
a3257a725b3d
Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8233
diff
changeset
|
666 } |
a3257a725b3d
Fixed header creation for header_only responses in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8233
diff
changeset
|
667 |
8215 | 668 cl = ngx_alloc_chain_link(c->pool); |
669 if (cl == NULL) { | |
670 return NULL; | |
671 } | |
672 | |
673 cl->buf = b; | |
674 cl->next = NULL; | |
675 | |
676 n = b->last - b->pos; | |
677 | |
678 len = 1 + ngx_http_v3_encode_varlen_int(NULL, n); | |
679 | |
680 b = ngx_create_temp_buf(c->pool, len); | |
681 if (b == NULL) { | |
682 return NULL; | |
683 } | |
684 | |
685 *b->last++ = NGX_HTTP_V3_FRAME_HEADERS; | |
686 b->last = (u_char *) ngx_http_v3_encode_varlen_int(b->last, n); | |
687 | |
688 hl = ngx_alloc_chain_link(c->pool); | |
689 if (hl == NULL) { | |
690 return NULL; | |
691 } | |
692 | |
693 hl->buf = b; | |
694 hl->next = cl; | |
695 | |
8451
908cae4f3078
HTTP/3: do not emit a DATA frame header for header_only responses.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8408
diff
changeset
|
696 if (r->headers_out.content_length_n >= 0 && !r->header_only) { |
8215 | 697 len = 1 + ngx_http_v3_encode_varlen_int(NULL, |
698 r->headers_out.content_length_n); | |
699 | |
700 b = ngx_create_temp_buf(c->pool, len); | |
701 if (b == NULL) { | |
8394 | 702 return NULL; |
8215 | 703 } |
704 | |
705 *b->last++ = NGX_HTTP_V3_FRAME_DATA; | |
706 b->last = (u_char *) ngx_http_v3_encode_varlen_int(b->last, | |
707 r->headers_out.content_length_n); | |
708 | |
709 bl = ngx_alloc_chain_link(c->pool); | |
710 if (bl == NULL) { | |
711 return NULL; | |
712 } | |
713 | |
714 bl->buf = b; | |
715 bl->next = NULL; | |
716 cl->next = bl; | |
717 } | |
718 | |
719 return hl; | |
720 } | |
8292
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
721 |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
722 |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
723 ngx_chain_t * |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
724 ngx_http_v3_create_trailers(ngx_http_request_t *r) |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
725 { |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
726 ngx_buf_t *b; |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
727 ngx_chain_t *cl; |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
728 |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
729 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
730 "http3 create trailers"); |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
731 |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
732 /* XXX */ |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
733 |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
734 b = ngx_calloc_buf(r->pool); |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
735 if (b == NULL) { |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
736 return NULL; |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
737 } |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
738 |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
739 b->last_buf = 1; |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
740 |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
741 cl = ngx_alloc_chain_link(r->pool); |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
742 if (cl == NULL) { |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
743 return NULL; |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
744 } |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
745 |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
746 cl->buf = b; |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
747 cl->next = NULL; |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
748 |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
749 return cl; |
46e3542d51b3
Chunked response body in HTTP/3.
Roman Arutyunyan <arut@nginx.com>
parents:
8291
diff
changeset
|
750 } |