http2 able to send test.html to nghttp2
Signed-off-by: Andy Green <andy.green@linaro.org>
diff --git a/changelog b/changelog
index f50d87b..6881a5b 100644
--- a/changelog
+++ b/changelog
@@ -27,6 +27,55 @@
writeable callback is called again. If you only do one write per writeable callback,
you can ignore this.
+HTTP2-related: HTTP2 changes how headers are handled, lws now has new version-
+agnositic header creation APIs. These do the right thing depending on each
+connection's HTTP version without the user code having to know or care, except
+to make sure to use the new APIs for headers (test-server is updated to use
+them already, so look there for examples)
+
+The APIs "render" the headers into a user-provided buffer and bump *p as it
+is used. If *p reaches end, then the APIs return nonzero for error.
+
+LWS_VISIBLE LWS_EXTERN int
+lws_add_http_header_status(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ unsigned int code,
+ unsigned char **p,
+ unsigned char *end);
+
+Start a response header reporting status like 200, 500, etc
+
+LWS_VISIBLE LWS_EXTERN int
+lws_add_http_header_by_name(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ const unsigned char *name,
+ const unsigned char *value,
+ int length,
+ unsigned char **p,
+ unsigned char *end);
+
+Add a header like name: value in HTTP1.x
+
+LWS_VISIBLE LWS_EXTERN int
+lws_finalize_http_header(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ unsigned char **p,
+ unsigned char *end);
+
+Finish off the headers, like add the extra \r\n in HTTP1.x
+
+LWS_VISIBLE LWS_EXTERN int
+lws_add_http_header_by_token(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ enum lws_token_indexes token,
+ const unsigned char *value,
+ int length,
+ unsigned char **p,
+ unsigned char *end);
+
+Add a header by using a lws token as the name part. In HTTP2, this can be
+compressed to one or two bytes.
+
User api removal
----------------
@@ -37,6 +86,18 @@
it off is deprecated.
+User api changes
+----------------
+
+HTTP2-related: API libwebsockets_serve_http_file() takes an extra parameter at
+the end now
+
+int other_headers_len)
+
+If you are providing other headers, they must be generated using the new
+HTTP-version-agnostic APIs, and you must provide the length of them using this
+additional parameter.
+
v1.3-chrome37-firefox30
=======================
diff --git a/lib/hpack.c b/lib/hpack.c
index 1bda810..bd4f462 100644
--- a/lib/hpack.c
+++ b/lib/hpack.c
@@ -468,3 +468,98 @@
return 0;
}
+
+static int lws_http2_num(int starting_bits, unsigned long num, unsigned char **p, unsigned char *end)
+{
+ int mask = (1 << starting_bits) - 1;
+
+ if (num < mask) {
+ *((*p)++) |= num;
+ return *p >= end;
+ }
+
+ *((*p)++) |= mask;
+ if (*p >= end)
+ return 1;
+
+ num -= mask;
+ while (num >= 128) {
+ *((*p)++) = 0x80 | (num & 0x7f);
+ if (*p >= end)
+ return 1;
+ num >>= 7;
+ }
+
+ return 0;
+}
+
+int lws_add_http2_header_by_name(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ const unsigned char *name,
+ const unsigned char *value,
+ int length,
+ unsigned char **p,
+ unsigned char *end)
+{
+ int len;
+
+ lwsl_info("%s: %p %s:%s\n", __func__, *p, name, value);
+
+ len = strlen((char *)name);
+ if (len)
+ if (name[len - 1] == ':')
+ len--;
+
+ if (end - *p < len + length + 8)
+ return 1;
+
+ *((*p)++) = 0; /* not indexed, literal name */
+
+ **p = 0; /* non-HUF */
+ if (lws_http2_num(7, len, p, end))
+ return 1;
+ memcpy(*p, name, len);
+ *p += len;
+
+ *(*p) = 0; /* non-HUF */
+ if (lws_http2_num(7, length, p, end))
+ return 1;
+
+ memcpy(*p, value, length);
+ *p += length;
+
+ return 0;
+}
+
+int lws_add_http2_header_by_token(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ enum lws_token_indexes token,
+ const unsigned char *value,
+ int length,
+ unsigned char **p,
+ unsigned char *end)
+{
+ const unsigned char *name;
+
+ name = lws_token_to_string(token);
+ if (!name)
+ return 1;
+
+ return lws_add_http2_header_by_name(context, wsi, name, value, length, p, end);
+}
+
+int lws_add_http2_header_status(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ unsigned int code,
+ unsigned char **p,
+ unsigned char *end)
+{
+ unsigned char status[10];
+ int n;
+
+ n = sprintf((char *)status, "%u", code);
+ if (lws_add_http2_header_by_token(context, wsi, WSI_TOKEN_HTTP_COLON_STATUS, status, n, p, end))
+ return 1;
+
+ return 0;
+}
\ No newline at end of file
diff --git a/lib/lextable-strings.h b/lib/lextable-strings.h
new file mode 100644
index 0000000..1e82d8c
--- /dev/null
+++ b/lib/lextable-strings.h
@@ -0,0 +1,85 @@
+/* set of parsable strings -- ALL LOWER CASE */
+
+static const char *set[] = {
+ "get ",
+ "post ",
+ "options ",
+ "host:",
+ "connection:",
+ "upgrade:",
+ "origin:",
+ "sec-websocket-draft:",
+ "\x0d\x0a",
+
+ "sec-websocket-extensions:",
+ "sec-websocket-key1:",
+ "sec-websocket-key2:",
+ "sec-websocket-protocol:",
+
+ "sec-websocket-accept:",
+ "sec-websocket-nonce:",
+ "http/1.1 ",
+ "http2-settings:",
+
+ "accept:",
+ "access-control-request-headers:",
+ "if-modified-since:",
+ "if-none-match:",
+ "accept-encoding:",
+ "accept-language:",
+ "pragma:",
+ "cache-control:",
+ "authorization:",
+ "cookie:",
+ "content-length:",
+ "content-type:",
+ "date:",
+ "range:",
+ "referer:",
+ "sec-websocket-key:",
+ "sec-websocket-version:",
+ "sec-websocket-origin:",
+
+ ":authority:",
+ ":method:",
+ ":path:",
+ ":scheme:",
+ ":status:",
+
+ "accept-charset:",
+ "accept-ranges:",
+ "access-control-allow-origin:",
+ "age:",
+ "allow:",
+ "content-disposition:",
+ "content-encoding:",
+ "content-language:",
+ "content-location:",
+ "content-range:",
+ "etag:",
+ "expect:",
+ "expires:",
+ "from:",
+ "if-match:",
+ "if-range:",
+ "if-unmodified-since:",
+ "last-modified:",
+ "link:",
+ "location:",
+ "max-forwards:",
+ "proxy-authenticate:",
+ "proxy-authorization:",
+ "refresh:",
+ "retry-after:",
+ "server:",
+ "set-cookie:",
+ "strict-transport-security:",
+ "transfer-encoding:",
+ "user-agent:",
+ "vary:",
+ "via:",
+ "www-authenticate:",
+
+ "", /* not matchable */
+
+};
diff --git a/lib/lextable.h b/lib/lextable.h
index 3714e4c..633a5b5 100644
--- a/lib/lextable.h
+++ b/lib/lextable.h
@@ -8,16 +8,16 @@
0x0D /* '.' */, 0xC4, 0x00 /* (to 0x00D9 state 68) */,
0x61 /* 'a' */, 0x16, 0x01 /* (to 0x012E state 129) */,
0x69 /* 'i' */, 0x55, 0x01 /* (to 0x0170 state 163) */,
- 0x64 /* 'd' */, 0xFB, 0x01 /* (to 0x0219 state 265) */,
- 0x72 /* 'r' */, 0xFE, 0x01 /* (to 0x021F state 270) */,
- 0x3A /* ':' */, 0x2F, 0x02 /* (to 0x0253 state 299) */,
- 0x65 /* 'e' */, 0xB6, 0x02 /* (to 0x02DD state 405) */,
- 0x66 /* 'f' */, 0xD2, 0x02 /* (to 0x02FC state 421) */,
- 0x6C /* 'l' */, 0xF4, 0x02 /* (to 0x0321 state 454) */,
- 0x6D /* 'm' */, 0x17, 0x03 /* (to 0x0347 state 480) */,
- 0x74 /* 't' */, 0x80, 0x03 /* (to 0x03B3 state 574) */,
- 0x76 /* 'v' */, 0x9B, 0x03 /* (to 0x03D1 state 602) */,
- 0x77 /* 'w' */, 0xA8, 0x03 /* (to 0x03E1 state 610) */,
+ 0x64 /* 'd' */, 0xFE, 0x01 /* (to 0x021C state 265) */,
+ 0x72 /* 'r' */, 0x01, 0x02 /* (to 0x0222 state 270) */,
+ 0x3A /* ':' */, 0x32, 0x02 /* (to 0x0256 state 299) */,
+ 0x65 /* 'e' */, 0xC3, 0x02 /* (to 0x02EA state 414) */,
+ 0x66 /* 'f' */, 0xDF, 0x02 /* (to 0x0309 state 430) */,
+ 0x6C /* 'l' */, 0x01, 0x03 /* (to 0x032E state 463) */,
+ 0x6D /* 'm' */, 0x24, 0x03 /* (to 0x0354 state 489) */,
+ 0x74 /* 't' */, 0x8D, 0x03 /* (to 0x03C0 state 583) */,
+ 0x76 /* 'v' */, 0xA8, 0x03 /* (to 0x03DE state 611) */,
+ 0x77 /* 'w' */, 0xB5, 0x03 /* (to 0x03EE state 619) */,
0x08, /* fail */
/* pos 003d: 1 */ 0xE5 /* 'e' -> */,
/* pos 003e: 2 */ 0xF4 /* 't' -> */,
@@ -65,7 +65,7 @@
/* pos 0084: 32 */ 0xBA /* ':' -> */,
/* pos 0085: 33 */ 0x00, 0x04 /* - terminal marker 4 - */,
/* pos 0087: 34 */ 0x70 /* 'p' */, 0x07, 0x00 /* (to 0x008E state 35) */,
- 0x73 /* 's' */, 0x3C, 0x03 /* (to 0x03C6 state 592) */,
+ 0x73 /* 's' */, 0x49, 0x03 /* (to 0x03D3 state 601) */,
0x08, /* fail */
/* pos 008e: 35 */ 0xE7 /* 'g' -> */,
/* pos 008f: 36 */ 0xF2 /* 'r' -> */,
@@ -81,11 +81,11 @@
/* pos 009a: 46 */ 0xBA /* ':' -> */,
/* pos 009b: 47 */ 0x00, 0x06 /* - terminal marker 6 - */,
/* pos 009d: 48 */ 0x65 /* 'e' */, 0x07, 0x00 /* (to 0x00A4 state 49) */,
- 0x74 /* 't' */, 0xF9, 0x02 /* (to 0x0399 state 549) */,
+ 0x74 /* 't' */, 0x06, 0x03 /* (to 0x03A6 state 558) */,
0x08, /* fail */
/* pos 00a4: 49 */ 0x63 /* 'c' */, 0x0A, 0x00 /* (to 0x00AE state 50) */,
- 0x72 /* 'r' */, 0xE2, 0x02 /* (to 0x0389 state 535) */,
- 0x74 /* 't' */, 0xE5, 0x02 /* (to 0x038F state 540) */,
+ 0x72 /* 'r' */, 0xEF, 0x02 /* (to 0x0396 state 544) */,
+ 0x74 /* 't' */, 0xF2, 0x02 /* (to 0x039C state 549) */,
0x08, /* fail */
/* pos 00ae: 50 */ 0xAD /* '-' -> */,
/* pos 00af: 51 */ 0xF7 /* 'w' -> */,
@@ -104,8 +104,8 @@
0x70 /* 'p' */, 0x38, 0x00 /* (to 0x00FA state 88) */,
0x61 /* 'a' */, 0x3F, 0x00 /* (to 0x0104 state 97) */,
0x6E /* 'n' */, 0x44, 0x00 /* (to 0x010C state 104) */,
- 0x76 /* 'v' */, 0x77, 0x01 /* (to 0x0242 state 284) */,
- 0x6F /* 'o' */, 0x7D, 0x01 /* (to 0x024B state 292) */,
+ 0x76 /* 'v' */, 0x7A, 0x01 /* (to 0x0245 state 284) */,
+ 0x6F /* 'o' */, 0x80, 0x01 /* (to 0x024E state 292) */,
0x08, /* fail */
/* pos 00d2: 62 */ 0xF2 /* 'r' -> */,
/* pos 00d3: 63 */ 0xE1 /* 'a' -> */,
@@ -130,7 +130,7 @@
/* pos 00e9: 82 */ 0xF9 /* 'y' -> */,
/* pos 00ea: 83 */ 0x31 /* '1' */, 0x0A, 0x00 /* (to 0x00F4 state 84) */,
0x32 /* '2' */, 0x0A, 0x00 /* (to 0x00F7 state 86) */,
- 0x3A /* ':' */, 0x50, 0x01 /* (to 0x0240 state 283) */,
+ 0x3A /* ':' */, 0x53, 0x01 /* (to 0x0243 state 283) */,
0x08, /* fail */
/* pos 00f4: 84 */ 0xBA /* ':' -> */,
/* pos 00f5: 85 */ 0x00, 0x0A /* - terminal marker 10 - */,
@@ -181,8 +181,8 @@
/* pos 012c: 128 */ 0x00, 0x10 /* - terminal marker 16 - */,
/* pos 012e: 129 */ 0x63 /* 'c' */, 0x0D, 0x00 /* (to 0x013B state 130) */,
0x75 /* 'u' */, 0xAC, 0x00 /* (to 0x01DD state 230) */,
- 0x67 /* 'g' */, 0x79, 0x01 /* (to 0x02AD state 363) */,
- 0x6C /* 'l' */, 0x7A, 0x01 /* (to 0x02B1 state 366) */,
+ 0x67 /* 'g' */, 0x7C, 0x01 /* (to 0x02B0 state 363) */,
+ 0x6C /* 'l' */, 0x7D, 0x01 /* (to 0x02B4 state 366) */,
0x08, /* fail */
/* pos 013b: 130 */ 0xE3 /* 'c' -> */,
/* pos 013c: 131 */ 0xE5 /* 'e' -> */,
@@ -205,7 +205,7 @@
/* pos 0156: 144 */ 0xEC /* 'l' -> */,
/* pos 0157: 145 */ 0xAD /* '-' -> */,
/* pos 0158: 146 */ 0x72 /* 'r' */, 0x07, 0x00 /* (to 0x015F state 147) */,
- 0x61 /* 'a' */, 0x44, 0x01 /* (to 0x029F state 350) */,
+ 0x61 /* 'a' */, 0x47, 0x01 /* (to 0x02A2 state 350) */,
0x08, /* fail */
/* pos 015f: 147 */ 0xE5 /* 'e' -> */,
/* pos 0160: 148 */ 0xF1 /* 'q' -> */,
@@ -227,11 +227,11 @@
/* pos 0171: 164 */ 0xAD /* '-' -> */,
/* pos 0172: 165 */ 0x6D /* 'm' */, 0x0D, 0x00 /* (to 0x017F state 166) */,
0x6E /* 'n' */, 0x20, 0x00 /* (to 0x0195 state 181) */,
- 0x72 /* 'r' */, 0x90, 0x01 /* (to 0x0308 state 431) */,
- 0x75 /* 'u' */, 0x94, 0x01 /* (to 0x030F state 437) */,
+ 0x72 /* 'r' */, 0x9D, 0x01 /* (to 0x0315 state 440) */,
+ 0x75 /* 'u' */, 0xA1, 0x01 /* (to 0x031C state 446) */,
0x08, /* fail */
/* pos 017f: 166 */ 0x6F /* 'o' */, 0x07, 0x00 /* (to 0x0186 state 167) */,
- 0x61 /* 'a' */, 0x80, 0x01 /* (to 0x0302 state 426) */,
+ 0x61 /* 'a' */, 0x8D, 0x01 /* (to 0x030F state 435) */,
0x08, /* fail */
/* pos 0186: 167 */ 0xE4 /* 'd' -> */,
/* pos 0187: 168 */ 0xE9 /* 'i' -> */,
@@ -260,8 +260,8 @@
/* pos 019f: 191 */ 0x00, 0x14 /* - terminal marker 20 - */,
/* pos 01a1: 192 */ 0x65 /* 'e' */, 0x0D, 0x00 /* (to 0x01AE state 193) */,
0x6C /* 'l' */, 0x14, 0x00 /* (to 0x01B8 state 202) */,
- 0x63 /* 'c' */, 0xE7, 0x00 /* (to 0x028E state 335) */,
- 0x72 /* 'r' */, 0xED, 0x00 /* (to 0x0297 state 343) */,
+ 0x63 /* 'c' */, 0xEA, 0x00 /* (to 0x0291 state 335) */,
+ 0x72 /* 'r' */, 0xF0, 0x00 /* (to 0x029A state 343) */,
0x08, /* fail */
/* pos 01ae: 193 */ 0xEE /* 'n' -> */,
/* pos 01af: 194 */ 0xE3 /* 'c' -> */,
@@ -282,7 +282,7 @@
/* pos 01bf: 209 */ 0xBA /* ':' -> */,
/* pos 01c0: 210 */ 0x00, 0x16 /* - terminal marker 22 - */,
/* pos 01c2: 211 */ 0x61 /* 'a' */, 0x07, 0x00 /* (to 0x01C9 state 212) */,
- 0x6F /* 'o' */, 0x90, 0x01 /* (to 0x0355 state 493) */,
+ 0x6F /* 'o' */, 0x9D, 0x01 /* (to 0x0362 state 502) */,
0x08, /* fail */
/* pos 01c9: 212 */ 0xE7 /* 'g' -> */,
/* pos 01ca: 213 */ 0xED /* 'm' -> */,
@@ -324,409 +324,419 @@
/* pos 01f2: 249 */ 0xEE /* 'n' -> */,
/* pos 01f3: 250 */ 0xF4 /* 't' -> */,
/* pos 01f4: 251 */ 0xAD /* '-' -> */,
-/* pos 01f5: 252 */ 0x6C /* 'l' */, 0x0D, 0x00 /* (to 0x0202 state 253) */,
- 0x74 /* 't' */, 0x1B, 0x00 /* (to 0x0213 state 260) */,
- 0x64 /* 'd' */, 0xBC, 0x00 /* (to 0x02B7 state 371) */,
- 0x72 /* 'r' */, 0xD8, 0x00 /* (to 0x02D6 state 399) */,
+/* pos 01f5: 252 */ 0x6C /* 'l' */, 0x10, 0x00 /* (to 0x0205 state 253) */,
+ 0x74 /* 't' */, 0x1E, 0x00 /* (to 0x0216 state 260) */,
+ 0x64 /* 'd' */, 0xBF, 0x00 /* (to 0x02BA state 371) */,
+ 0x65 /* 'e' */, 0xC9, 0x00 /* (to 0x02C7 state 383) */,
+ 0x72 /* 'r' */, 0xE2, 0x00 /* (to 0x02E3 state 408) */,
0x08, /* fail */
-/* pos 0202: 253 */ 0x65 /* 'e' */, 0x0A, 0x00 /* (to 0x020C state 254) */,
- 0x61 /* 'a' */, 0xBF, 0x00 /* (to 0x02C4 state 383) */,
- 0x6F /* 'o' */, 0xC5, 0x00 /* (to 0x02CD state 391) */,
+/* pos 0205: 253 */ 0x65 /* 'e' */, 0x0A, 0x00 /* (to 0x020F state 254) */,
+ 0x61 /* 'a' */, 0xC9, 0x00 /* (to 0x02D1 state 392) */,
+ 0x6F /* 'o' */, 0xCF, 0x00 /* (to 0x02DA state 400) */,
0x08, /* fail */
-/* pos 020c: 254 */ 0xEE /* 'n' -> */,
-/* pos 020d: 255 */ 0xE7 /* 'g' -> */,
-/* pos 020e: 256 */ 0xF4 /* 't' -> */,
-/* pos 020f: 257 */ 0xE8 /* 'h' -> */,
-/* pos 0210: 258 */ 0xBA /* ':' -> */,
-/* pos 0211: 259 */ 0x00, 0x1B /* - terminal marker 27 - */,
-/* pos 0213: 260 */ 0xF9 /* 'y' -> */,
-/* pos 0214: 261 */ 0xF0 /* 'p' -> */,
-/* pos 0215: 262 */ 0xE5 /* 'e' -> */,
-/* pos 0216: 263 */ 0xBA /* ':' -> */,
-/* pos 0217: 264 */ 0x00, 0x1C /* - terminal marker 28 - */,
-/* pos 0219: 265 */ 0xE1 /* 'a' -> */,
-/* pos 021a: 266 */ 0xF4 /* 't' -> */,
-/* pos 021b: 267 */ 0xE5 /* 'e' -> */,
-/* pos 021c: 268 */ 0xBA /* ':' -> */,
-/* pos 021d: 269 */ 0x00, 0x1D /* - terminal marker 29 - */,
-/* pos 021f: 270 */ 0x61 /* 'a' */, 0x07, 0x00 /* (to 0x0226 state 271) */,
- 0x65 /* 'e' */, 0x0A, 0x00 /* (to 0x022C state 276) */,
+/* pos 020f: 254 */ 0xEE /* 'n' -> */,
+/* pos 0210: 255 */ 0xE7 /* 'g' -> */,
+/* pos 0211: 256 */ 0xF4 /* 't' -> */,
+/* pos 0212: 257 */ 0xE8 /* 'h' -> */,
+/* pos 0213: 258 */ 0xBA /* ':' -> */,
+/* pos 0214: 259 */ 0x00, 0x1B /* - terminal marker 27 - */,
+/* pos 0216: 260 */ 0xF9 /* 'y' -> */,
+/* pos 0217: 261 */ 0xF0 /* 'p' -> */,
+/* pos 0218: 262 */ 0xE5 /* 'e' -> */,
+/* pos 0219: 263 */ 0xBA /* ':' -> */,
+/* pos 021a: 264 */ 0x00, 0x1C /* - terminal marker 28 - */,
+/* pos 021c: 265 */ 0xE1 /* 'a' -> */,
+/* pos 021d: 266 */ 0xF4 /* 't' -> */,
+/* pos 021e: 267 */ 0xE5 /* 'e' -> */,
+/* pos 021f: 268 */ 0xBA /* ':' -> */,
+/* pos 0220: 269 */ 0x00, 0x1D /* - terminal marker 29 - */,
+/* pos 0222: 270 */ 0x61 /* 'a' */, 0x07, 0x00 /* (to 0x0229 state 271) */,
+ 0x65 /* 'e' */, 0x0A, 0x00 /* (to 0x022F state 276) */,
0x08, /* fail */
-/* pos 0226: 271 */ 0xEE /* 'n' -> */,
-/* pos 0227: 272 */ 0xE7 /* 'g' -> */,
-/* pos 0228: 273 */ 0xE5 /* 'e' -> */,
-/* pos 0229: 274 */ 0xBA /* ':' -> */,
-/* pos 022a: 275 */ 0x00, 0x1E /* - terminal marker 30 - */,
-/* pos 022c: 276 */ 0x66 /* 'f' */, 0x07, 0x00 /* (to 0x0233 state 277) */,
- 0x74 /* 't' */, 0x4F, 0x01 /* (to 0x037E state 525) */,
+/* pos 0229: 271 */ 0xEE /* 'n' -> */,
+/* pos 022a: 272 */ 0xE7 /* 'g' -> */,
+/* pos 022b: 273 */ 0xE5 /* 'e' -> */,
+/* pos 022c: 274 */ 0xBA /* ':' -> */,
+/* pos 022d: 275 */ 0x00, 0x1E /* - terminal marker 30 - */,
+/* pos 022f: 276 */ 0x66 /* 'f' */, 0x07, 0x00 /* (to 0x0236 state 277) */,
+ 0x74 /* 't' */, 0x59, 0x01 /* (to 0x038B state 534) */,
0x08, /* fail */
-/* pos 0233: 277 */ 0x65 /* 'e' */, 0x07, 0x00 /* (to 0x023A state 278) */,
- 0x72 /* 'r' */, 0x42, 0x01 /* (to 0x0378 state 520) */,
+/* pos 0236: 277 */ 0x65 /* 'e' */, 0x07, 0x00 /* (to 0x023D state 278) */,
+ 0x72 /* 'r' */, 0x4C, 0x01 /* (to 0x0385 state 529) */,
0x08, /* fail */
-/* pos 023a: 278 */ 0xF2 /* 'r' -> */,
-/* pos 023b: 279 */ 0xE5 /* 'e' -> */,
-/* pos 023c: 280 */ 0xF2 /* 'r' -> */,
-/* pos 023d: 281 */ 0xBA /* ':' -> */,
-/* pos 023e: 282 */ 0x00, 0x1F /* - terminal marker 31 - */,
-/* pos 0240: 283 */ 0x00, 0x20 /* - terminal marker 32 - */,
-/* pos 0242: 284 */ 0xE5 /* 'e' -> */,
-/* pos 0243: 285 */ 0xF2 /* 'r' -> */,
-/* pos 0244: 286 */ 0xF3 /* 's' -> */,
-/* pos 0245: 287 */ 0xE9 /* 'i' -> */,
-/* pos 0246: 288 */ 0xEF /* 'o' -> */,
-/* pos 0247: 289 */ 0xEE /* 'n' -> */,
-/* pos 0248: 290 */ 0xBA /* ':' -> */,
-/* pos 0249: 291 */ 0x00, 0x21 /* - terminal marker 33 - */,
-/* pos 024b: 292 */ 0xF2 /* 'r' -> */,
-/* pos 024c: 293 */ 0xE9 /* 'i' -> */,
-/* pos 024d: 294 */ 0xE7 /* 'g' -> */,
-/* pos 024e: 295 */ 0xE9 /* 'i' -> */,
-/* pos 024f: 296 */ 0xEE /* 'n' -> */,
-/* pos 0250: 297 */ 0xBA /* ':' -> */,
-/* pos 0251: 298 */ 0x00, 0x22 /* - terminal marker 34 - */,
-/* pos 0253: 299 */ 0x61 /* 'a' */, 0x0D, 0x00 /* (to 0x0260 state 300) */,
- 0x6D /* 'm' */, 0x15, 0x00 /* (to 0x026B state 310) */,
- 0x70 /* 'p' */, 0x1A, 0x00 /* (to 0x0273 state 317) */,
- 0x73 /* 's' */, 0x1D, 0x00 /* (to 0x0279 state 322) */,
+/* pos 023d: 278 */ 0xF2 /* 'r' -> */,
+/* pos 023e: 279 */ 0xE5 /* 'e' -> */,
+/* pos 023f: 280 */ 0xF2 /* 'r' -> */,
+/* pos 0240: 281 */ 0xBA /* ':' -> */,
+/* pos 0241: 282 */ 0x00, 0x1F /* - terminal marker 31 - */,
+/* pos 0243: 283 */ 0x00, 0x20 /* - terminal marker 32 - */,
+/* pos 0245: 284 */ 0xE5 /* 'e' -> */,
+/* pos 0246: 285 */ 0xF2 /* 'r' -> */,
+/* pos 0247: 286 */ 0xF3 /* 's' -> */,
+/* pos 0248: 287 */ 0xE9 /* 'i' -> */,
+/* pos 0249: 288 */ 0xEF /* 'o' -> */,
+/* pos 024a: 289 */ 0xEE /* 'n' -> */,
+/* pos 024b: 290 */ 0xBA /* ':' -> */,
+/* pos 024c: 291 */ 0x00, 0x21 /* - terminal marker 33 - */,
+/* pos 024e: 292 */ 0xF2 /* 'r' -> */,
+/* pos 024f: 293 */ 0xE9 /* 'i' -> */,
+/* pos 0250: 294 */ 0xE7 /* 'g' -> */,
+/* pos 0251: 295 */ 0xE9 /* 'i' -> */,
+/* pos 0252: 296 */ 0xEE /* 'n' -> */,
+/* pos 0253: 297 */ 0xBA /* ':' -> */,
+/* pos 0254: 298 */ 0x00, 0x22 /* - terminal marker 34 - */,
+/* pos 0256: 299 */ 0x61 /* 'a' */, 0x0D, 0x00 /* (to 0x0263 state 300) */,
+ 0x6D /* 'm' */, 0x15, 0x00 /* (to 0x026E state 310) */,
+ 0x70 /* 'p' */, 0x1A, 0x00 /* (to 0x0276 state 317) */,
+ 0x73 /* 's' */, 0x1D, 0x00 /* (to 0x027C state 322) */,
0x08, /* fail */
-/* pos 0260: 300 */ 0xF5 /* 'u' -> */,
-/* pos 0261: 301 */ 0xF4 /* 't' -> */,
-/* pos 0262: 302 */ 0xE8 /* 'h' -> */,
-/* pos 0263: 303 */ 0xEF /* 'o' -> */,
-/* pos 0264: 304 */ 0xF2 /* 'r' -> */,
-/* pos 0265: 305 */ 0xE9 /* 'i' -> */,
-/* pos 0266: 306 */ 0xF4 /* 't' -> */,
-/* pos 0267: 307 */ 0xF9 /* 'y' -> */,
-/* pos 0268: 308 */ 0xBA /* ':' -> */,
-/* pos 0269: 309 */ 0x00, 0x23 /* - terminal marker 35 - */,
-/* pos 026b: 310 */ 0xE5 /* 'e' -> */,
-/* pos 026c: 311 */ 0xF4 /* 't' -> */,
-/* pos 026d: 312 */ 0xE8 /* 'h' -> */,
-/* pos 026e: 313 */ 0xEF /* 'o' -> */,
-/* pos 026f: 314 */ 0xE4 /* 'd' -> */,
-/* pos 0270: 315 */ 0xBA /* ':' -> */,
-/* pos 0271: 316 */ 0x00, 0x24 /* - terminal marker 36 - */,
-/* pos 0273: 317 */ 0xE1 /* 'a' -> */,
-/* pos 0274: 318 */ 0xF4 /* 't' -> */,
-/* pos 0275: 319 */ 0xE8 /* 'h' -> */,
-/* pos 0276: 320 */ 0xBA /* ':' -> */,
-/* pos 0277: 321 */ 0x00, 0x25 /* - terminal marker 37 - */,
-/* pos 0279: 322 */ 0x63 /* 'c' */, 0x07, 0x00 /* (to 0x0280 state 323) */,
- 0x74 /* 't' */, 0x0B, 0x00 /* (to 0x0287 state 329) */,
+/* pos 0263: 300 */ 0xF5 /* 'u' -> */,
+/* pos 0264: 301 */ 0xF4 /* 't' -> */,
+/* pos 0265: 302 */ 0xE8 /* 'h' -> */,
+/* pos 0266: 303 */ 0xEF /* 'o' -> */,
+/* pos 0267: 304 */ 0xF2 /* 'r' -> */,
+/* pos 0268: 305 */ 0xE9 /* 'i' -> */,
+/* pos 0269: 306 */ 0xF4 /* 't' -> */,
+/* pos 026a: 307 */ 0xF9 /* 'y' -> */,
+/* pos 026b: 308 */ 0xBA /* ':' -> */,
+/* pos 026c: 309 */ 0x00, 0x23 /* - terminal marker 35 - */,
+/* pos 026e: 310 */ 0xE5 /* 'e' -> */,
+/* pos 026f: 311 */ 0xF4 /* 't' -> */,
+/* pos 0270: 312 */ 0xE8 /* 'h' -> */,
+/* pos 0271: 313 */ 0xEF /* 'o' -> */,
+/* pos 0272: 314 */ 0xE4 /* 'd' -> */,
+/* pos 0273: 315 */ 0xBA /* ':' -> */,
+/* pos 0274: 316 */ 0x00, 0x24 /* - terminal marker 36 - */,
+/* pos 0276: 317 */ 0xE1 /* 'a' -> */,
+/* pos 0277: 318 */ 0xF4 /* 't' -> */,
+/* pos 0278: 319 */ 0xE8 /* 'h' -> */,
+/* pos 0279: 320 */ 0xBA /* ':' -> */,
+/* pos 027a: 321 */ 0x00, 0x25 /* - terminal marker 37 - */,
+/* pos 027c: 322 */ 0x63 /* 'c' */, 0x07, 0x00 /* (to 0x0283 state 323) */,
+ 0x74 /* 't' */, 0x0B, 0x00 /* (to 0x028A state 329) */,
0x08, /* fail */
-/* pos 0280: 323 */ 0xE8 /* 'h' -> */,
-/* pos 0281: 324 */ 0xE5 /* 'e' -> */,
-/* pos 0282: 325 */ 0xED /* 'm' -> */,
-/* pos 0283: 326 */ 0xE5 /* 'e' -> */,
-/* pos 0284: 327 */ 0xBA /* ':' -> */,
-/* pos 0285: 328 */ 0x00, 0x26 /* - terminal marker 38 - */,
-/* pos 0287: 329 */ 0xE1 /* 'a' -> */,
-/* pos 0288: 330 */ 0xF4 /* 't' -> */,
-/* pos 0289: 331 */ 0xF5 /* 'u' -> */,
-/* pos 028a: 332 */ 0xF3 /* 's' -> */,
-/* pos 028b: 333 */ 0xBA /* ':' -> */,
-/* pos 028c: 334 */ 0x00, 0x27 /* - terminal marker 39 - */,
-/* pos 028e: 335 */ 0xE8 /* 'h' -> */,
-/* pos 028f: 336 */ 0xE1 /* 'a' -> */,
-/* pos 0290: 337 */ 0xF2 /* 'r' -> */,
-/* pos 0291: 338 */ 0xF3 /* 's' -> */,
-/* pos 0292: 339 */ 0xE5 /* 'e' -> */,
-/* pos 0293: 340 */ 0xF4 /* 't' -> */,
-/* pos 0294: 341 */ 0xBA /* ':' -> */,
-/* pos 0295: 342 */ 0x00, 0x28 /* - terminal marker 40 - */,
-/* pos 0297: 343 */ 0xE1 /* 'a' -> */,
-/* pos 0298: 344 */ 0xEE /* 'n' -> */,
-/* pos 0299: 345 */ 0xE7 /* 'g' -> */,
-/* pos 029a: 346 */ 0xE5 /* 'e' -> */,
-/* pos 029b: 347 */ 0xF3 /* 's' -> */,
-/* pos 029c: 348 */ 0xBA /* ':' -> */,
-/* pos 029d: 349 */ 0x00, 0x29 /* - terminal marker 41 - */,
-/* pos 029f: 350 */ 0xEC /* 'l' -> */,
-/* pos 02a0: 351 */ 0xEC /* 'l' -> */,
-/* pos 02a1: 352 */ 0xEF /* 'o' -> */,
-/* pos 02a2: 353 */ 0xF7 /* 'w' -> */,
-/* pos 02a3: 354 */ 0xAD /* '-' -> */,
-/* pos 02a4: 355 */ 0xEF /* 'o' -> */,
-/* pos 02a5: 356 */ 0xF2 /* 'r' -> */,
-/* pos 02a6: 357 */ 0xE9 /* 'i' -> */,
-/* pos 02a7: 358 */ 0xE7 /* 'g' -> */,
-/* pos 02a8: 359 */ 0xE9 /* 'i' -> */,
-/* pos 02a9: 360 */ 0xEE /* 'n' -> */,
-/* pos 02aa: 361 */ 0xBA /* ':' -> */,
-/* pos 02ab: 362 */ 0x00, 0x2A /* - terminal marker 42 - */,
-/* pos 02ad: 363 */ 0xE5 /* 'e' -> */,
-/* pos 02ae: 364 */ 0xBA /* ':' -> */,
-/* pos 02af: 365 */ 0x00, 0x2B /* - terminal marker 43 - */,
-/* pos 02b1: 366 */ 0xEC /* 'l' -> */,
-/* pos 02b2: 367 */ 0xEF /* 'o' -> */,
-/* pos 02b3: 368 */ 0xF7 /* 'w' -> */,
-/* pos 02b4: 369 */ 0xBA /* ':' -> */,
-/* pos 02b5: 370 */ 0x00, 0x2C /* - terminal marker 44 - */,
-/* pos 02b7: 371 */ 0xE9 /* 'i' -> */,
-/* pos 02b8: 372 */ 0xF3 /* 's' -> */,
-/* pos 02b9: 373 */ 0xF0 /* 'p' -> */,
-/* pos 02ba: 374 */ 0xEF /* 'o' -> */,
-/* pos 02bb: 375 */ 0xF3 /* 's' -> */,
-/* pos 02bc: 376 */ 0xE9 /* 'i' -> */,
-/* pos 02bd: 377 */ 0xF4 /* 't' -> */,
-/* pos 02be: 378 */ 0xE9 /* 'i' -> */,
-/* pos 02bf: 379 */ 0xEF /* 'o' -> */,
-/* pos 02c0: 380 */ 0xEE /* 'n' -> */,
-/* pos 02c1: 381 */ 0xBA /* ':' -> */,
-/* pos 02c2: 382 */ 0x00, 0x2D /* - terminal marker 45 - */,
-/* pos 02c4: 383 */ 0xEE /* 'n' -> */,
-/* pos 02c5: 384 */ 0xE7 /* 'g' -> */,
-/* pos 02c6: 385 */ 0xF5 /* 'u' -> */,
-/* pos 02c7: 386 */ 0xE1 /* 'a' -> */,
-/* pos 02c8: 387 */ 0xE7 /* 'g' -> */,
-/* pos 02c9: 388 */ 0xE5 /* 'e' -> */,
-/* pos 02ca: 389 */ 0xBA /* ':' -> */,
-/* pos 02cb: 390 */ 0x00, 0x2E /* - terminal marker 46 - */,
-/* pos 02cd: 391 */ 0xE3 /* 'c' -> */,
-/* pos 02ce: 392 */ 0xE1 /* 'a' -> */,
-/* pos 02cf: 393 */ 0xF4 /* 't' -> */,
-/* pos 02d0: 394 */ 0xE9 /* 'i' -> */,
-/* pos 02d1: 395 */ 0xEF /* 'o' -> */,
-/* pos 02d2: 396 */ 0xEE /* 'n' -> */,
-/* pos 02d3: 397 */ 0xBA /* ':' -> */,
-/* pos 02d4: 398 */ 0x00, 0x2F /* - terminal marker 47 - */,
-/* pos 02d6: 399 */ 0xE1 /* 'a' -> */,
-/* pos 02d7: 400 */ 0xEE /* 'n' -> */,
-/* pos 02d8: 401 */ 0xE7 /* 'g' -> */,
-/* pos 02d9: 402 */ 0xE5 /* 'e' -> */,
-/* pos 02da: 403 */ 0xBA /* ':' -> */,
-/* pos 02db: 404 */ 0x00, 0x30 /* - terminal marker 48 - */,
-/* pos 02dd: 405 */ 0x74 /* 't' */, 0x07, 0x00 /* (to 0x02E4 state 406) */,
- 0x78 /* 'x' */, 0x09, 0x00 /* (to 0x02E9 state 410) */,
+/* pos 0283: 323 */ 0xE8 /* 'h' -> */,
+/* pos 0284: 324 */ 0xE5 /* 'e' -> */,
+/* pos 0285: 325 */ 0xED /* 'm' -> */,
+/* pos 0286: 326 */ 0xE5 /* 'e' -> */,
+/* pos 0287: 327 */ 0xBA /* ':' -> */,
+/* pos 0288: 328 */ 0x00, 0x26 /* - terminal marker 38 - */,
+/* pos 028a: 329 */ 0xE1 /* 'a' -> */,
+/* pos 028b: 330 */ 0xF4 /* 't' -> */,
+/* pos 028c: 331 */ 0xF5 /* 'u' -> */,
+/* pos 028d: 332 */ 0xF3 /* 's' -> */,
+/* pos 028e: 333 */ 0xBA /* ':' -> */,
+/* pos 028f: 334 */ 0x00, 0x27 /* - terminal marker 39 - */,
+/* pos 0291: 335 */ 0xE8 /* 'h' -> */,
+/* pos 0292: 336 */ 0xE1 /* 'a' -> */,
+/* pos 0293: 337 */ 0xF2 /* 'r' -> */,
+/* pos 0294: 338 */ 0xF3 /* 's' -> */,
+/* pos 0295: 339 */ 0xE5 /* 'e' -> */,
+/* pos 0296: 340 */ 0xF4 /* 't' -> */,
+/* pos 0297: 341 */ 0xBA /* ':' -> */,
+/* pos 0298: 342 */ 0x00, 0x28 /* - terminal marker 40 - */,
+/* pos 029a: 343 */ 0xE1 /* 'a' -> */,
+/* pos 029b: 344 */ 0xEE /* 'n' -> */,
+/* pos 029c: 345 */ 0xE7 /* 'g' -> */,
+/* pos 029d: 346 */ 0xE5 /* 'e' -> */,
+/* pos 029e: 347 */ 0xF3 /* 's' -> */,
+/* pos 029f: 348 */ 0xBA /* ':' -> */,
+/* pos 02a0: 349 */ 0x00, 0x29 /* - terminal marker 41 - */,
+/* pos 02a2: 350 */ 0xEC /* 'l' -> */,
+/* pos 02a3: 351 */ 0xEC /* 'l' -> */,
+/* pos 02a4: 352 */ 0xEF /* 'o' -> */,
+/* pos 02a5: 353 */ 0xF7 /* 'w' -> */,
+/* pos 02a6: 354 */ 0xAD /* '-' -> */,
+/* pos 02a7: 355 */ 0xEF /* 'o' -> */,
+/* pos 02a8: 356 */ 0xF2 /* 'r' -> */,
+/* pos 02a9: 357 */ 0xE9 /* 'i' -> */,
+/* pos 02aa: 358 */ 0xE7 /* 'g' -> */,
+/* pos 02ab: 359 */ 0xE9 /* 'i' -> */,
+/* pos 02ac: 360 */ 0xEE /* 'n' -> */,
+/* pos 02ad: 361 */ 0xBA /* ':' -> */,
+/* pos 02ae: 362 */ 0x00, 0x2A /* - terminal marker 42 - */,
+/* pos 02b0: 363 */ 0xE5 /* 'e' -> */,
+/* pos 02b1: 364 */ 0xBA /* ':' -> */,
+/* pos 02b2: 365 */ 0x00, 0x2B /* - terminal marker 43 - */,
+/* pos 02b4: 366 */ 0xEC /* 'l' -> */,
+/* pos 02b5: 367 */ 0xEF /* 'o' -> */,
+/* pos 02b6: 368 */ 0xF7 /* 'w' -> */,
+/* pos 02b7: 369 */ 0xBA /* ':' -> */,
+/* pos 02b8: 370 */ 0x00, 0x2C /* - terminal marker 44 - */,
+/* pos 02ba: 371 */ 0xE9 /* 'i' -> */,
+/* pos 02bb: 372 */ 0xF3 /* 's' -> */,
+/* pos 02bc: 373 */ 0xF0 /* 'p' -> */,
+/* pos 02bd: 374 */ 0xEF /* 'o' -> */,
+/* pos 02be: 375 */ 0xF3 /* 's' -> */,
+/* pos 02bf: 376 */ 0xE9 /* 'i' -> */,
+/* pos 02c0: 377 */ 0xF4 /* 't' -> */,
+/* pos 02c1: 378 */ 0xE9 /* 'i' -> */,
+/* pos 02c2: 379 */ 0xEF /* 'o' -> */,
+/* pos 02c3: 380 */ 0xEE /* 'n' -> */,
+/* pos 02c4: 381 */ 0xBA /* ':' -> */,
+/* pos 02c5: 382 */ 0x00, 0x2D /* - terminal marker 45 - */,
+/* pos 02c7: 383 */ 0xEE /* 'n' -> */,
+/* pos 02c8: 384 */ 0xE3 /* 'c' -> */,
+/* pos 02c9: 385 */ 0xEF /* 'o' -> */,
+/* pos 02ca: 386 */ 0xE4 /* 'd' -> */,
+/* pos 02cb: 387 */ 0xE9 /* 'i' -> */,
+/* pos 02cc: 388 */ 0xEE /* 'n' -> */,
+/* pos 02cd: 389 */ 0xE7 /* 'g' -> */,
+/* pos 02ce: 390 */ 0xBA /* ':' -> */,
+/* pos 02cf: 391 */ 0x00, 0x2E /* - terminal marker 46 - */,
+/* pos 02d1: 392 */ 0xEE /* 'n' -> */,
+/* pos 02d2: 393 */ 0xE7 /* 'g' -> */,
+/* pos 02d3: 394 */ 0xF5 /* 'u' -> */,
+/* pos 02d4: 395 */ 0xE1 /* 'a' -> */,
+/* pos 02d5: 396 */ 0xE7 /* 'g' -> */,
+/* pos 02d6: 397 */ 0xE5 /* 'e' -> */,
+/* pos 02d7: 398 */ 0xBA /* ':' -> */,
+/* pos 02d8: 399 */ 0x00, 0x2F /* - terminal marker 47 - */,
+/* pos 02da: 400 */ 0xE3 /* 'c' -> */,
+/* pos 02db: 401 */ 0xE1 /* 'a' -> */,
+/* pos 02dc: 402 */ 0xF4 /* 't' -> */,
+/* pos 02dd: 403 */ 0xE9 /* 'i' -> */,
+/* pos 02de: 404 */ 0xEF /* 'o' -> */,
+/* pos 02df: 405 */ 0xEE /* 'n' -> */,
+/* pos 02e0: 406 */ 0xBA /* ':' -> */,
+/* pos 02e1: 407 */ 0x00, 0x30 /* - terminal marker 48 - */,
+/* pos 02e3: 408 */ 0xE1 /* 'a' -> */,
+/* pos 02e4: 409 */ 0xEE /* 'n' -> */,
+/* pos 02e5: 410 */ 0xE7 /* 'g' -> */,
+/* pos 02e6: 411 */ 0xE5 /* 'e' -> */,
+/* pos 02e7: 412 */ 0xBA /* ':' -> */,
+/* pos 02e8: 413 */ 0x00, 0x31 /* - terminal marker 49 - */,
+/* pos 02ea: 414 */ 0x74 /* 't' */, 0x07, 0x00 /* (to 0x02F1 state 415) */,
+ 0x78 /* 'x' */, 0x09, 0x00 /* (to 0x02F6 state 419) */,
0x08, /* fail */
-/* pos 02e4: 406 */ 0xE1 /* 'a' -> */,
-/* pos 02e5: 407 */ 0xE7 /* 'g' -> */,
-/* pos 02e6: 408 */ 0xBA /* ':' -> */,
-/* pos 02e7: 409 */ 0x00, 0x31 /* - terminal marker 49 - */,
-/* pos 02e9: 410 */ 0xF0 /* 'p' -> */,
-/* pos 02ea: 411 */ 0x65 /* 'e' */, 0x07, 0x00 /* (to 0x02F1 state 412) */,
- 0x69 /* 'i' */, 0x09, 0x00 /* (to 0x02F6 state 416) */,
+/* pos 02f1: 415 */ 0xE1 /* 'a' -> */,
+/* pos 02f2: 416 */ 0xE7 /* 'g' -> */,
+/* pos 02f3: 417 */ 0xBA /* ':' -> */,
+/* pos 02f4: 418 */ 0x00, 0x32 /* - terminal marker 50 - */,
+/* pos 02f6: 419 */ 0xF0 /* 'p' -> */,
+/* pos 02f7: 420 */ 0x65 /* 'e' */, 0x07, 0x00 /* (to 0x02FE state 421) */,
+ 0x69 /* 'i' */, 0x09, 0x00 /* (to 0x0303 state 425) */,
0x08, /* fail */
-/* pos 02f1: 412 */ 0xE3 /* 'c' -> */,
-/* pos 02f2: 413 */ 0xF4 /* 't' -> */,
-/* pos 02f3: 414 */ 0xBA /* ':' -> */,
-/* pos 02f4: 415 */ 0x00, 0x32 /* - terminal marker 50 - */,
-/* pos 02f6: 416 */ 0xF2 /* 'r' -> */,
-/* pos 02f7: 417 */ 0xE5 /* 'e' -> */,
-/* pos 02f8: 418 */ 0xF3 /* 's' -> */,
-/* pos 02f9: 419 */ 0xBA /* ':' -> */,
-/* pos 02fa: 420 */ 0x00, 0x33 /* - terminal marker 51 - */,
-/* pos 02fc: 421 */ 0xF2 /* 'r' -> */,
-/* pos 02fd: 422 */ 0xEF /* 'o' -> */,
-/* pos 02fe: 423 */ 0xED /* 'm' -> */,
-/* pos 02ff: 424 */ 0xBA /* ':' -> */,
-/* pos 0300: 425 */ 0x00, 0x34 /* - terminal marker 52 - */,
-/* pos 0302: 426 */ 0xF4 /* 't' -> */,
-/* pos 0303: 427 */ 0xE3 /* 'c' -> */,
-/* pos 0304: 428 */ 0xE8 /* 'h' -> */,
-/* pos 0305: 429 */ 0xBA /* ':' -> */,
-/* pos 0306: 430 */ 0x00, 0x35 /* - terminal marker 53 - */,
-/* pos 0308: 431 */ 0xE1 /* 'a' -> */,
-/* pos 0309: 432 */ 0xEE /* 'n' -> */,
-/* pos 030a: 433 */ 0xE7 /* 'g' -> */,
-/* pos 030b: 434 */ 0xE5 /* 'e' -> */,
-/* pos 030c: 435 */ 0xBA /* ':' -> */,
-/* pos 030d: 436 */ 0x00, 0x36 /* - terminal marker 54 - */,
-/* pos 030f: 437 */ 0xEE /* 'n' -> */,
-/* pos 0310: 438 */ 0xED /* 'm' -> */,
-/* pos 0311: 439 */ 0xEF /* 'o' -> */,
-/* pos 0312: 440 */ 0xE4 /* 'd' -> */,
-/* pos 0313: 441 */ 0xE9 /* 'i' -> */,
-/* pos 0314: 442 */ 0xE6 /* 'f' -> */,
-/* pos 0315: 443 */ 0xE9 /* 'i' -> */,
-/* pos 0316: 444 */ 0xE5 /* 'e' -> */,
-/* pos 0317: 445 */ 0xE4 /* 'd' -> */,
-/* pos 0318: 446 */ 0xAD /* '-' -> */,
-/* pos 0319: 447 */ 0xF3 /* 's' -> */,
-/* pos 031a: 448 */ 0xE9 /* 'i' -> */,
-/* pos 031b: 449 */ 0xEE /* 'n' -> */,
-/* pos 031c: 450 */ 0xE3 /* 'c' -> */,
-/* pos 031d: 451 */ 0xE5 /* 'e' -> */,
-/* pos 031e: 452 */ 0xBA /* ':' -> */,
-/* pos 031f: 453 */ 0x00, 0x37 /* - terminal marker 55 - */,
-/* pos 0321: 454 */ 0x61 /* 'a' */, 0x0A, 0x00 /* (to 0x032B state 455) */,
- 0x69 /* 'i' */, 0x15, 0x00 /* (to 0x0339 state 468) */,
- 0x6F /* 'o' */, 0x17, 0x00 /* (to 0x033E state 472) */,
+/* pos 02fe: 421 */ 0xE3 /* 'c' -> */,
+/* pos 02ff: 422 */ 0xF4 /* 't' -> */,
+/* pos 0300: 423 */ 0xBA /* ':' -> */,
+/* pos 0301: 424 */ 0x00, 0x33 /* - terminal marker 51 - */,
+/* pos 0303: 425 */ 0xF2 /* 'r' -> */,
+/* pos 0304: 426 */ 0xE5 /* 'e' -> */,
+/* pos 0305: 427 */ 0xF3 /* 's' -> */,
+/* pos 0306: 428 */ 0xBA /* ':' -> */,
+/* pos 0307: 429 */ 0x00, 0x34 /* - terminal marker 52 - */,
+/* pos 0309: 430 */ 0xF2 /* 'r' -> */,
+/* pos 030a: 431 */ 0xEF /* 'o' -> */,
+/* pos 030b: 432 */ 0xED /* 'm' -> */,
+/* pos 030c: 433 */ 0xBA /* ':' -> */,
+/* pos 030d: 434 */ 0x00, 0x35 /* - terminal marker 53 - */,
+/* pos 030f: 435 */ 0xF4 /* 't' -> */,
+/* pos 0310: 436 */ 0xE3 /* 'c' -> */,
+/* pos 0311: 437 */ 0xE8 /* 'h' -> */,
+/* pos 0312: 438 */ 0xBA /* ':' -> */,
+/* pos 0313: 439 */ 0x00, 0x36 /* - terminal marker 54 - */,
+/* pos 0315: 440 */ 0xE1 /* 'a' -> */,
+/* pos 0316: 441 */ 0xEE /* 'n' -> */,
+/* pos 0317: 442 */ 0xE7 /* 'g' -> */,
+/* pos 0318: 443 */ 0xE5 /* 'e' -> */,
+/* pos 0319: 444 */ 0xBA /* ':' -> */,
+/* pos 031a: 445 */ 0x00, 0x37 /* - terminal marker 55 - */,
+/* pos 031c: 446 */ 0xEE /* 'n' -> */,
+/* pos 031d: 447 */ 0xED /* 'm' -> */,
+/* pos 031e: 448 */ 0xEF /* 'o' -> */,
+/* pos 031f: 449 */ 0xE4 /* 'd' -> */,
+/* pos 0320: 450 */ 0xE9 /* 'i' -> */,
+/* pos 0321: 451 */ 0xE6 /* 'f' -> */,
+/* pos 0322: 452 */ 0xE9 /* 'i' -> */,
+/* pos 0323: 453 */ 0xE5 /* 'e' -> */,
+/* pos 0324: 454 */ 0xE4 /* 'd' -> */,
+/* pos 0325: 455 */ 0xAD /* '-' -> */,
+/* pos 0326: 456 */ 0xF3 /* 's' -> */,
+/* pos 0327: 457 */ 0xE9 /* 'i' -> */,
+/* pos 0328: 458 */ 0xEE /* 'n' -> */,
+/* pos 0329: 459 */ 0xE3 /* 'c' -> */,
+/* pos 032a: 460 */ 0xE5 /* 'e' -> */,
+/* pos 032b: 461 */ 0xBA /* ':' -> */,
+/* pos 032c: 462 */ 0x00, 0x38 /* - terminal marker 56 - */,
+/* pos 032e: 463 */ 0x61 /* 'a' */, 0x0A, 0x00 /* (to 0x0338 state 464) */,
+ 0x69 /* 'i' */, 0x15, 0x00 /* (to 0x0346 state 477) */,
+ 0x6F /* 'o' */, 0x17, 0x00 /* (to 0x034B state 481) */,
0x08, /* fail */
-/* pos 032b: 455 */ 0xF3 /* 's' -> */,
-/* pos 032c: 456 */ 0xF4 /* 't' -> */,
-/* pos 032d: 457 */ 0xAD /* '-' -> */,
-/* pos 032e: 458 */ 0xED /* 'm' -> */,
-/* pos 032f: 459 */ 0xEF /* 'o' -> */,
-/* pos 0330: 460 */ 0xE4 /* 'd' -> */,
-/* pos 0331: 461 */ 0xE9 /* 'i' -> */,
-/* pos 0332: 462 */ 0xE6 /* 'f' -> */,
-/* pos 0333: 463 */ 0xE9 /* 'i' -> */,
-/* pos 0334: 464 */ 0xE5 /* 'e' -> */,
-/* pos 0335: 465 */ 0xE4 /* 'd' -> */,
-/* pos 0336: 466 */ 0xBA /* ':' -> */,
-/* pos 0337: 467 */ 0x00, 0x38 /* - terminal marker 56 - */,
-/* pos 0339: 468 */ 0xEE /* 'n' -> */,
-/* pos 033a: 469 */ 0xEB /* 'k' -> */,
-/* pos 033b: 470 */ 0xBA /* ':' -> */,
-/* pos 033c: 471 */ 0x00, 0x39 /* - terminal marker 57 - */,
-/* pos 033e: 472 */ 0xE3 /* 'c' -> */,
-/* pos 033f: 473 */ 0xE1 /* 'a' -> */,
-/* pos 0340: 474 */ 0xF4 /* 't' -> */,
-/* pos 0341: 475 */ 0xE9 /* 'i' -> */,
-/* pos 0342: 476 */ 0xEF /* 'o' -> */,
-/* pos 0343: 477 */ 0xEE /* 'n' -> */,
-/* pos 0344: 478 */ 0xBA /* ':' -> */,
-/* pos 0345: 479 */ 0x00, 0x3A /* - terminal marker 58 - */,
-/* pos 0347: 480 */ 0xE1 /* 'a' -> */,
-/* pos 0348: 481 */ 0xF8 /* 'x' -> */,
-/* pos 0349: 482 */ 0xAD /* '-' -> */,
-/* pos 034a: 483 */ 0xE6 /* 'f' -> */,
-/* pos 034b: 484 */ 0xEF /* 'o' -> */,
-/* pos 034c: 485 */ 0xF2 /* 'r' -> */,
-/* pos 034d: 486 */ 0xF7 /* 'w' -> */,
-/* pos 034e: 487 */ 0xE1 /* 'a' -> */,
-/* pos 034f: 488 */ 0xF2 /* 'r' -> */,
-/* pos 0350: 489 */ 0xE4 /* 'd' -> */,
-/* pos 0351: 490 */ 0xF3 /* 's' -> */,
-/* pos 0352: 491 */ 0xBA /* ':' -> */,
-/* pos 0353: 492 */ 0x00, 0x3B /* - terminal marker 59 - */,
-/* pos 0355: 493 */ 0xF8 /* 'x' -> */,
-/* pos 0356: 494 */ 0xF9 /* 'y' -> */,
-/* pos 0357: 495 */ 0xAD /* '-' -> */,
-/* pos 0358: 496 */ 0xE1 /* 'a' -> */,
-/* pos 0359: 497 */ 0xF5 /* 'u' -> */,
-/* pos 035a: 498 */ 0xF4 /* 't' -> */,
-/* pos 035b: 499 */ 0xE8 /* 'h' -> */,
-/* pos 035c: 500 */ 0x65 /* 'e' */, 0x07, 0x00 /* (to 0x0363 state 501) */,
- 0x6F /* 'o' */, 0x0E, 0x00 /* (to 0x036D state 510) */,
+/* pos 0338: 464 */ 0xF3 /* 's' -> */,
+/* pos 0339: 465 */ 0xF4 /* 't' -> */,
+/* pos 033a: 466 */ 0xAD /* '-' -> */,
+/* pos 033b: 467 */ 0xED /* 'm' -> */,
+/* pos 033c: 468 */ 0xEF /* 'o' -> */,
+/* pos 033d: 469 */ 0xE4 /* 'd' -> */,
+/* pos 033e: 470 */ 0xE9 /* 'i' -> */,
+/* pos 033f: 471 */ 0xE6 /* 'f' -> */,
+/* pos 0340: 472 */ 0xE9 /* 'i' -> */,
+/* pos 0341: 473 */ 0xE5 /* 'e' -> */,
+/* pos 0342: 474 */ 0xE4 /* 'd' -> */,
+/* pos 0343: 475 */ 0xBA /* ':' -> */,
+/* pos 0344: 476 */ 0x00, 0x39 /* - terminal marker 57 - */,
+/* pos 0346: 477 */ 0xEE /* 'n' -> */,
+/* pos 0347: 478 */ 0xEB /* 'k' -> */,
+/* pos 0348: 479 */ 0xBA /* ':' -> */,
+/* pos 0349: 480 */ 0x00, 0x3A /* - terminal marker 58 - */,
+/* pos 034b: 481 */ 0xE3 /* 'c' -> */,
+/* pos 034c: 482 */ 0xE1 /* 'a' -> */,
+/* pos 034d: 483 */ 0xF4 /* 't' -> */,
+/* pos 034e: 484 */ 0xE9 /* 'i' -> */,
+/* pos 034f: 485 */ 0xEF /* 'o' -> */,
+/* pos 0350: 486 */ 0xEE /* 'n' -> */,
+/* pos 0351: 487 */ 0xBA /* ':' -> */,
+/* pos 0352: 488 */ 0x00, 0x3B /* - terminal marker 59 - */,
+/* pos 0354: 489 */ 0xE1 /* 'a' -> */,
+/* pos 0355: 490 */ 0xF8 /* 'x' -> */,
+/* pos 0356: 491 */ 0xAD /* '-' -> */,
+/* pos 0357: 492 */ 0xE6 /* 'f' -> */,
+/* pos 0358: 493 */ 0xEF /* 'o' -> */,
+/* pos 0359: 494 */ 0xF2 /* 'r' -> */,
+/* pos 035a: 495 */ 0xF7 /* 'w' -> */,
+/* pos 035b: 496 */ 0xE1 /* 'a' -> */,
+/* pos 035c: 497 */ 0xF2 /* 'r' -> */,
+/* pos 035d: 498 */ 0xE4 /* 'd' -> */,
+/* pos 035e: 499 */ 0xF3 /* 's' -> */,
+/* pos 035f: 500 */ 0xBA /* ':' -> */,
+/* pos 0360: 501 */ 0x00, 0x3C /* - terminal marker 60 - */,
+/* pos 0362: 502 */ 0xF8 /* 'x' -> */,
+/* pos 0363: 503 */ 0xF9 /* 'y' -> */,
+/* pos 0364: 504 */ 0xAD /* '-' -> */,
+/* pos 0365: 505 */ 0xE1 /* 'a' -> */,
+/* pos 0366: 506 */ 0xF5 /* 'u' -> */,
+/* pos 0367: 507 */ 0xF4 /* 't' -> */,
+/* pos 0368: 508 */ 0xE8 /* 'h' -> */,
+/* pos 0369: 509 */ 0x65 /* 'e' */, 0x07, 0x00 /* (to 0x0370 state 510) */,
+ 0x6F /* 'o' */, 0x0E, 0x00 /* (to 0x037A state 519) */,
0x08, /* fail */
-/* pos 0363: 501 */ 0xEE /* 'n' -> */,
-/* pos 0364: 502 */ 0xF4 /* 't' -> */,
-/* pos 0365: 503 */ 0xE9 /* 'i' -> */,
-/* pos 0366: 504 */ 0xE3 /* 'c' -> */,
-/* pos 0367: 505 */ 0xE1 /* 'a' -> */,
-/* pos 0368: 506 */ 0xF4 /* 't' -> */,
-/* pos 0369: 507 */ 0xE5 /* 'e' -> */,
-/* pos 036a: 508 */ 0xBA /* ':' -> */,
-/* pos 036b: 509 */ 0x00, 0x3C /* - terminal marker 60 - */,
-/* pos 036d: 510 */ 0xF2 /* 'r' -> */,
-/* pos 036e: 511 */ 0xE9 /* 'i' -> */,
-/* pos 036f: 512 */ 0xFA /* 'z' -> */,
-/* pos 0370: 513 */ 0xE1 /* 'a' -> */,
-/* pos 0371: 514 */ 0xF4 /* 't' -> */,
-/* pos 0372: 515 */ 0xE9 /* 'i' -> */,
-/* pos 0373: 516 */ 0xEF /* 'o' -> */,
-/* pos 0374: 517 */ 0xEE /* 'n' -> */,
-/* pos 0375: 518 */ 0xBA /* ':' -> */,
-/* pos 0376: 519 */ 0x00, 0x3D /* - terminal marker 61 - */,
-/* pos 0378: 520 */ 0xE5 /* 'e' -> */,
-/* pos 0379: 521 */ 0xF3 /* 's' -> */,
-/* pos 037a: 522 */ 0xE8 /* 'h' -> */,
-/* pos 037b: 523 */ 0xBA /* ':' -> */,
-/* pos 037c: 524 */ 0x00, 0x3E /* - terminal marker 62 - */,
-/* pos 037e: 525 */ 0xF2 /* 'r' -> */,
-/* pos 037f: 526 */ 0xF9 /* 'y' -> */,
-/* pos 0380: 527 */ 0xAD /* '-' -> */,
-/* pos 0381: 528 */ 0xE1 /* 'a' -> */,
-/* pos 0382: 529 */ 0xE6 /* 'f' -> */,
-/* pos 0383: 530 */ 0xF4 /* 't' -> */,
-/* pos 0384: 531 */ 0xE5 /* 'e' -> */,
-/* pos 0385: 532 */ 0xF2 /* 'r' -> */,
-/* pos 0386: 533 */ 0xBA /* ':' -> */,
-/* pos 0387: 534 */ 0x00, 0x3F /* - terminal marker 63 - */,
-/* pos 0389: 535 */ 0xF6 /* 'v' -> */,
-/* pos 038a: 536 */ 0xE5 /* 'e' -> */,
-/* pos 038b: 537 */ 0xF2 /* 'r' -> */,
-/* pos 038c: 538 */ 0xBA /* ':' -> */,
-/* pos 038d: 539 */ 0x00, 0x40 /* - terminal marker 64 - */,
-/* pos 038f: 540 */ 0xAD /* '-' -> */,
-/* pos 0390: 541 */ 0xE3 /* 'c' -> */,
-/* pos 0391: 542 */ 0xEF /* 'o' -> */,
-/* pos 0392: 543 */ 0xEF /* 'o' -> */,
-/* pos 0393: 544 */ 0xEB /* 'k' -> */,
-/* pos 0394: 545 */ 0xE9 /* 'i' -> */,
-/* pos 0395: 546 */ 0xE5 /* 'e' -> */,
-/* pos 0396: 547 */ 0xBA /* ':' -> */,
-/* pos 0397: 548 */ 0x00, 0x41 /* - terminal marker 65 - */,
-/* pos 0399: 549 */ 0xF2 /* 'r' -> */,
-/* pos 039a: 550 */ 0xE9 /* 'i' -> */,
-/* pos 039b: 551 */ 0xE3 /* 'c' -> */,
-/* pos 039c: 552 */ 0xF4 /* 't' -> */,
-/* pos 039d: 553 */ 0xAD /* '-' -> */,
-/* pos 039e: 554 */ 0xF4 /* 't' -> */,
-/* pos 039f: 555 */ 0xF2 /* 'r' -> */,
-/* pos 03a0: 556 */ 0xE1 /* 'a' -> */,
-/* pos 03a1: 557 */ 0xEE /* 'n' -> */,
-/* pos 03a2: 558 */ 0xF3 /* 's' -> */,
-/* pos 03a3: 559 */ 0xF0 /* 'p' -> */,
-/* pos 03a4: 560 */ 0xEF /* 'o' -> */,
-/* pos 03a5: 561 */ 0xF2 /* 'r' -> */,
-/* pos 03a6: 562 */ 0xF4 /* 't' -> */,
-/* pos 03a7: 563 */ 0xAD /* '-' -> */,
-/* pos 03a8: 564 */ 0xF3 /* 's' -> */,
-/* pos 03a9: 565 */ 0xE5 /* 'e' -> */,
-/* pos 03aa: 566 */ 0xE3 /* 'c' -> */,
-/* pos 03ab: 567 */ 0xF5 /* 'u' -> */,
-/* pos 03ac: 568 */ 0xF2 /* 'r' -> */,
-/* pos 03ad: 569 */ 0xE9 /* 'i' -> */,
-/* pos 03ae: 570 */ 0xF4 /* 't' -> */,
-/* pos 03af: 571 */ 0xF9 /* 'y' -> */,
-/* pos 03b0: 572 */ 0xBA /* ':' -> */,
-/* pos 03b1: 573 */ 0x00, 0x42 /* - terminal marker 66 - */,
-/* pos 03b3: 574 */ 0xF2 /* 'r' -> */,
-/* pos 03b4: 575 */ 0xE1 /* 'a' -> */,
-/* pos 03b5: 576 */ 0xEE /* 'n' -> */,
-/* pos 03b6: 577 */ 0xF3 /* 's' -> */,
-/* pos 03b7: 578 */ 0xE6 /* 'f' -> */,
-/* pos 03b8: 579 */ 0xE5 /* 'e' -> */,
-/* pos 03b9: 580 */ 0xF2 /* 'r' -> */,
-/* pos 03ba: 581 */ 0xAD /* '-' -> */,
-/* pos 03bb: 582 */ 0xE5 /* 'e' -> */,
-/* pos 03bc: 583 */ 0xEE /* 'n' -> */,
-/* pos 03bd: 584 */ 0xE3 /* 'c' -> */,
-/* pos 03be: 585 */ 0xEF /* 'o' -> */,
-/* pos 03bf: 586 */ 0xE4 /* 'd' -> */,
-/* pos 03c0: 587 */ 0xE9 /* 'i' -> */,
-/* pos 03c1: 588 */ 0xEE /* 'n' -> */,
-/* pos 03c2: 589 */ 0xE7 /* 'g' -> */,
-/* pos 03c3: 590 */ 0xBA /* ':' -> */,
-/* pos 03c4: 591 */ 0x00, 0x43 /* - terminal marker 67 - */,
-/* pos 03c6: 592 */ 0xE5 /* 'e' -> */,
-/* pos 03c7: 593 */ 0xF2 /* 'r' -> */,
-/* pos 03c8: 594 */ 0xAD /* '-' -> */,
-/* pos 03c9: 595 */ 0xE1 /* 'a' -> */,
-/* pos 03ca: 596 */ 0xE7 /* 'g' -> */,
-/* pos 03cb: 597 */ 0xE5 /* 'e' -> */,
-/* pos 03cc: 598 */ 0xEE /* 'n' -> */,
-/* pos 03cd: 599 */ 0xF4 /* 't' -> */,
-/* pos 03ce: 600 */ 0xBA /* ':' -> */,
-/* pos 03cf: 601 */ 0x00, 0x44 /* - terminal marker 68 - */,
-/* pos 03d1: 602 */ 0x61 /* 'a' */, 0x07, 0x00 /* (to 0x03D8 state 603) */,
- 0x69 /* 'i' */, 0x09, 0x00 /* (to 0x03DD state 607) */,
+/* pos 0370: 510 */ 0xEE /* 'n' -> */,
+/* pos 0371: 511 */ 0xF4 /* 't' -> */,
+/* pos 0372: 512 */ 0xE9 /* 'i' -> */,
+/* pos 0373: 513 */ 0xE3 /* 'c' -> */,
+/* pos 0374: 514 */ 0xE1 /* 'a' -> */,
+/* pos 0375: 515 */ 0xF4 /* 't' -> */,
+/* pos 0376: 516 */ 0xE5 /* 'e' -> */,
+/* pos 0377: 517 */ 0xBA /* ':' -> */,
+/* pos 0378: 518 */ 0x00, 0x3D /* - terminal marker 61 - */,
+/* pos 037a: 519 */ 0xF2 /* 'r' -> */,
+/* pos 037b: 520 */ 0xE9 /* 'i' -> */,
+/* pos 037c: 521 */ 0xFA /* 'z' -> */,
+/* pos 037d: 522 */ 0xE1 /* 'a' -> */,
+/* pos 037e: 523 */ 0xF4 /* 't' -> */,
+/* pos 037f: 524 */ 0xE9 /* 'i' -> */,
+/* pos 0380: 525 */ 0xEF /* 'o' -> */,
+/* pos 0381: 526 */ 0xEE /* 'n' -> */,
+/* pos 0382: 527 */ 0xBA /* ':' -> */,
+/* pos 0383: 528 */ 0x00, 0x3E /* - terminal marker 62 - */,
+/* pos 0385: 529 */ 0xE5 /* 'e' -> */,
+/* pos 0386: 530 */ 0xF3 /* 's' -> */,
+/* pos 0387: 531 */ 0xE8 /* 'h' -> */,
+/* pos 0388: 532 */ 0xBA /* ':' -> */,
+/* pos 0389: 533 */ 0x00, 0x3F /* - terminal marker 63 - */,
+/* pos 038b: 534 */ 0xF2 /* 'r' -> */,
+/* pos 038c: 535 */ 0xF9 /* 'y' -> */,
+/* pos 038d: 536 */ 0xAD /* '-' -> */,
+/* pos 038e: 537 */ 0xE1 /* 'a' -> */,
+/* pos 038f: 538 */ 0xE6 /* 'f' -> */,
+/* pos 0390: 539 */ 0xF4 /* 't' -> */,
+/* pos 0391: 540 */ 0xE5 /* 'e' -> */,
+/* pos 0392: 541 */ 0xF2 /* 'r' -> */,
+/* pos 0393: 542 */ 0xBA /* ':' -> */,
+/* pos 0394: 543 */ 0x00, 0x40 /* - terminal marker 64 - */,
+/* pos 0396: 544 */ 0xF6 /* 'v' -> */,
+/* pos 0397: 545 */ 0xE5 /* 'e' -> */,
+/* pos 0398: 546 */ 0xF2 /* 'r' -> */,
+/* pos 0399: 547 */ 0xBA /* ':' -> */,
+/* pos 039a: 548 */ 0x00, 0x41 /* - terminal marker 65 - */,
+/* pos 039c: 549 */ 0xAD /* '-' -> */,
+/* pos 039d: 550 */ 0xE3 /* 'c' -> */,
+/* pos 039e: 551 */ 0xEF /* 'o' -> */,
+/* pos 039f: 552 */ 0xEF /* 'o' -> */,
+/* pos 03a0: 553 */ 0xEB /* 'k' -> */,
+/* pos 03a1: 554 */ 0xE9 /* 'i' -> */,
+/* pos 03a2: 555 */ 0xE5 /* 'e' -> */,
+/* pos 03a3: 556 */ 0xBA /* ':' -> */,
+/* pos 03a4: 557 */ 0x00, 0x42 /* - terminal marker 66 - */,
+/* pos 03a6: 558 */ 0xF2 /* 'r' -> */,
+/* pos 03a7: 559 */ 0xE9 /* 'i' -> */,
+/* pos 03a8: 560 */ 0xE3 /* 'c' -> */,
+/* pos 03a9: 561 */ 0xF4 /* 't' -> */,
+/* pos 03aa: 562 */ 0xAD /* '-' -> */,
+/* pos 03ab: 563 */ 0xF4 /* 't' -> */,
+/* pos 03ac: 564 */ 0xF2 /* 'r' -> */,
+/* pos 03ad: 565 */ 0xE1 /* 'a' -> */,
+/* pos 03ae: 566 */ 0xEE /* 'n' -> */,
+/* pos 03af: 567 */ 0xF3 /* 's' -> */,
+/* pos 03b0: 568 */ 0xF0 /* 'p' -> */,
+/* pos 03b1: 569 */ 0xEF /* 'o' -> */,
+/* pos 03b2: 570 */ 0xF2 /* 'r' -> */,
+/* pos 03b3: 571 */ 0xF4 /* 't' -> */,
+/* pos 03b4: 572 */ 0xAD /* '-' -> */,
+/* pos 03b5: 573 */ 0xF3 /* 's' -> */,
+/* pos 03b6: 574 */ 0xE5 /* 'e' -> */,
+/* pos 03b7: 575 */ 0xE3 /* 'c' -> */,
+/* pos 03b8: 576 */ 0xF5 /* 'u' -> */,
+/* pos 03b9: 577 */ 0xF2 /* 'r' -> */,
+/* pos 03ba: 578 */ 0xE9 /* 'i' -> */,
+/* pos 03bb: 579 */ 0xF4 /* 't' -> */,
+/* pos 03bc: 580 */ 0xF9 /* 'y' -> */,
+/* pos 03bd: 581 */ 0xBA /* ':' -> */,
+/* pos 03be: 582 */ 0x00, 0x43 /* - terminal marker 67 - */,
+/* pos 03c0: 583 */ 0xF2 /* 'r' -> */,
+/* pos 03c1: 584 */ 0xE1 /* 'a' -> */,
+/* pos 03c2: 585 */ 0xEE /* 'n' -> */,
+/* pos 03c3: 586 */ 0xF3 /* 's' -> */,
+/* pos 03c4: 587 */ 0xE6 /* 'f' -> */,
+/* pos 03c5: 588 */ 0xE5 /* 'e' -> */,
+/* pos 03c6: 589 */ 0xF2 /* 'r' -> */,
+/* pos 03c7: 590 */ 0xAD /* '-' -> */,
+/* pos 03c8: 591 */ 0xE5 /* 'e' -> */,
+/* pos 03c9: 592 */ 0xEE /* 'n' -> */,
+/* pos 03ca: 593 */ 0xE3 /* 'c' -> */,
+/* pos 03cb: 594 */ 0xEF /* 'o' -> */,
+/* pos 03cc: 595 */ 0xE4 /* 'd' -> */,
+/* pos 03cd: 596 */ 0xE9 /* 'i' -> */,
+/* pos 03ce: 597 */ 0xEE /* 'n' -> */,
+/* pos 03cf: 598 */ 0xE7 /* 'g' -> */,
+/* pos 03d0: 599 */ 0xBA /* ':' -> */,
+/* pos 03d1: 600 */ 0x00, 0x44 /* - terminal marker 68 - */,
+/* pos 03d3: 601 */ 0xE5 /* 'e' -> */,
+/* pos 03d4: 602 */ 0xF2 /* 'r' -> */,
+/* pos 03d5: 603 */ 0xAD /* '-' -> */,
+/* pos 03d6: 604 */ 0xE1 /* 'a' -> */,
+/* pos 03d7: 605 */ 0xE7 /* 'g' -> */,
+/* pos 03d8: 606 */ 0xE5 /* 'e' -> */,
+/* pos 03d9: 607 */ 0xEE /* 'n' -> */,
+/* pos 03da: 608 */ 0xF4 /* 't' -> */,
+/* pos 03db: 609 */ 0xBA /* ':' -> */,
+/* pos 03dc: 610 */ 0x00, 0x45 /* - terminal marker 69 - */,
+/* pos 03de: 611 */ 0x61 /* 'a' */, 0x07, 0x00 /* (to 0x03E5 state 612) */,
+ 0x69 /* 'i' */, 0x09, 0x00 /* (to 0x03EA state 616) */,
0x08, /* fail */
-/* pos 03d8: 603 */ 0xF2 /* 'r' -> */,
-/* pos 03d9: 604 */ 0xF9 /* 'y' -> */,
-/* pos 03da: 605 */ 0xBA /* ':' -> */,
-/* pos 03db: 606 */ 0x00, 0x45 /* - terminal marker 69 - */,
-/* pos 03dd: 607 */ 0xE1 /* 'a' -> */,
-/* pos 03de: 608 */ 0xBA /* ':' -> */,
-/* pos 03df: 609 */ 0x00, 0x46 /* - terminal marker 70 - */,
-/* pos 03e1: 610 */ 0xF7 /* 'w' -> */,
-/* pos 03e2: 611 */ 0xF7 /* 'w' -> */,
-/* pos 03e3: 612 */ 0xAD /* '-' -> */,
-/* pos 03e4: 613 */ 0xE1 /* 'a' -> */,
-/* pos 03e5: 614 */ 0xF5 /* 'u' -> */,
-/* pos 03e6: 615 */ 0xF4 /* 't' -> */,
-/* pos 03e7: 616 */ 0xE8 /* 'h' -> */,
-/* pos 03e8: 617 */ 0xE5 /* 'e' -> */,
-/* pos 03e9: 618 */ 0xEE /* 'n' -> */,
-/* pos 03ea: 619 */ 0xF4 /* 't' -> */,
-/* pos 03eb: 620 */ 0xE9 /* 'i' -> */,
-/* pos 03ec: 621 */ 0xE3 /* 'c' -> */,
-/* pos 03ed: 622 */ 0xE1 /* 'a' -> */,
-/* pos 03ee: 623 */ 0xF4 /* 't' -> */,
-/* pos 03ef: 624 */ 0xE5 /* 'e' -> */,
-/* pos 03f0: 625 */ 0xBA /* ':' -> */,
-/* pos 03f1: 626 */ 0x00, 0x47 /* - terminal marker 71 - */,
-/* total size 1011 bytes */
+/* pos 03e5: 612 */ 0xF2 /* 'r' -> */,
+/* pos 03e6: 613 */ 0xF9 /* 'y' -> */,
+/* pos 03e7: 614 */ 0xBA /* ':' -> */,
+/* pos 03e8: 615 */ 0x00, 0x46 /* - terminal marker 70 - */,
+/* pos 03ea: 616 */ 0xE1 /* 'a' -> */,
+/* pos 03eb: 617 */ 0xBA /* ':' -> */,
+/* pos 03ec: 618 */ 0x00, 0x47 /* - terminal marker 71 - */,
+/* pos 03ee: 619 */ 0xF7 /* 'w' -> */,
+/* pos 03ef: 620 */ 0xF7 /* 'w' -> */,
+/* pos 03f0: 621 */ 0xAD /* '-' -> */,
+/* pos 03f1: 622 */ 0xE1 /* 'a' -> */,
+/* pos 03f2: 623 */ 0xF5 /* 'u' -> */,
+/* pos 03f3: 624 */ 0xF4 /* 't' -> */,
+/* pos 03f4: 625 */ 0xE8 /* 'h' -> */,
+/* pos 03f5: 626 */ 0xE5 /* 'e' -> */,
+/* pos 03f6: 627 */ 0xEE /* 'n' -> */,
+/* pos 03f7: 628 */ 0xF4 /* 't' -> */,
+/* pos 03f8: 629 */ 0xE9 /* 'i' -> */,
+/* pos 03f9: 630 */ 0xE3 /* 'c' -> */,
+/* pos 03fa: 631 */ 0xE1 /* 'a' -> */,
+/* pos 03fb: 632 */ 0xF4 /* 't' -> */,
+/* pos 03fc: 633 */ 0xE5 /* 'e' -> */,
+/* pos 03fd: 634 */ 0xBA /* ':' -> */,
+/* pos 03fe: 635 */ 0x00, 0x48 /* - terminal marker 72 - */,
+/* total size 1024 bytes */
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index 50b8ff4..30dbd57 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -326,18 +326,7 @@
WSI_TOKEN_KEY,
WSI_TOKEN_VERSION,
WSI_TOKEN_SWORIGIN,
-
- WSI_TOKEN_HTTP_URI_ARGS,
- /* use token storage to stash these */
-
- _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
- _WSI_TOKEN_CLIENT_PEER_ADDRESS,
- _WSI_TOKEN_CLIENT_URI,
- _WSI_TOKEN_CLIENT_HOST,
- _WSI_TOKEN_CLIENT_ORIGIN,
-
-#ifdef LWS_USE_HTTP2
WSI_TOKEN_HTTP_COLON_AUTHORITY,
WSI_TOKEN_HTTP_COLON_METHOD,
WSI_TOKEN_HTTP_COLON_PATH,
@@ -377,7 +366,16 @@
WSI_TOKEN_HTTP_VARY,
WSI_TOKEN_HTTP_VIA,
WSI_TOKEN_HTTP_WWW_AUTHENTICATE,
-#endif
+
+ WSI_TOKEN_HTTP_URI_ARGS,
+
+ /* use token storage to stash these */
+
+ _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
+ _WSI_TOKEN_CLIENT_PEER_ADDRESS,
+ _WSI_TOKEN_CLIENT_URI,
+ _WSI_TOKEN_CLIENT_HOST,
+ _WSI_TOKEN_CLIENT_ORIGIN,
/* always last real token index*/
WSI_TOKEN_COUNT,
@@ -1044,6 +1042,37 @@
LWS_VISIBLE LWS_EXTERN void
libwebsocket_cancel_service(struct libwebsocket_context *context);
+LWS_VISIBLE LWS_EXTERN const unsigned char *
+lws_token_to_string(enum lws_token_indexes token);
+
+LWS_VISIBLE LWS_EXTERN int
+lws_add_http_header_by_name(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ const unsigned char *name,
+ const unsigned char *value,
+ int length,
+ unsigned char **p,
+ unsigned char *end);
+LWS_VISIBLE LWS_EXTERN int
+lws_finalize_http_header(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ unsigned char **p,
+ unsigned char *end);
+LWS_VISIBLE LWS_EXTERN int
+lws_add_http_header_by_token(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ enum lws_token_indexes token,
+ const unsigned char *value,
+ int length,
+ unsigned char **p,
+ unsigned char *end);
+LWS_VISIBLE LWS_EXTERN int
+lws_add_http_header_status(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ unsigned int code,
+ unsigned char **p,
+ unsigned char *end);
+
#ifdef LWS_USE_LIBEV
LWS_VISIBLE LWS_EXTERN int
libwebsocket_initloop(
@@ -1126,7 +1155,8 @@
LWS_VISIBLE LWS_EXTERN int
libwebsockets_serve_http_file(struct libwebsocket_context *context,
struct libwebsocket *wsi, const char *file,
- const char *content_type, const char *other_headers);
+ const char *content_type, const char *other_headers,
+ int other_headers_len);
LWS_VISIBLE LWS_EXTERN int
libwebsockets_serve_http_file_fragment(struct libwebsocket_context *context,
struct libwebsocket *wsi);
diff --git a/lib/minilex.c b/lib/minilex.c
index 9a0a8d1..1aea0f6 100644
--- a/lib/minilex.c
+++ b/lib/minilex.c
@@ -16,90 +16,7 @@
#include <stdlib.h>
#include <string.h>
-/* set of parsable strings -- ALL LOWER CASE */
-
-const char *set[] = {
- "get ",
- "post ",
- "options ",
- "host:",
- "connection:",
- "upgrade:",
- "origin:",
- "sec-websocket-draft:",
- "\x0d\x0a",
-
- "sec-websocket-extensions:",
- "sec-websocket-key1:",
- "sec-websocket-key2:",
- "sec-websocket-protocol:",
-
- "sec-websocket-accept:",
- "sec-websocket-nonce:",
- "http/1.1 ",
- "http2-settings:",
-
- "accept:",
- "access-control-request-headers:",
- "if-modified-since:",
- "if-none-match:",
- "accept-encoding:",
- "accept-language:",
- "pragma:",
- "cache-control:",
- "authorization:",
- "cookie:",
- "content-length:",
- "content-type:",
- "date:",
- "range:",
- "referer:",
- "sec-websocket-key:",
- "sec-websocket-version:",
- "sec-websocket-origin:",
-
- ":authority:",
- ":method:",
- ":path:",
- ":scheme:",
- ":status:",
-
- "accept-charset:",
- "accept-ranges:",
- "access-control-allow-origin:",
- "age:",
- "allow:",
- "content-disposition:",
- "content-language:",
- "content-location:",
- "content-range:",
- "etag:",
- "expect:",
- "expires:",
- "from:",
- "if-match:",
- "if-range:",
- "if-unmodified-since:",
- "last-modified:",
- "link:",
- "location:",
- "max-forwards:",
- "proxy-authenticate:",
- "proxy-authorization:",
- "refresh:",
- "retry-after:",
- "server:",
- "set-cookie:",
- "strict-transport-security:",
- "transfer-encoding:",
- "user-agent:",
- "vary:",
- "via:",
- "www-authenticate:",
-
- "", /* not matchable */
-
-};
+#include "lextable-strings.h"
/*
* b7 = 0 = 1-byte seq
diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h
index 9d5f1b4..a52ee41 100755
--- a/lib/private-libwebsockets.h
+++ b/lib/private-libwebsockets.h
@@ -923,6 +923,28 @@
LWS_EXTERN int lws_hpack_interpret(struct libwebsocket_context *context,
struct libwebsocket *wsi,
unsigned char c);
+LWS_EXTERN int
+lws_add_http2_header_by_name(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ const unsigned char *name,
+ const unsigned char *value,
+ int length,
+ unsigned char **p,
+ unsigned char *end);
+LWS_EXTERN int
+lws_add_http2_header_by_token(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ enum lws_token_indexes token,
+ const unsigned char *value,
+ int length,
+ unsigned char **p,
+ unsigned char *end);
+LWS_EXTERN int
+lws_add_http2_header_status(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ unsigned int code,
+ unsigned char **p,
+ unsigned char *end);
#endif
LWS_EXTERN int
diff --git a/lib/server.c b/lib/server.c
index 8563a43..b05b3ef 100644
--- a/lib/server.c
+++ b/lib/server.c
@@ -834,6 +834,87 @@
return 1;
}
+#include "lextable-strings.h"
+
+const unsigned char *lws_token_to_string(enum lws_token_indexes token)
+{
+ if ((unsigned int)token >= ARRAY_SIZE(set))
+ return NULL;
+
+ return (unsigned char *)set[token];
+}
+
+int lws_add_http_header_by_name(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ const unsigned char *name,
+ const unsigned char *value,
+ int length,
+ unsigned char **p,
+ unsigned char *end)
+{
+#ifdef LWS_USE_HTTP2
+ if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING)
+ return lws_add_http2_header_by_name(context, wsi, name, value, length, p, end);
+#endif
+ if (name) {
+ while (*p < end && *name)
+ *((*p)++) = *name++;
+
+ if (*p == end)
+ return 1;
+
+ *((*p)++) = ' ';
+ }
+ if (*p + length + 3 >= end)
+ return 1;
+
+ memcpy(*p, value, length);
+ *p += length;
+
+ *((*p)++) = '\x0d';
+ *((*p)++) = '\x0a';
+
+ return 0;
+}
+
+int lws_finalize_http_header(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ unsigned char **p,
+ unsigned char *end)
+{
+#ifdef LWS_USE_HTTP2
+ if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING)
+ return 0;
+#endif
+
+ if ((long)(end - *p) < 3)
+ return 1;
+
+ *((*p)++) = '\x0d';
+ *((*p)++) = '\x0a';
+
+ return 0;
+}
+
+int lws_add_http_header_by_token(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ enum lws_token_indexes token,
+ const unsigned char *value,
+ int length,
+ unsigned char **p,
+ unsigned char *end)
+{
+ const unsigned char *name;
+#ifdef LWS_USE_HTTP2
+ if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING)
+ return lws_add_http2_header_by_token(context, wsi, token, value, length, p, end);
+#endif
+ name = lws_token_to_string(token);
+ if (!name)
+ return 1;
+
+ return lws_add_http_header_by_name(context, wsi, name, value, length, p, end);
+}
static const char *err400[] = {
"Bad Request",
@@ -865,12 +946,36 @@
"HTTP Version Not Supported"
};
+int lws_add_http_header_status(struct libwebsocket_context *context,
+ struct libwebsocket *wsi,
+ unsigned int code,
+ unsigned char **p,
+ unsigned char *end)
+{
+ unsigned char code_and_desc[60];
+ const char *description = "";
+ int n;
+
+#ifdef LWS_USE_HTTP2
+ if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING)
+ return lws_add_http2_header_status(context, wsi, code, p, end);
+#endif
+ if (code >= 400 && code < (400 + ARRAY_SIZE(err400)))
+ description = err400[code - 400];
+ if (code >= 500 && code < (500 + ARRAY_SIZE(err500)))
+ description = err500[code - 500];
+
+ n = sprintf((char *)code_and_desc, "HTTP/1.0 %u %s", code, description);
+
+ return lws_add_http_header_by_name(context, wsi, NULL, code_and_desc, n, p, end);
+}
+
/**
* libwebsockets_return_http_status() - Return simple http status
* @context: libwebsockets context
* @wsi: Websocket instance (available from user callback)
* @code: Status index, eg, 404
- * @html_body: User-readable HTML description, or NULL
+ * @html_body: User-readable HTML description < 1KB, or NULL
*
* Helper to report HTTP errors back to the client cleanly and
* consistently
@@ -880,30 +985,30 @@
unsigned int code, const char *html_body)
{
int n, m;
- const char *description = "";
+
+ unsigned char *p = context->service_buffer + LWS_SEND_BUFFER_PRE_PADDING;
+ unsigned char *start = p;
+ unsigned char *end = p + sizeof(context->service_buffer) -
+ LWS_SEND_BUFFER_PRE_PADDING;
if (!html_body)
html_body = "";
- if (code >= 400 && code < (400 + ARRAY_SIZE(err400)))
- description = err400[code - 400];
- if (code >= 500 && code < (500 + ARRAY_SIZE(err500)))
- description = err500[code - 500];
+ if (lws_add_http_header_status(context, wsi, code, &p, end))
+ return 1;
+ if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_SERVER, (unsigned char *)"libwebsockets", 13, &p, end))
+ return 1;
+ if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, (unsigned char *)"text/html", 9, &p, end))
+ return 1;
+ if (lws_finalize_http_header(context, wsi, &p, end))
+ return 1;
- n = sprintf((char *)context->service_buffer +
- LWS_SEND_BUFFER_PRE_PADDING,
- "HTTP/1.0 %u %s\x0d\x0a"
- "Server: libwebsockets\x0d\x0a"
- "Content-Type: text/html\x0d\x0a\x0d\x0a"
- "<h1>%u %s</h1>%s",
- code, description, code, description, html_body);
+ m = libwebsocket_write(wsi, start, p - start, LWS_WRITE_HTTP_HEADERS);
+ if (m)
+ return m;
- lwsl_info((const char *)context->service_buffer +
- LWS_SEND_BUFFER_PRE_PADDING);
-
- m = libwebsocket_write(wsi, context->service_buffer +
- LWS_SEND_BUFFER_PRE_PADDING, n,
- LWS_WRITE_HTTP_HEADERS);
+ n = sprintf((char *)start, "<html><body><h1>%u</h1>%s</body></html>", code, html_body);
+ m = libwebsocket_write(wsi, start, n, LWS_WRITE_HTTP);
return m;
}
@@ -929,10 +1034,14 @@
LWS_VISIBLE int libwebsockets_serve_http_file(
struct libwebsocket_context *context,
struct libwebsocket *wsi, const char *file,
- const char *content_type, const char *other_headers)
+ const char *content_type, const char *other_headers,
+ int other_headers_len)
{
unsigned char *response = context->service_buffer + LWS_SEND_BUFFER_PRE_PADDING;
unsigned char *p = response;
+ unsigned char *end = p + sizeof(context->service_buffer) -
+ LWS_SEND_BUFFER_PRE_PADDING;
+ unsigned char clen[10];
int ret = 0;
int n;
@@ -945,17 +1054,26 @@
return -1;
}
- p += sprintf((char *)p, "HTTP/1.0 200 OK\x0d\x0a"
- "Server: libwebsockets\x0d\x0a"
- "Content-Type: %s\x0d\x0a", content_type);
- if (other_headers) {
- n = strlen(other_headers);
- memcpy(p, other_headers, n);
- p += n;
- }
- p += sprintf((char *)p,
- "Content-Length: %lu\x0d\x0a\x0d\x0a", wsi->u.http.filelen);
+ if (lws_add_http_header_status(context, wsi, 200, &p, end))
+ return 1;
+ if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_SERVER, (unsigned char *)"libwebsockets", 13, &p, end))
+ return 1;
+ if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, (unsigned char *)content_type, strlen(content_type), &p, end))
+ return 1;
+ n = sprintf((char *)clen, "%lu", (unsigned long)wsi->u.http.filelen);
+ if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH, clen, n, &p, end))
+ return 1;
+ if (other_headers) {
+ if ((end - p) < other_headers_len)
+ return -1;
+ memcpy(p, other_headers, other_headers_len);
+ p += other_headers_len;
+ }
+
+ if (lws_finalize_http_header(context, wsi, &p, end))
+ return 1;
+
ret = libwebsocket_write(wsi, response,
p - response, LWS_WRITE_HTTP_HEADERS);
if (ret != (p - response)) {
diff --git a/test-server/test-server.c b/test-server/test-server.c
index 24438d1..d33d2f9 100644
--- a/test-server/test-server.c
+++ b/test-server/test-server.c
@@ -105,61 +105,27 @@
static void
dump_handshake_info(struct libwebsocket *wsi)
{
- int n;
- static const char *token_names[] = {
- /*[WSI_TOKEN_GET_URI] =*/ "GET URI",
- /*[WSI_TOKEN_POST_URI] =*/ "POST URI",
- /*[WSI_TOKEN_OPTIONS_URI] =*/ "options uri",
- /*[WSI_TOKEN_HOST] =*/ "Host",
- /*[WSI_TOKEN_CONNECTION] =*/ "Connection",
- /*[WSI_TOKEN_UPGRADE] =*/ "Upgrade",
- /*[WSI_TOKEN_ORIGIN] =*/ "Origin",
- /*[WSI_TOKEN_DRAFT] =*/ "Draft",
- /*[WSI_TOKEN_CHALLENGE] =*/ "Challenge",
- /* new for 05 */
- /*[WSI_TOKEN_EXTENSIONS] =*/ "Extensions",
- /*[WSI_TOKEN_KEY1] =*/ "key 1",
- /*[WSI_TOKEN_KEY2] =*/ "key 2",
-
- /*[WSI_TOKEN_PROTOCOL] =*/ "Protocol",
-
- /* client receives these */
- /*[WSI_TOKEN_ACCEPT] =*/ "Accept",
- /*[WSI_TOKEN_NONCE] =*/ "Nonce",
- /*[WSI_TOKEN_HTTP] =*/ "Http",
- "http2-settings",
- "Accept:",
- "a-c-request-headers:",
- "If-Modified-Since:",
- "if-none-match:",
- "Accept-Encoding:",
- "Accept-Language:",
- "Pragma:",
- "Cache-Control:",
- "Authorization:",
- "Cookie:",
- "Content-Length:",
- "Content-Type:",
- "Date:",
- "Range:",
- "Referer:",
- /* new for 04 */
- /*[WSI_TOKEN_KEY] =*/ "Key",
- /*[WSI_TOKEN_VERSION] =*/ "Version",
- /*[WSI_TOKEN_SWORIGIN] =*/ "Sworigin",
- "Uri-Args:",
-
- };
+ int n = 0;
char buf[256];
+ const unsigned char *c;
- for (n = 0; n < sizeof(token_names) / sizeof(token_names[0]); n++) {
- if (!lws_hdr_total_length(wsi, n))
+ do {
+ c = lws_token_to_string(n);
+ if (!c) {
+ n++;
continue;
+ }
+
+ if (!lws_hdr_total_length(wsi, n)) {
+ n++;
+ continue;
+ }
lws_hdr_copy(wsi, buf, sizeof buf, n);
- fprintf(stderr, " %s = %s\n", token_names[n], buf);
- }
+ fprintf(stderr, " %s = %s\n", (char *)c, buf);
+ n++;
+ } while (c);
}
const char * get_mimetype(const char *file)
@@ -207,7 +173,7 @@
#ifdef EXTERNAL_POLL
struct libwebsocket_pollargs *pa = (struct libwebsocket_pollargs *)in;
#endif
-
+ unsigned char *end;
switch (reason) {
case LWS_CALLBACK_HTTP:
@@ -240,7 +206,7 @@
/* well, let's demonstrate how to send the hard way */
p = buffer + LWS_SEND_BUFFER_PRE_PADDING;
-
+ end = p + sizeof(buffer) - LWS_SEND_BUFFER_PRE_PADDING;
#ifdef WIN32
pss->fd = open(leaf_path, O_RDONLY | _O_BINARY);
#else
@@ -256,20 +222,33 @@
* we will send a big jpeg file, but it could be
* anything. Set the Content-Type: appropriately
* so the browser knows what to do with it.
+ *
+ * Notice we use the APIs to build the header, which
+ * will do the right thing for HTTP 1/1.1 and HTTP2
+ * depending on what connection it happens to be working
+ * on
*/
-
- p += sprintf((char *)p,
- "HTTP/1.0 200 OK\x0d\x0a"
- "Server: libwebsockets\x0d\x0a"
- "Content-Type: image/jpeg\x0d\x0a"
- "Content-Length: %u\x0d\x0a\x0d\x0a",
- (unsigned int)stat_buf.st_size);
+ if (lws_add_http_header_status(context, wsi, 200, &p, end))
+ return 1;
+ if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_SERVER, (unsigned char *)"libwebsockets", 13, &p, end))
+ return 1;
+ if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, (unsigned char *)"image/jpeg", 10, &p, end))
+ return 1;
+ n = sprintf(b64, "%u", (unsigned int)stat_buf.st_size);
+ if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH, (unsigned char *)b64, n, &p, end))
+ return 1;
+ if (lws_finalize_http_header(context, wsi, &p, end))
+ return 1;
/*
* send the http headers...
* this won't block since it's the first payload sent
* on the connection since it was established
* (too small for partial)
+ *
+ * Notice they are sent using LWS_WRITE_HTTP_HEADERS
+ * which also means you can't send body too in one step,
+ * this is mandated by changes in HTTP2
*/
n = libwebsocket_write(wsi,
@@ -310,23 +289,25 @@
/* demostrates how to set a cookie on / */
other_headers = NULL;
+ n = 0;
if (!strcmp((const char *)in, "/") &&
!lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COOKIE)) {
/* this isn't very unguessable but it'll do for us */
gettimeofday(&tv, NULL);
- sprintf(b64, "LWS_%u_%u_COOKIE",
+ n = sprintf(b64, "test=LWS_%u_%u_COOKIE;Max-Age=360000",
(unsigned int)tv.tv_sec,
(unsigned int)tv.tv_usec);
- sprintf(leaf_path,
- "Set-Cookie: test=LWS_%u_%u_COOKIE;Max-Age=360000\x0d\x0a",
- (unsigned int)tv.tv_sec, (unsigned int)tv.tv_usec);
+ p = (unsigned char *)leaf_path;
+
+ if (lws_add_http_header_by_name(context, wsi, (unsigned char *)"set-cookie:", (unsigned char *)b64, n, &p, (unsigned char *)leaf_path + sizeof(leaf_path)))
+ return 1;
+ n = (char *)p - leaf_path;
other_headers = leaf_path;
- lwsl_err(other_headers);
}
if (libwebsockets_serve_http_file(context, wsi, buf,
- mimetype, other_headers))
+ mimetype, other_headers, n))
return -1; /* through completion or error, close the socket */
/*