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