comparison src/http/v3/ngx_http_v3.c @ 8215: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
8214:6fd2cce50fe2 8215: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 }