Mercurial > hg > nginx
comparison src/http/v3/ngx_http_v3_request.c @ 8406:66feab03d9b7 quic
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.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Tue, 19 May 2020 15:34:00 +0300 |
parents | d2759e4cc437 |
children | d6feece1288a |
comparison
equal
deleted
inserted
replaced
8405:d2759e4cc437 | 8406:66feab03d9b7 |
---|---|
114 return NGX_HTTP_PARSE_INVALID_REQUEST; | 114 return NGX_HTTP_PARSE_INVALID_REQUEST; |
115 } | 115 } |
116 | 116 |
117 | 117 |
118 ngx_int_t | 118 ngx_int_t |
119 ngx_http_v3_parse_header(ngx_http_request_t *r, ngx_buf_t *b) | 119 ngx_http_v3_parse_header(ngx_http_request_t *r, ngx_buf_t *b, |
120 ngx_uint_t allow_underscores) | |
120 { | 121 { |
122 u_char ch; | |
121 ngx_int_t rc; | 123 ngx_int_t rc; |
122 ngx_str_t *name, *value; | 124 ngx_str_t *name, *value; |
125 ngx_uint_t hash, i, n; | |
123 ngx_connection_t *c; | 126 ngx_connection_t *c; |
124 ngx_http_v3_parse_headers_t *st; | 127 ngx_http_v3_parse_headers_t *st; |
125 | 128 |
126 c = r->connection; | 129 c = r->connection; |
127 st = r->h3_parse; | 130 st = r->h3_parse; |
131 | |
132 if (st->header_rep.state == 0) { | |
133 r->invalid_header = 0; | |
134 } | |
128 | 135 |
129 if (st->state == 0) { | 136 if (st->state == 0) { |
130 if (r->header_name_start == NULL) { | 137 if (r->header_name_start == NULL) { |
131 name = &st->header_rep.header.name; | 138 name = &st->header_rep.header.name; |
132 | 139 |
162 | 169 |
163 r->header_name_start = name->data; | 170 r->header_name_start = name->data; |
164 r->header_name_end = name->data + name->len; | 171 r->header_name_end = name->data + name->len; |
165 r->header_start = value->data; | 172 r->header_start = value->data; |
166 r->header_end = value->data + value->len; | 173 r->header_end = value->data + value->len; |
167 r->header_hash = ngx_hash_key(name->data, name->len); | 174 |
168 | 175 hash = 0; |
169 /* XXX r->lowcase_index = i; */ | 176 i = 0; |
177 | |
178 for (n = 0; n < name->len; n++) { | |
179 ch = name->data[n]; | |
180 | |
181 if (ch >= 'A' && ch <= 'Z') { | |
182 /* | |
183 * A request or response containing uppercase | |
184 * header field names MUST be treated as malformed | |
185 */ | |
186 return NGX_HTTP_PARSE_INVALID_HEADER; | |
187 } | |
188 | |
189 if (ch == '\0') { | |
190 return NGX_HTTP_PARSE_INVALID_HEADER; | |
191 } | |
192 | |
193 if (ch == '_' && !allow_underscores) { | |
194 r->invalid_header = 1; | |
195 continue; | |
196 } | |
197 | |
198 if ((ch < 'a' || ch > 'z') | |
199 && (ch < '0' || ch > '9') | |
200 && ch != '-' && ch != '_') | |
201 { | |
202 r->invalid_header = 1; | |
203 continue; | |
204 } | |
205 | |
206 hash = ngx_hash(hash, ch); | |
207 r->lowcase_header[i++] = ch; | |
208 i &= (NGX_HTTP_LC_HEADER_LEN - 1); | |
209 } | |
210 | |
211 r->header_hash = hash; | |
212 r->lowcase_index = i; | |
170 | 213 |
171 return NGX_OK; | 214 return NGX_OK; |
172 } | 215 } |
173 | 216 |
174 | 217 |