Mercurial > hg > nginx
comparison src/http/v3/ngx_http_v3_filter_module.c @ 8851:051968b73c59 quic
HTTP/3: Huffman encoding for the Location response field.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Mon, 13 Sep 2021 16:25:32 +0300 |
parents | 355461f0cc3b |
children | 8fc9c7f2c533 |
comparison
equal
deleted
inserted
replaced
8850:355461f0cc3b | 8851:051968b73c59 |
---|---|
93 ngx_http_v3_header_filter(ngx_http_request_t *r) | 93 ngx_http_v3_header_filter(ngx_http_request_t *r) |
94 { | 94 { |
95 u_char *p; | 95 u_char *p; |
96 size_t len, n; | 96 size_t len, n; |
97 ngx_buf_t *b; | 97 ngx_buf_t *b; |
98 ngx_str_t host; | 98 ngx_str_t host, location; |
99 ngx_uint_t i, port; | 99 ngx_uint_t i, port; |
100 ngx_chain_t *out, *hl, *cl, **ll; | 100 ngx_chain_t *out, *hl, *cl, **ll; |
101 ngx_list_part_t *part; | 101 ngx_list_part_t *part; |
102 ngx_table_elt_t *header; | 102 ngx_table_elt_t *header; |
103 ngx_connection_t *c; | 103 ngx_connection_t *c; |
227 len += ngx_http_v3_encode_field_lri(NULL, 0, | 227 len += ngx_http_v3_encode_field_lri(NULL, 0, |
228 NGX_HTTP_V3_HEADER_LAST_MODIFIED, NULL, | 228 NGX_HTTP_V3_HEADER_LAST_MODIFIED, NULL, |
229 sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1); | 229 sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1); |
230 } | 230 } |
231 | 231 |
232 if (r->headers_out.location | 232 if (r->headers_out.location && r->headers_out.location->value.len) { |
233 && r->headers_out.location->value.len | 233 |
234 && r->headers_out.location->value.data[0] == '/' | 234 if (r->headers_out.location->value.data[0] == '/' |
235 && clcf->absolute_redirect) | 235 && clcf->absolute_redirect) |
236 { | 236 { |
237 if (clcf->server_name_in_redirect) { | |
238 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); | |
239 host = cscf->server_name; | |
240 | |
241 } else if (r->headers_in.server.len) { | |
242 host = r->headers_in.server; | |
243 | |
244 } else { | |
245 host.len = NGX_SOCKADDR_STRLEN; | |
246 host.data = addr; | |
247 | |
248 if (ngx_connection_local_sockaddr(c, &host, 0) != NGX_OK) { | |
249 return NGX_ERROR; | |
250 } | |
251 } | |
252 | |
253 port = ngx_inet_get_port(c->local_sockaddr); | |
254 | |
255 location.len = sizeof("https://") - 1 + host.len | |
256 + r->headers_out.location->value.len; | |
257 | |
258 if (clcf->port_in_redirect) { | |
259 port = (port == 443) ? 0 : port; | |
260 | |
261 } else { | |
262 port = 0; | |
263 } | |
264 | |
265 if (port) { | |
266 location.len += sizeof(":65535") - 1; | |
267 } | |
268 | |
269 location.data = ngx_pnalloc(r->pool, location.len); | |
270 if (location.data == NULL) { | |
271 return NGX_ERROR; | |
272 } | |
273 | |
274 p = ngx_cpymem(location.data, "https://", sizeof("https://") - 1); | |
275 p = ngx_cpymem(p, host.data, host.len); | |
276 | |
277 if (port) { | |
278 p = ngx_sprintf(p, ":%ui", port); | |
279 } | |
280 | |
281 p = ngx_cpymem(p, r->headers_out.location->value.data, | |
282 r->headers_out.location->value.len); | |
283 | |
284 /* update r->headers_out.location->value for possible logging */ | |
285 | |
286 r->headers_out.location->value.len = p - location.data; | |
287 r->headers_out.location->value.data = location.data; | |
288 ngx_str_set(&r->headers_out.location->key, "Location"); | |
289 } | |
290 | |
237 r->headers_out.location->hash = 0; | 291 r->headers_out.location->hash = 0; |
238 | 292 |
239 if (clcf->server_name_in_redirect) { | |
240 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); | |
241 host = cscf->server_name; | |
242 | |
243 } else if (r->headers_in.server.len) { | |
244 host = r->headers_in.server; | |
245 | |
246 } else { | |
247 host.len = NGX_SOCKADDR_STRLEN; | |
248 host.data = addr; | |
249 | |
250 if (ngx_connection_local_sockaddr(c, &host, 0) != NGX_OK) { | |
251 return NGX_ERROR; | |
252 } | |
253 } | |
254 | |
255 port = ngx_inet_get_port(c->local_sockaddr); | |
256 | |
257 n = sizeof("https://") - 1 + host.len | |
258 + r->headers_out.location->value.len; | |
259 | |
260 if (clcf->port_in_redirect) { | |
261 port = (port == 443) ? 0 : port; | |
262 | |
263 } else { | |
264 port = 0; | |
265 } | |
266 | |
267 if (port) { | |
268 n += sizeof(":65535") - 1; | |
269 } | |
270 | |
271 len += ngx_http_v3_encode_field_lri(NULL, 0, | 293 len += ngx_http_v3_encode_field_lri(NULL, 0, |
272 NGX_HTTP_V3_HEADER_LOCATION, NULL, n); | 294 NGX_HTTP_V3_HEADER_LOCATION, NULL, |
273 | 295 r->headers_out.location->value.len); |
274 } else { | |
275 ngx_str_null(&host); | |
276 port = 0; | |
277 } | 296 } |
278 | 297 |
279 #if (NGX_HTTP_GZIP) | 298 #if (NGX_HTTP_GZIP) |
280 if (r->gzip_vary) { | 299 if (r->gzip_vary) { |
281 if (clcf->gzip_vary) { | 300 if (clcf->gzip_vary) { |
423 b->last = (u_char *) ngx_http_v3_encode_field_lri(b->last, 0, | 442 b->last = (u_char *) ngx_http_v3_encode_field_lri(b->last, 0, |
424 NGX_HTTP_V3_HEADER_LAST_MODIFIED, | 443 NGX_HTTP_V3_HEADER_LAST_MODIFIED, |
425 p, n); | 444 p, n); |
426 } | 445 } |
427 | 446 |
428 if (host.data) { | 447 if (r->headers_out.location && r->headers_out.location->value.len) { |
429 n = sizeof("https://") - 1 + host.len | |
430 + r->headers_out.location->value.len; | |
431 | |
432 if (port) { | |
433 n += ngx_sprintf(b->last, ":%ui", port) - b->last; | |
434 } | |
435 | |
436 b->last = (u_char *) ngx_http_v3_encode_field_lri(b->last, 0, | 448 b->last = (u_char *) ngx_http_v3_encode_field_lri(b->last, 0, |
437 NGX_HTTP_V3_HEADER_LOCATION, | 449 NGX_HTTP_V3_HEADER_LOCATION, |
438 NULL, n); | 450 r->headers_out.location->value.data, |
439 | 451 r->headers_out.location->value.len); |
440 p = b->last; | |
441 b->last = ngx_cpymem(b->last, "https://", sizeof("https://") - 1); | |
442 b->last = ngx_cpymem(b->last, host.data, host.len); | |
443 | |
444 if (port) { | |
445 b->last = ngx_sprintf(b->last, ":%ui", port); | |
446 } | |
447 | |
448 b->last = ngx_cpymem(b->last, r->headers_out.location->value.data, | |
449 r->headers_out.location->value.len); | |
450 | |
451 /* update r->headers_out.location->value for possible logging */ | |
452 | |
453 r->headers_out.location->value.len = b->last - p; | |
454 r->headers_out.location->value.data = p; | |
455 ngx_str_set(&r->headers_out.location->key, "Location"); | |
456 } | 452 } |
457 | 453 |
458 #if (NGX_HTTP_GZIP) | 454 #if (NGX_HTTP_GZIP) |
459 if (r->gzip_vary) { | 455 if (r->gzip_vary) { |
460 b->last = (u_char *) ngx_http_v3_encode_field_ri(b->last, 0, | 456 b->last = (u_char *) ngx_http_v3_encode_field_ri(b->last, 0, |