Mercurial > hg > nginx-quic
comparison src/http/v3/ngx_http_v3.c @ 7681:38c0898b6df7 quic
HTTP/3.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Fri, 13 Mar 2020 19:36:33 +0300 |
parents | |
children | 268f4389130d |
comparison
equal
deleted
inserted
replaced
7680:6fd2cce50fe2 | 7681:38c0898b6df7 |
---|---|
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 3; | |
38 } | |
39 | |
40 *p++ = 0x80 | (value >> 16); | |
41 *p++ = (value >> 8); | |
42 *p++ = value; | |
43 return (uintptr_t) p; | |
44 | |
45 } | |
46 | |
47 if (p == NULL) { | |
48 return 4; | |
49 } | |
50 | |
51 *p++ = 0xc0 | (value >> 24); | |
52 *p++ = (value >> 16); | |
53 *p++ = (value >> 8); | |
54 *p++ = value; | |
55 return (uintptr_t) p; | |
56 } | |
57 | |
58 | |
59 uintptr_t | |
60 ngx_http_v3_encode_prefix_int(u_char *p, uint64_t value, ngx_uint_t prefix) | |
61 { | |
62 ngx_uint_t thresh, n; | |
63 | |
64 thresh = (1 << prefix) - 1; | |
65 | |
66 if (value < thresh) { | |
67 if (p == NULL) { | |
68 return 1; | |
69 } | |
70 | |
71 *p++ |= value; | |
72 return (uintptr_t) p; | |
73 } | |
74 | |
75 value -= thresh; | |
76 | |
77 for (n = 10; n > 1; n--) { | |
78 if (value >> (7 * (n - 1))) { | |
79 break; | |
80 } | |
81 } | |
82 | |
83 if (p == NULL) { | |
84 return n + 1; | |
85 } | |
86 | |
87 *p++ |= thresh; | |
88 | |
89 for ( /* void */ ; n > 1; n--) { | |
90 *p++ = 0x80 | (value >> 7 * (n - 1)); | |
91 } | |
92 | |
93 *p++ = value & 0x7f; | |
94 | |
95 return (uintptr_t) p; | |
96 } | |
97 | |
98 | |
99 uint64_t | |
100 ngx_http_v3_decode_varlen_int(u_char *p) | |
101 { | |
102 uint64_t value; | |
103 ngx_uint_t len; | |
104 | |
105 len = *p >> 6; | |
106 value = *p & 0x3f; | |
107 | |
108 while (len--) { | |
109 value = (value << 8) + *p++; | |
110 } | |
111 | |
112 return value; | |
113 } | |
114 | |
115 | |
116 int64_t | |
117 ngx_http_v3_decode_prefix_int(u_char **src, size_t len, ngx_uint_t prefix) | |
118 { | |
119 u_char *p; | |
120 int64_t value, thresh; | |
121 | |
122 if (len == 0) { | |
123 return NGX_ERROR; | |
124 } | |
125 | |
126 p = *src; | |
127 | |
128 thresh = (1 << prefix) - 1; | |
129 value = *p++ & thresh; | |
130 | |
131 if (value != thresh) { | |
132 *src = p; | |
133 return value; | |
134 } | |
135 | |
136 value = 0; | |
137 | |
138 /* XXX handle overflows */ | |
139 | |
140 while (--len) { | |
141 value = (value << 7) + (*p & 0x7f); | |
142 if ((*p++ & 0x80) == 0) { | |
143 *src = p; | |
144 return value + thresh; | |
145 } | |
146 } | |
147 | |
148 return NGX_ERROR; | |
149 } | |
150 | |
151 | |
152 ngx_int_t | |
153 ngx_http_v3_decode_huffman(ngx_connection_t *c, ngx_str_t *s) | |
154 { | |
155 u_char state, *p, *data; | |
156 | |
157 state = 0; | |
158 | |
159 p = ngx_pnalloc(c->pool, s->len * 8 / 5); | |
160 if (p == NULL) { | |
161 return NGX_ERROR; | |
162 } | |
163 | |
164 data = p; | |
165 | |
166 if (ngx_http_v2_huff_decode(&state, s->data, s->len, &p, 1, c->log) | |
167 != NGX_OK) | |
168 { | |
169 return NGX_ERROR; | |
170 } | |
171 | |
172 s->len = p - data; | |
173 s->data = data; | |
174 | |
175 return NGX_OK; | |
176 } |