blob: 0d19815579a0646b70559f4ffa7bdb436180647d [file] [log] [blame]
Andy Greenecc2e722014-10-09 16:57:47 +08001/*
2 * Official static header table for HPACK
3 * +-------+-----------------------------+---------------+
4 | 1 | :authority | |
5 | 2 | :method | GET |
6 | 3 | :method | POST |
7 | 4 | :path | / |
8 | 5 | :path | /index.html |
9 | 6 | :scheme | http |
10 | 7 | :scheme | https |
11 | 8 | :status | 200 |
12 | 9 | :status | 204 |
13 | 10 | :status | 206 |
14 | 11 | :status | 304 |
15 | 12 | :status | 400 |
16 | 13 | :status | 404 |
17 | 14 | :status | 500 |
18 | 15 | accept-charset | |
19 | 16 | accept-encoding | gzip, deflate |
20 | 17 | accept-language | |
21 | 18 | accept-ranges | |
22 | 19 | accept | |
23 | 20 | access-control-allow-origin | |
24 | 21 | age | |
25 | 22 | allow | |
26 | 23 | authorization | |
27 | 24 | cache-control | |
28 | 25 | content-disposition | |
29 | 26 | content-encoding | |
30 | 27 | content-language | |
31 | 28 | content-length | |
32 | 29 | content-location | |
33 | 30 | content-range | |
34 | 31 | content-type | |
35 | 32 | cookie | |
36 | 33 | date | |
37 | 34 | etag | |
38 | 35 | expect | |
39 | 36 | expires | |
40 | 37 | from | |
41 | 38 | host | |
42 | 39 | if-match | |
43 | 40 | if-modified-since | |
44 | 41 | if-none-match | |
45 | 42 | if-range | |
46 | 43 | if-unmodified-since | |
47 | 44 | last-modified | |
48 | 45 | link | |
49 | 46 | location | |
50 | 47 | max-forwards | |
51 | 48 | proxy-authenticate | |
52 | 49 | proxy-authorization | |
53 | 50 | range | |
54 | 51 | referer | |
55 | 52 | refresh | |
56 | 53 | retry-after | |
57 | 54 | server | |
58 | 55 | set-cookie | |
59 | 56 | strict-transport-security | |
60 | 57 | transfer-encoding | |
61 | 58 | user-agent | |
62 | 59 | vary | |
63 | 60 | via | |
64 | 61 | www-authenticate | |
65 +-------+-----------------------------+---------------+
66*/
67
68static const unsigned char static_token[] = {
69 0,
70 WSI_TOKEN_HTTP_COLON_AUTHORITY,
71 WSI_TOKEN_HTTP_COLON_METHOD,
72 WSI_TOKEN_HTTP_COLON_METHOD,
73 WSI_TOKEN_HTTP_COLON_PATH,
74 WSI_TOKEN_HTTP_COLON_PATH,
75 WSI_TOKEN_HTTP_COLON_SCHEME,
76 WSI_TOKEN_HTTP_COLON_SCHEME,
77 WSI_TOKEN_HTTP_COLON_STATUS,
78 WSI_TOKEN_HTTP_COLON_STATUS,
79 WSI_TOKEN_HTTP_COLON_STATUS,
80 WSI_TOKEN_HTTP_COLON_STATUS,
81 WSI_TOKEN_HTTP_COLON_STATUS,
82 WSI_TOKEN_HTTP_COLON_STATUS,
83 WSI_TOKEN_HTTP_COLON_STATUS,
84 WSI_TOKEN_HTTP_ACCEPT_CHARSET,
85 WSI_TOKEN_HTTP_ACCEPT_ENCODING,
86 WSI_TOKEN_HTTP_ACCEPT_LANGUAGE,
87 WSI_TOKEN_HTTP_ACCEPT_RANGES,
88 WSI_TOKEN_HTTP_ACCEPT,
89 WSI_TOKEN_HTTP_ACCESS_CONTROL_ALLOW_ORIGIN,
90 WSI_TOKEN_HTTP_AGE,
91 WSI_TOKEN_HTTP_ALLOW,
92 WSI_TOKEN_HTTP_AUTHORIZATION,
93 WSI_TOKEN_HTTP_CACHE_CONTROL,
94 WSI_TOKEN_HTTP_CONTENT_DISPOSITION,
95 WSI_TOKEN_HTTP_CONTENT_ENCODING,
96 WSI_TOKEN_HTTP_CONTENT_LANGUAGE,
97 WSI_TOKEN_HTTP_CONTENT_LENGTH,
98 WSI_TOKEN_HTTP_CONTENT_LOCATION,
99 WSI_TOKEN_HTTP_CONTENT_RANGE,
100 WSI_TOKEN_HTTP_CONTENT_TYPE,
101 WSI_TOKEN_HTTP_COOKIE,
102 WSI_TOKEN_HTTP_DATE,
103 WSI_TOKEN_HTTP_ETAG,
104 WSI_TOKEN_HTTP_EXPECT,
105 WSI_TOKEN_HTTP_EXPIRES,
106 WSI_TOKEN_HTTP_FROM,
107 WSI_TOKEN_HTTP_HOST,
108 WSI_TOKEN_HTTP_IF_MATCH,
109 WSI_TOKEN_HTTP_IF_MODIFIED_SINCE,
110 WSI_TOKEN_HTTP_IF_NONE_MATCH,
111 WSI_TOKEN_HTTP_IF_RANGE,
112 WSI_TOKEN_HTTP_IF_UNMODIFIED_SINCE,
113 WSI_TOKEN_HTTP_LAST_MODIFIED,
114 WSI_TOKEN_HTTP_LINK,
115 WSI_TOKEN_HTTP_LOCATION,
116 WSI_TOKEN_HTTP_MAX_FORWARDS,
117 WSI_TOKEN_HTTP_PROXY_AUTHENTICATE,
118 WSI_TOKEN_HTTP_PROXY_AUTHORIZATION,
119 WSI_TOKEN_HTTP_RANGE,
120 WSI_TOKEN_HTTP_REFERER,
121 WSI_TOKEN_HTTP_REFRESH,
122 WSI_TOKEN_HTTP_RETRY_AFTER,
123 WSI_TOKEN_HTTP_SERVER,
124 WSI_TOKEN_HTTP_SET_COOKIE,
125 WSI_TOKEN_HTTP_STRICT_TRANSPORT_SECURITY,
126 WSI_TOKEN_HTTP_TRANSFER_ENCODING,
127 WSI_TOKEN_HTTP_USER_AGENT,
128 WSI_TOKEN_HTTP_VARY,
129 WSI_TOKEN_HTTP_VIA,
130 WSI_TOKEN_HTTP_WWW_AUTHENTICATE,
131};
132
133static const char * const http2_canned[] = {
134 "",
135 "",
136 "GET",
137 "POST",
138 "/",
139 "/index.html",
140 "http",
141 "https",
142 "200",
143 "204",
144 "206",
145 "300",
146 "304",
147 "400",
148 "404",
149 "500",
150 "",
151 "gzip, deflate"
152};
153
154#include "huftable.h"
155
156int lextable_decode(int pos, char c)
157{
158 int q = pos + !!c;
159
160 if (lextable_terms[q >> 3] & (1 << (q & 7))) /* terminal */
161 return lextable[q] | 0x8000;
162
163 return pos + (lextable[q] << 1);
164}
165
166static int lws_add_header(int header, const char *payload, int len)
167{
168 wsi->u.ah.frag_index[header]
169}
170
171int lws_hpack_interpret(struct libwebsocket *wsi, unsigned char c)
172{
173 switch (wsi->u.http2.hpack) {
174 case HPKS_TYPE:
175 if (c & 0x80) { /* indexed header field only */
176 wsi->u.http2.header_index = c & 0x7f;
177 /* stay at same state */
178 break;
179 }
180 if (c & 0x40) { /* literal header incr idx */
181 if (c == 0x40) { /* literal name */
182 wsi->u.http2.header_index = 0;
183 wsi->u.http2.hpack
184 wsi->u.http2.hpack = HPKS_HLEN;
185 break;
186 }
187 /* indexed name */
188 wsi->u.http2.header_index = c & 0x3f;
189 wsi->u.http2.hpack = HPKS_HLEN;
190 break;
191 }
192 switch(c & 0xf0) {
193 case 0: /* literal header without indexing */
194 if (c == 0) { /* literal name */
195 wsi->u.http2.hpack = HPKS_NAME_HLEN;
196 break;
197 }
198 /* indexed name */
199 wsi->u.http2.header_index = c & 0xf;
200 wsi->u.http2.hpack = HPKS_VALUE_HLEN;
201 break;
202 case 0x10: /* literal header never indexed */
203 if (c == 0x10) { /* literal name */
204 wsi->u.http2.header_index = 0;
205 wsi->u.http2.hpack = HPKS_NAME_HLEN;
206 break;
207 }
208 /* indexed name */
209 wsi->u.http2.header_index = c & 0xf;
210 wsi->u.http2.hpack = HPKS_NAME_HLEN;
211 break;
212 case 0x20:
213 case 0x30: /* header table size update */
214 /* = c & 0x1f */
215 /* stay at same state */
216 break;
217 }
218 break;
219 case HPKS_HLEN:
220 wsi->u.http2.huff = !!(c & 0x80);
221 wsi->u.http2.hpack_len = c & 0x7f;
222 if (wsi->u.http2.hpack_len < 127) {
223 wsi->u.http2.hpack = HPKS_NAME_DATA;
224 break;
225 }
226 wsi->u.http2.hpack_m = 0;
227 wsi->u.http2.hpack = HPKS_NAME_HLEN_EXT;
228 break;
229 case HPKS_HLEN_EXT:
230 wsi->u.http2.hpack_len += (c & 0x7f) << wsi->u.http2.hpack_m;
231 wsi->u.http2.hpack_m += 7;
232 if (!(c & 0x80))
233 wsi->u.http2.hpack = HPKS_NAME_DATA;
234 break;
235
236 case HPKS_DATA:
237
238 }
239}