comparison src/http/v3/ngx_http_v3_encode.c @ 8009:6e1798a4a0d2 quic

HTTP/3: renamed ngx_http_v3.c to ngx_http_v3_encode.c. The file contains only encoding functions.
author Roman Arutyunyan <arut@nginx.com>
date Mon, 13 Jul 2020 12:38:08 +0300
parents src/http/v3/ngx_http_v3.c@79125ef2e39f
children 985f9351dd87
comparison
equal deleted inserted replaced
8008:e24f7b50ba1d 8009:6e1798a4a0d2
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) {
37 return 4;
38 }
39
40 *p++ = 0x80 | (value >> 24);
41 *p++ = (value >> 16);
42 *p++ = (value >> 8);
43 *p++ = value;
44 return (uintptr_t) p;
45 }
46
47 if (p == NULL) {
48 return 8;
49 }
50
51 *p++ = 0xc0 | (value >> 56);
52 *p++ = (value >> 48);
53 *p++ = (value >> 40);
54 *p++ = (value >> 32);
55 *p++ = (value >> 24);
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
81 if (p == NULL) {
82 for (n = 2; value >= 128; n++) {
83 value >>= 7;
84 }
85
86 return n;
87 }
88
89 *p++ |= thresh;
90
91 while (value >= 128) {
92 *p++ = 0x80 | value;
93 value >>= 7;
94 }
95
96 *p++ = value;
97
98 return (uintptr_t) p;
99 }
100
101
102 uintptr_t
103 ngx_http_v3_encode_header_block_prefix(u_char *p, ngx_uint_t insert_count,
104 ngx_uint_t sign, ngx_uint_t delta_base)
105 {
106 if (p == NULL) {
107 return ngx_http_v3_encode_prefix_int(NULL, insert_count, 8)
108 + ngx_http_v3_encode_prefix_int(NULL, delta_base, 7);
109 }
110
111 *p = 0;
112 p = (u_char *) ngx_http_v3_encode_prefix_int(p, insert_count, 8);
113
114 *p = sign ? 0x80 : 0;
115 p = (u_char *) ngx_http_v3_encode_prefix_int(p, delta_base, 7);
116
117 return (uintptr_t) p;
118 }
119
120
121 uintptr_t
122 ngx_http_v3_encode_header_ri(u_char *p, ngx_uint_t dynamic, ngx_uint_t index)
123 {
124 /* Indexed Header Field */
125
126 if (p == NULL) {
127 return ngx_http_v3_encode_prefix_int(NULL, index, 6);
128 }
129
130 *p = dynamic ? 0x80 : 0xc0;
131
132 return ngx_http_v3_encode_prefix_int(p, index, 6);
133 }
134
135
136 uintptr_t
137 ngx_http_v3_encode_header_lri(u_char *p, ngx_uint_t dynamic, ngx_uint_t index,
138 u_char *data, size_t len)
139 {
140 /* Literal Header Field With Name Reference */
141
142 if (p == NULL) {
143 return ngx_http_v3_encode_prefix_int(NULL, index, 4)
144 + ngx_http_v3_encode_prefix_int(NULL, len, 7)
145 + len;
146 }
147
148 *p = dynamic ? 0x60 : 0x70;
149 p = (u_char *) ngx_http_v3_encode_prefix_int(p, index, 4);
150
151 *p = 0;
152 p = (u_char *) ngx_http_v3_encode_prefix_int(p, len, 7);
153
154 if (data) {
155 p = ngx_cpymem(p, data, len);
156 }
157
158 return (uintptr_t) p;
159 }
160
161
162 uintptr_t
163 ngx_http_v3_encode_header_l(u_char *p, ngx_str_t *name, ngx_str_t *value)
164 {
165 /* Literal Header Field Without Name Reference */
166
167 if (p == NULL) {
168 return ngx_http_v3_encode_prefix_int(NULL, name->len, 3)
169 + name->len
170 + ngx_http_v3_encode_prefix_int(NULL, value->len, 7)
171 + value->len;
172 }
173
174 *p = 0x30;
175 p = (u_char *) ngx_http_v3_encode_prefix_int(p, name->len, 3);
176
177 ngx_strlow(p, name->data, name->len);
178 p += name->len;
179
180 *p = 0;
181 p = (u_char *) ngx_http_v3_encode_prefix_int(p, value->len, 7);
182
183 p = ngx_cpymem(p, value->data, value->len);
184
185 return (uintptr_t) p;
186 }
187
188
189 uintptr_t
190 ngx_http_v3_encode_header_pbi(u_char *p, ngx_uint_t index)
191 {
192 /* Indexed Header Field With Post-Base Index */
193
194 if (p == NULL) {
195 return ngx_http_v3_encode_prefix_int(NULL, index, 4);
196 }
197
198 *p = 0x10;
199
200 return ngx_http_v3_encode_prefix_int(p, index, 4);
201 }
202
203
204 uintptr_t
205 ngx_http_v3_encode_header_lpbi(u_char *p, ngx_uint_t index, u_char *data,
206 size_t len)
207 {
208 /* Literal Header Field With Post-Base Name Reference */
209
210 if (p == NULL) {
211 return ngx_http_v3_encode_prefix_int(NULL, index, 3)
212 + ngx_http_v3_encode_prefix_int(NULL, len, 7)
213 + len;
214 }
215
216 *p = 0x08;
217 p = (u_char *) ngx_http_v3_encode_prefix_int(p, index, 3);
218
219 *p = 0;
220 p = (u_char *) ngx_http_v3_encode_prefix_int(p, len, 7);
221
222 if (data) {
223 p = ngx_cpymem(p, data, len);
224 }
225
226 return (uintptr_t) p;
227 }