Mercurial > hg > nginx
annotate src/http/v3/ngx_http_v3_encode.c @ 9112:d59277dd3d8c
QUIC: fixed post-close use-after-free.
Previously, ngx_quic_close_connection() could be called in a way that QUIC
connection was accessed after the call. In most cases the connection is not
closed right away, but close timeout is scheduled. However, it's not always
the case. Also, if the close process started earlier for a different reason,
calling ngx_quic_close_connection() may actually close the connection. The
connection object should not be accessed after that.
Now, when possible, return statement is added to eliminate post-close connection
object access. In other places ngx_quic_close_connection() is substituted with
posting close event.
Also, the new way of closing connection in ngx_quic_stream_cleanup_handler()
fixes another problem in this function. Previously it passed stream connection
instead of QUIC connection to ngx_quic_close_connection(). This could result
in incomplete connection shutdown. One consequence of that could be that QUIC
streams were freed without shutting down their application contexts. This could
result in another use-after-free.
Found by Coverity (CID 1530402).
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Mon, 22 May 2023 15:59:42 +0400 |
parents | 5c86189a1c1b |
children |
rev | line source |
---|---|
8215 | 1 |
2 /* | |
3 * Copyright (C) Roman Arutyunyan | |
4 * Copyright (C) Nginx, Inc. | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
13 uintptr_t | |
14 ngx_http_v3_encode_varlen_int(u_char *p, uint64_t value) | |
15 { | |
16 if (value <= 63) { | |
17 if (p == NULL) { | |
18 return 1; | |
19 } | |
20 | |
21 *p++ = value; | |
22 return (uintptr_t) p; | |
23 } | |
24 | |
25 if (value <= 16383) { | |
26 if (p == NULL) { | |
27 return 2; | |
28 } | |
29 | |
30 *p++ = 0x40 | (value >> 8); | |
31 *p++ = value; | |
32 return (uintptr_t) p; | |
33 } | |
34 | |
35 if (value <= 1073741823) { | |
36 if (p == NULL) { | |
8349
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
37 return 4; |
8215 | 38 } |
39 | |
8349
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
40 *p++ = 0x80 | (value >> 24); |
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
41 *p++ = (value >> 16); |
8215 | 42 *p++ = (value >> 8); |
43 *p++ = value; | |
44 return (uintptr_t) p; | |
45 } | |
46 | |
47 if (p == NULL) { | |
8349
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
48 return 8; |
8215 | 49 } |
50 | |
8349
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
51 *p++ = 0xc0 | (value >> 56); |
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
52 *p++ = (value >> 48); |
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
53 *p++ = (value >> 40); |
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
54 *p++ = (value >> 32); |
b13176e717ba
HTTP/3: fixed encoding variable-length integers.
Roman Arutyunyan <arut@nginx.com>
parents:
8226
diff
changeset
|
55 *p++ = (value >> 24); |
8215 | 56 *p++ = (value >> 16); |
57 *p++ = (value >> 8); | |
58 *p++ = value; | |
59 return (uintptr_t) p; | |
60 } | |
61 | |
62 | |
63 uintptr_t | |
64 ngx_http_v3_encode_prefix_int(u_char *p, uint64_t value, ngx_uint_t prefix) | |
65 { | |
66 ngx_uint_t thresh, n; | |
67 | |
68 thresh = (1 << prefix) - 1; | |
69 | |
70 if (value < thresh) { | |
71 if (p == NULL) { | |
72 return 1; | |
73 } | |
74 | |
75 *p++ |= value; | |
76 return (uintptr_t) p; | |
77 } | |
78 | |
79 value -= thresh; | |
80 | |
8455
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8349
diff
changeset
|
81 if (p == NULL) { |
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8349
diff
changeset
|
82 for (n = 2; value >= 128; n++) { |
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8349
diff
changeset
|
83 value >>= 7; |
8215 | 84 } |
85 | |
8455
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8349
diff
changeset
|
86 return n; |
8215 | 87 } |
88 | |
89 *p++ |= thresh; | |
90 | |
8455
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8349
diff
changeset
|
91 while (value >= 128) { |
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8349
diff
changeset
|
92 *p++ = 0x80 | value; |
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8349
diff
changeset
|
93 value >>= 7; |
8215 | 94 } |
95 | |
8455
b0e81f49d7c0
HTTP/3: fixed prefixed integer encoding and decoding.
Roman Arutyunyan <arut@nginx.com>
parents:
8349
diff
changeset
|
96 *p++ = value; |
8215 | 97 |
98 return (uintptr_t) p; | |
99 } | |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
100 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
101 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
102 uintptr_t |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
103 ngx_http_v3_encode_field_section_prefix(u_char *p, ngx_uint_t insert_count, |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
104 ngx_uint_t sign, ngx_uint_t delta_base) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
105 { |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
106 if (p == NULL) { |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
107 return ngx_http_v3_encode_prefix_int(NULL, insert_count, 8) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
108 + ngx_http_v3_encode_prefix_int(NULL, delta_base, 7); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
109 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
110 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
111 *p = 0; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
112 p = (u_char *) ngx_http_v3_encode_prefix_int(p, insert_count, 8); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
113 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
114 *p = sign ? 0x80 : 0; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
115 p = (u_char *) ngx_http_v3_encode_prefix_int(p, delta_base, 7); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
116 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
117 return (uintptr_t) p; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
118 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
119 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
120 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
121 uintptr_t |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
122 ngx_http_v3_encode_field_ri(u_char *p, ngx_uint_t dynamic, ngx_uint_t index) |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
123 { |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
124 /* Indexed Field Line */ |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
125 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
126 if (p == NULL) { |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
127 return ngx_http_v3_encode_prefix_int(NULL, index, 6); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
128 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
129 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
130 *p = dynamic ? 0x80 : 0xc0; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
131 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
132 return ngx_http_v3_encode_prefix_int(p, index, 6); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
133 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
134 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
135 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
136 uintptr_t |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
137 ngx_http_v3_encode_field_lri(u_char *p, ngx_uint_t dynamic, ngx_uint_t index, |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
138 u_char *data, size_t len) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
139 { |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
140 size_t hlen; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
141 u_char *p1, *p2; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
142 |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
143 /* Literal Field Line With Name Reference */ |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
144 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
145 if (p == NULL) { |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
146 return ngx_http_v3_encode_prefix_int(NULL, index, 4) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
147 + ngx_http_v3_encode_prefix_int(NULL, len, 7) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
148 + len; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
149 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
150 |
8534
985f9351dd87
HTTP/3: do not set the never-indexed literal bit by default.
Roman Arutyunyan <arut@nginx.com>
parents:
8491
diff
changeset
|
151 *p = dynamic ? 0x40 : 0x50; |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
152 p = (u_char *) ngx_http_v3_encode_prefix_int(p, index, 4); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
153 |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
154 p1 = p; |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
155 *p = 0; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
156 p = (u_char *) ngx_http_v3_encode_prefix_int(p, len, 7); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
157 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
158 if (data) { |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
159 p2 = p; |
8942
5c86189a1c1b
Merged with the default branch.
Ruslan Ermilov <ru@nginx.com>
parents:
8848
diff
changeset
|
160 hlen = ngx_http_huff_encode(data, len, p, 0); |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
161 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
162 if (hlen) { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
163 p = p1; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
164 *p = 0x80; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
165 p = (u_char *) ngx_http_v3_encode_prefix_int(p, hlen, 7); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
166 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
167 if (p != p2) { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
168 ngx_memmove(p, p2, hlen); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
169 } |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
170 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
171 p += hlen; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
172 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
173 } else { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
174 p = ngx_cpymem(p, data, len); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
175 } |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
176 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
177 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
178 return (uintptr_t) p; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
179 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
180 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
181 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
182 uintptr_t |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
183 ngx_http_v3_encode_field_l(u_char *p, ngx_str_t *name, ngx_str_t *value) |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
184 { |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
185 size_t hlen; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
186 u_char *p1, *p2; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
187 |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
188 /* Literal Field Line With Literal Name */ |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
189 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
190 if (p == NULL) { |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
191 return ngx_http_v3_encode_prefix_int(NULL, name->len, 3) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
192 + name->len |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
193 + ngx_http_v3_encode_prefix_int(NULL, value->len, 7) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
194 + value->len; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
195 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
196 |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
197 p1 = p; |
8534
985f9351dd87
HTTP/3: do not set the never-indexed literal bit by default.
Roman Arutyunyan <arut@nginx.com>
parents:
8491
diff
changeset
|
198 *p = 0x20; |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
199 p = (u_char *) ngx_http_v3_encode_prefix_int(p, name->len, 3); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
200 |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
201 p2 = p; |
8942
5c86189a1c1b
Merged with the default branch.
Ruslan Ermilov <ru@nginx.com>
parents:
8848
diff
changeset
|
202 hlen = ngx_http_huff_encode(name->data, name->len, p, 1); |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
203 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
204 if (hlen) { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
205 p = p1; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
206 *p = 0x28; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
207 p = (u_char *) ngx_http_v3_encode_prefix_int(p, hlen, 3); |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
208 |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
209 if (p != p2) { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
210 ngx_memmove(p, p2, hlen); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
211 } |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
212 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
213 p += hlen; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
214 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
215 } else { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
216 ngx_strlow(p, name->data, name->len); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
217 p += name->len; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
218 } |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
219 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
220 p1 = p; |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
221 *p = 0; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
222 p = (u_char *) ngx_http_v3_encode_prefix_int(p, value->len, 7); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
223 |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
224 p2 = p; |
8942
5c86189a1c1b
Merged with the default branch.
Ruslan Ermilov <ru@nginx.com>
parents:
8848
diff
changeset
|
225 hlen = ngx_http_huff_encode(value->data, value->len, p, 0); |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
226 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
227 if (hlen) { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
228 p = p1; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
229 *p = 0x80; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
230 p = (u_char *) ngx_http_v3_encode_prefix_int(p, hlen, 7); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
231 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
232 if (p != p2) { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
233 ngx_memmove(p, p2, hlen); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
234 } |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
235 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
236 p += hlen; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
237 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
238 } else { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
239 p = ngx_cpymem(p, value->data, value->len); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
240 } |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
241 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
242 return (uintptr_t) p; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
243 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
244 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
245 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
246 uintptr_t |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
247 ngx_http_v3_encode_field_pbi(u_char *p, ngx_uint_t index) |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
248 { |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
249 /* Indexed Field Line With Post-Base Index */ |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
250 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
251 if (p == NULL) { |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
252 return ngx_http_v3_encode_prefix_int(NULL, index, 4); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
253 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
254 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
255 *p = 0x10; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
256 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
257 return ngx_http_v3_encode_prefix_int(p, index, 4); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
258 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
259 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
260 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
261 uintptr_t |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
262 ngx_http_v3_encode_field_lpbi(u_char *p, ngx_uint_t index, u_char *data, |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
263 size_t len) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
264 { |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
265 size_t hlen; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
266 u_char *p1, *p2; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
267 |
8807
0ac25efb2da3
HTTP/3: quic-qpack term updates.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8534
diff
changeset
|
268 /* Literal Field Line With Post-Base Name Reference */ |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
269 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
270 if (p == NULL) { |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
271 return ngx_http_v3_encode_prefix_int(NULL, index, 3) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
272 + ngx_http_v3_encode_prefix_int(NULL, len, 7) |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
273 + len; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
274 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
275 |
8534
985f9351dd87
HTTP/3: do not set the never-indexed literal bit by default.
Roman Arutyunyan <arut@nginx.com>
parents:
8491
diff
changeset
|
276 *p = 0; |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
277 p = (u_char *) ngx_http_v3_encode_prefix_int(p, index, 3); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
278 |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
279 p1 = p; |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
280 *p = 0; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
281 p = (u_char *) ngx_http_v3_encode_prefix_int(p, len, 7); |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
282 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
283 if (data) { |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
284 p2 = p; |
8942
5c86189a1c1b
Merged with the default branch.
Ruslan Ermilov <ru@nginx.com>
parents:
8848
diff
changeset
|
285 hlen = ngx_http_huff_encode(data, len, p, 0); |
8848
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
286 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
287 if (hlen) { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
288 p = p1; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
289 *p = 0x80; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
290 p = (u_char *) ngx_http_v3_encode_prefix_int(p, hlen, 7); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
291 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
292 if (p != p2) { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
293 ngx_memmove(p, p2, hlen); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
294 } |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
295 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
296 p += hlen; |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
297 |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
298 } else { |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
299 p = ngx_cpymem(p, data, len); |
b5a305db30e0
HTTP/3: implemented QPACK Huffman encoding for response fields.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8807
diff
changeset
|
300 } |
8488
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
301 } |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
302 |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
303 return (uintptr_t) p; |
79125ef2e39f
HTTP/3: header encoding functions.
Roman Arutyunyan <arut@nginx.com>
parents:
8455
diff
changeset
|
304 } |