13 static uint32_t usual[] = {
36 #if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED)
38 #define ngx_str3_cmp(m, c0, c1, c2, c3) \
39 *(uint32_t *) m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0)
41 #define ngx_str3Ocmp(m, c0, c1, c2, c3) \
42 *(uint32_t *) m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0)
44 #define ngx_str4cmp(m, c0, c1, c2, c3) \
45 *(uint32_t *) m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0)
47 #define ngx_str5cmp(m, c0, c1, c2, c3, c4) \
48 *(uint32_t *) m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0) \
51 #define ngx_str6cmp(m, c0, c1, c2, c3, c4, c5) \
52 *(uint32_t *) m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0) \
53 && (((uint32_t *) m)[1] & 0xffff) == ((c5 << 8) | c4)
55 #define ngx_str7_cmp(m, c0, c1, c2, c3, c4, c5, c6, c7) \
56 *(uint32_t *) m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0) \
57 && ((uint32_t *) m)[1] == ((c7 << 24) | (c6 << 16) | (c5 << 8) | c4)
59 #define ngx_str8cmp(m, c0, c1, c2, c3, c4, c5, c6, c7) \
60 *(uint32_t *) m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0) \
61 && ((uint32_t *) m)[1] == ((c7 << 24) | (c6 << 16) | (c5 << 8) | c4)
63 #define ngx_str9cmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8) \
64 *(uint32_t *) m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0) \
65 && ((uint32_t *) m)[1] == ((c7 << 24) | (c6 << 16) | (c5 << 8) | c4) \
70 #define ngx_str3_cmp(m, c0, c1, c2, c3) \
71 m[0] == c0 && m[1] == c1 && m[2] == c2
73 #define ngx_str3Ocmp(m, c0, c1, c2, c3) \
74 m[0] == c0 && m[2] == c2 && m[3] == c3
76 #define ngx_str4cmp(m, c0, c1, c2, c3) \
77 m[0] == c0 && m[1] == c1 && m[2] == c2 && m[3] == c3
79 #define ngx_str5cmp(m, c0, c1, c2, c3, c4) \
80 m[0] == c0 && m[1] == c1 && m[2] == c2 && m[3] == c3 && m[4] == c4
82 #define ngx_str6cmp(m, c0, c1, c2, c3, c4, c5) \
83 m[0] == c0 && m[1] == c1 && m[2] == c2 && m[3] == c3 \
84 && m[4] == c4 && m[5] == c5
86 #define ngx_str7_cmp(m, c0, c1, c2, c3, c4, c5, c6, c7) \
87 m[0] == c0 && m[1] == c1 && m[2] == c2 && m[3] == c3 \
88 && m[4] == c4 && m[5] == c5 && m[6] == c6
90 #define ngx_str8cmp(m, c0, c1, c2, c3, c4, c5, c6, c7) \
91 m[0] == c0 && m[1] == c1 && m[2] == c2 && m[3] == c3 \
92 && m[4] == c4 && m[5] == c5 && m[6] == c6 && m[7] == c7
94 #define ngx_str9cmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8) \
95 m[0] == c0 && m[1] == c1 && m[2] == c2 && m[3] == c3 \
96 && m[4] == c4 && m[5] == c5 && m[6] == c6 && m[7] == c7 && m[8] == c8
106 u_char c, ch, *p, *m;
110 sw_spaces_before_uri,
113 sw_schema_slash_slash,
120 sw_after_slash_in_uri,
122 sw_check_uri_http_09,
129 sw_first_major_digit,
131 sw_first_minor_digit,
133 sw_spaces_after_digit,
139 for (p = b->
pos; p < b->last; p++) {
148 if (ch ==
CR || ch ==
LF) {
152 if ((ch < 'A' || ch >
'Z') && ch !=
'_') {
228 if (
ngx_str6cmp(m,
'D',
'E',
'L',
'E',
'T',
'E')) {
233 if (
ngx_str6cmp(m,
'U',
'N',
'L',
'O',
'C',
'K')) {
241 if (
ngx_str7_cmp(m,
'O',
'P',
'T',
'I',
'O',
'N',
'S',
' '))
249 if (
ngx_str8cmp(m,
'P',
'R',
'O',
'P',
'F',
'I',
'N',
'D'))
258 'P',
'R',
'O',
'P',
'P',
'A',
'T',
'C',
'H'))
266 state = sw_spaces_before_uri;
270 if ((ch < 'A' || ch >
'Z') && ch !=
'_') {
277 case sw_spaces_before_uri:
281 state = sw_after_slash_in_uri;
285 c = (u_char) (ch | 0x20);
286 if (c >=
'a' && c <=
'z') {
302 c = (u_char) (ch | 0x20);
303 if (c >=
'a' && c <=
'z') {
310 state = sw_schema_slash;
317 case sw_schema_slash:
320 state = sw_schema_slash_slash;
327 case sw_schema_slash_slash:
330 state = sw_host_start;
342 state = sw_host_ip_literal;
352 c = (u_char) (ch | 0x20);
353 if (c >=
'a' && c <=
'z') {
357 if ((ch >=
'0' && ch <=
'9') || ch ==
'.' || ch ==
'-') {
373 state = sw_after_slash_in_uri;
382 state = sw_host_http_09;
389 case sw_host_ip_literal:
391 if (ch >=
'0' && ch <=
'9') {
395 c = (u_char) (ch | 0x20);
396 if (c >=
'a' && c <=
'z') {
431 if (ch >=
'0' && ch <=
'9') {
439 state = sw_after_slash_in_uri;
449 state = sw_host_http_09;
457 case sw_host_http_09:
463 state = sw_almost_done;
479 case sw_after_slash_in_uri:
481 if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
482 state = sw_check_uri;
489 state = sw_check_uri_http_09;
494 state = sw_almost_done;
532 state = sw_check_uri;
540 if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
554 state = sw_after_slash_in_uri;
561 state = sw_check_uri_http_09;
566 state = sw_almost_done;
575 state = sw_after_slash_in_uri;
599 case sw_check_uri_http_09:
605 state = sw_almost_done;
616 state = sw_check_uri;
625 if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
637 state = sw_almost_done;
658 state = sw_almost_done;
697 state = sw_http_HTTP;
707 state = sw_first_major_digit;
715 case sw_first_major_digit:
716 if (ch < '1' || ch >
'9') {
721 state = sw_major_digit;
727 state = sw_first_minor_digit;
731 if (ch < '0' || ch >
'9') {
739 case sw_first_minor_digit:
740 if (ch < '0' || ch >
'9') {
745 state = sw_minor_digit;
751 state = sw_almost_done;
760 state = sw_spaces_after_digit;
764 if (ch < '0' || ch >
'9') {
771 case sw_spaces_after_digit:
776 state = sw_almost_done;
830 sw_space_before_value,
832 sw_space_after_value,
835 sw_header_almost_done
840 static u_char lowcase[] =
841 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
842 "\0\0\0\0\0\0\0\0\0\0\0\0\0-\0\0" "0123456789\0\0\0\0\0\0"
843 "\0abcdefghijklmnopqrstuvwxyz\0\0\0\0\0"
844 "\0abcdefghijklmnopqrstuvwxyz\0\0\0\0\0"
845 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
846 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
847 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
848 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
854 for (p = b->
pos; p < b->last; p++) {
867 state = sw_header_almost_done;
907 if (allow_underscores) {
921 state = sw_space_before_value;
929 state = sw_almost_done;
946 state = sw_ignore_line;
959 case sw_space_before_value:
966 state = sw_almost_done;
986 state = sw_space_after_value;
990 state = sw_almost_done;
1001 case sw_space_after_value:
1006 state = sw_almost_done;
1019 case sw_ignore_line:
1030 case sw_almost_done:
1042 case sw_header_almost_done:
1062 r->
state = sw_start;
1071 r->
state = sw_start;
1083 sw_after_slash_in_uri,
1102 state = sw_after_slash_in_uri;
1106 case sw_after_slash_in_uri:
1108 if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
1109 state = sw_check_uri;
1116 state = sw_check_uri;
1148 state = sw_check_uri;
1156 if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
1170 state = sw_after_slash_in_uri;
1181 state = sw_after_slash_in_uri;
1205 if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
1228 u_char c, ch, decoded, *p, *u;
1236 } state, quoted_state;
1238 #if (NGX_SUPPRESS_WARN)
1240 quoted_state = sw_usual;
1251 while (p <= r->uri_end) {
1260 "s:%d in:'%Xd:%c', out:'%c'", state, ch, ch, *u);
1266 if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
1276 && *(u - 1) ==
'.' && *(u - 2) !=
'.')
1300 && *(u - 1) ==
'.' && *(u - 2) !=
'.')
1310 quoted_state = state;
1335 if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
1348 if (!merge_slashes) {
1357 quoted_state = state;
1378 if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
1398 quoted_state = state;
1419 if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
1434 if (u < r->uri.data) {
1445 quoted_state = state;
1467 if (ch >=
'0' && ch <=
'9') {
1468 decoded = (u_char) (ch -
'0');
1469 state = sw_quoted_second;
1474 c = (u_char) (ch | 0x20);
1475 if (c >=
'a' && c <=
'f') {
1476 decoded = (u_char) (c -
'a' + 10);
1477 state = sw_quoted_second;
1484 case sw_quoted_second:
1485 if (ch >=
'0' && ch <=
'9') {
1486 ch = (u_char) ((decoded << 4) + ch -
'0');
1488 if (ch ==
'%' || ch ==
'#') {
1494 }
else if (ch ==
'\0') {
1498 state = quoted_state;
1502 c = (u_char) (ch | 0x20);
1503 if (c >=
'a' && c <=
'f') {
1504 ch = (u_char) ((decoded << 4) + c -
'a' + 10);
1512 }
else if (ch ==
'+') {
1516 state = quoted_state;
1539 while (p < r->uri_end) {
1576 sw_first_major_digit,
1578 sw_first_minor_digit,
1581 sw_space_after_status,
1588 for (p = b->
pos; p < b->last; p++) {
1637 state = sw_first_major_digit;
1645 case sw_first_major_digit:
1646 if (ch < '1' || ch >
'9') {
1651 state = sw_major_digit;
1655 case sw_major_digit:
1657 state = sw_first_minor_digit;
1661 if (ch < '0' || ch >
'9') {
1669 case sw_first_minor_digit:
1670 if (ch < '0' || ch >
'9') {
1675 state = sw_minor_digit;
1679 case sw_minor_digit:
1685 if (ch < '0' || ch >
'9') {
1698 if (ch < '0' || ch >
'9') {
1702 status->
code = status->
code * 10 + ch -
'0';
1704 if (++status->
count == 3) {
1705 state = sw_space_after_status;
1706 status->
start = p - 2;
1712 case sw_space_after_status:
1715 state = sw_status_text;
1718 state = sw_status_text;
1721 state = sw_almost_done;
1731 case sw_status_text:
1734 state = sw_almost_done;
1743 case sw_almost_done:
1744 status->
end = p - 1;
1763 if (status->
end == NULL) {
1768 r->
state = sw_start;
1784 if (len == 0 || p[0] ==
'?') {
1792 for ( ; len; len--) {
1796 if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
1801 args->
len = len - 1;
1828 "unsafe URI \"%V\" was detected", uri);
1840 u_char *start, *last, *end, ch;
1845 for (i = 0; i < headers->
nelts; i++) {
1848 "parse header: \"%V: %V\"", &h[i]->
key, &h[i]->
value);
1857 while (start < end) {
1863 for (start += name->
len; start < end && *start ==
' '; start++) {
1867 if (value == NULL) {
1868 if (start == end || *start ==
',') {
1875 if (start == end || *start++ !=
'=') {
1880 while (start < end && *start ==
' ') { start++; }
1882 for (last = start; last < end && *last !=
';'; last++) {
1886 value->
len = last - start;
1887 value->
data = start;
1893 while (start < end) {
1895 if (ch ==
';' || ch ==
',') {
1900 while (start < end && *start ==
' ') { start++; }
1920 for ( ; p < last; p++) {
1930 if ((p == r->
args.
data || *(p - 1) ==
'&') && *(p + len) ==
'=') {
1932 value->
data = p + len + 1;
1934 p = ngx_strlchr(p, last,
'&');
1957 p = ngx_strlchr(uri->
data, last,
'?');
1962 args->
len = last - p;
1981 sw_chunk_extension_almost_done,
1984 sw_after_data_almost_done,
1985 sw_last_chunk_extension,
1986 sw_last_chunk_extension_almost_done,
1988 sw_trailer_almost_done,
1990 sw_trailer_header_almost_done
1995 if (state == sw_chunk_data && ctx->
size == 0) {
1996 state = sw_after_data;
2001 for (pos = b->
pos; pos < b->last; pos++) {
2006 "http chunked byte: %02Xd s:%d", ch, state);
2010 case sw_chunk_start:
2011 if (ch >=
'0' && ch <=
'9') {
2012 state = sw_chunk_size;
2013 ctx->
size = ch -
'0';
2017 c = (u_char) (ch | 0x20);
2019 if (c >=
'a' && c <=
'f') {
2020 state = sw_chunk_size;
2021 ctx->
size = c -
'a' + 10;
2028 if (ch >=
'0' && ch <=
'9') {
2029 ctx->
size = ctx->
size * 16 + (ch -
'0');
2033 c = (u_char) (ch | 0x20);
2035 if (c >=
'a' && c <=
'f') {
2036 ctx->
size = ctx->
size * 16 + (c -
'a' + 10);
2040 if (ctx->
size == 0) {
2044 state = sw_last_chunk_extension_almost_done;
2052 state = sw_last_chunk_extension;
2063 state = sw_chunk_extension_almost_done;
2066 state = sw_chunk_data;
2071 state = sw_chunk_extension;
2079 case sw_chunk_extension:
2082 state = sw_chunk_extension_almost_done;
2085 state = sw_chunk_data;
2089 case sw_chunk_extension_almost_done:
2091 state = sw_chunk_data;
2103 state = sw_after_data_almost_done;
2106 state = sw_chunk_start;
2110 case sw_after_data_almost_done:
2112 state = sw_chunk_start;
2117 case sw_last_chunk_extension:
2120 state = sw_last_chunk_extension_almost_done;
2127 case sw_last_chunk_extension_almost_done:
2137 state = sw_trailer_almost_done;
2142 state = sw_trailer_header;
2146 case sw_trailer_almost_done:
2152 case sw_trailer_header:
2155 state = sw_trailer_header_almost_done;
2162 case sw_trailer_header_almost_done:
2179 case sw_chunk_start:
2186 case sw_chunk_extension:
2187 case sw_chunk_extension_almost_done:
2194 case sw_after_data_almost_done:
2197 case sw_last_chunk_extension:
2198 case sw_last_chunk_extension_almost_done:
2202 case sw_trailer_almost_done:
2205 case sw_trailer_header:
2206 case sw_trailer_header_almost_done: