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