ext/kcar/kcar.c in kcar-0.6.0 vs ext/kcar/kcar.c in kcar-0.7.0
- old
+ new
@@ -10,14 +10,24 @@
#include "ext_help.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
+#include <limits.h>
#include "c_util.h"
static VALUE eParserError;
-static ID id_sq, id_sq_set;
+static ID id_uminus, id_sq, id_sq_set;
+static VALUE g_rack_url_scheme,
+ g_80, g_443, g_http, g_https,
+ g_HTTP_HOST, g_HTTP_CONNECTION, g_HTTP_TRAILER, g_HTTP_TRANSFER_ENCODING,
+ g_HTTP_VERSION,
+ g_CONTENT_LENGTH, g_CONTENT_TYPE, g_FRAGMENT,
+ g_PATH_INFO, g_QUERY_STRING,
+ g_REQUEST_METHOD, g_REQUEST_PATH, g_REQUEST_URI,
+ g_SERVER_NAME, g_SERVER_PORT, g_SERVER_PROTOCOL;
+static VALUE e413, e414;
/** Defines common length and error messages for input length validation. */
#define DEF_MAX_LENGTH(N, length) \
static const size_t MAX_##N##_LENGTH = length; \
static const char MAX_##N##_LENGTH_ERR[] = \
@@ -30,75 +40,180 @@
#define VALIDATE_MAX_LENGTH(len, N) do { \
if (len > MAX_##N##_LENGTH) \
rb_raise(eParserError, MAX_##N##_LENGTH_ERR); \
} while (0)
+#define VALIDATE_MAX_URI_LENGTH(len, N) do { \
+ if (len > MAX_##N##_LENGTH) \
+ rb_raise(e414, MAX_##N##_LENGTH_ERR); \
+} while (0)
+
/* Defines the maximum allowed lengths for various input elements.*/
DEF_MAX_LENGTH(FIELD_NAME, 256);
DEF_MAX_LENGTH(FIELD_VALUE, 80 * 1024);
DEF_MAX_LENGTH(HEADER, (1024 * (80 + 32)));
+DEF_MAX_LENGTH(REQUEST_URI, 1024 * 15);
+DEF_MAX_LENGTH(REQUEST_PATH, 4096); /* common PATH_MAX on modern systems */
+DEF_MAX_LENGTH(QUERY_STRING, (1024 * 10));
-#define UH_FL_CHUNKED 0x1
-#define UH_FL_HASBODY 0x2
-#define UH_FL_INBODY 0x4
-#define UH_FL_HASTRAILER 0x8
-#define UH_FL_INTRAILER 0x10
-#define UH_FL_INCHUNK 0x20
-#define UH_FL_KEEPALIVE 0x40
-#define UH_FL_HASHEADER 0x80
-
struct http_parser {
int cs; /* Ragel internal state */
- unsigned int flags;
- size_t mark;
- size_t offset;
+ unsigned int is_request:1;
+ unsigned int has_query:1;
+ unsigned int has_scheme:1;
+ unsigned int chunked:1;
+ unsigned int has_body:1;
+ unsigned int in_body:1;
+ unsigned int has_trailer:1;
+ unsigned int in_trailer:1;
+ unsigned int in_chunk:1;
+ unsigned int persistent:1;
+ unsigned int has_header:1;
+ unsigned int body_eof_seen:1;
+ unsigned int is_https:1;
+ unsigned int padding:19;
+ unsigned int mark;
+ unsigned int offset;
union { /* these 2 fields don't nest */
- size_t field;
- size_t query;
+ unsigned int field;
+ unsigned int query;
} start;
union {
- size_t field_len; /* only used during header processing */
- size_t dest_offset; /* only used during body processing */
+ unsigned int field_len; /* only used during header processing */
+ unsigned int dest_offset; /* only used during body processing */
} s;
VALUE cont; /* Qfalse: unset, Qnil: ignored header, T_STRING: append */
- VALUE status; /* String or Qnil */
union {
+ /* String or Qnil */
+ VALUE status; /* status string for responses */
+ VALUE host; /* Host: header for requests */
+ } v;
+ union {
off_t content;
off_t chunk;
} len;
};
+static unsigned int ulong2uint(unsigned long n)
+{
+ unsigned int i = (unsigned int)n;
+
+ if (sizeof(unsigned int) != sizeof(unsigned long)) {
+ if ((unsigned long)i != n) {
+ rb_raise(rb_eRangeError, "too large to be 32-bit uint: %lu", n);
+ }
+ }
+ return i;
+}
+
#define REMAINING (unsigned long)(pe - p)
-#define LEN(AT, FPC) (FPC - buffer - hp->AT)
-#define MARK(M,FPC) (hp->M = (FPC) - buffer)
+#define LEN(AT, FPC) (ulong2uint(FPC - buffer) - hp->AT)
+#define MARK(M,FPC) (hp->M = ulong2uint((FPC) - buffer))
#define PTR_TO(F) (buffer + hp->F)
#define STR_NEW(M,FPC) rb_str_new(PTR_TO(M), LEN(M, FPC))
#define STRIPPED_STR_NEW(M,FPC) stripped_str_new(PTR_TO(M), LEN(M, FPC))
-#define HP_FL_TEST(hp,fl) ((hp)->flags & (UH_FL_##fl))
-#define HP_FL_SET(hp,fl) ((hp)->flags |= (UH_FL_##fl))
-#define HP_FL_UNSET(hp,fl) ((hp)->flags &= ~(UH_FL_##fl))
-#define HP_FL_ALL(hp,fl) (HP_FL_TEST(hp, fl) == (UH_FL_##fl))
+/* Downcases a single ASCII character. Locale-agnostic. */
+static void downcase_char(char *c)
+{
+ if (*c >= 'A' && *c <= 'Z')
+ *c |= 0x20;
+}
static int is_lws(char c)
{
return (c == ' ' || c == '\t');
}
+/* this will dedupe under Ruby 2.5+ (December 2017) */
+static VALUE str_dd_freeze(VALUE str)
+{
+ if (STR_UMINUS_DEDUPE)
+ return rb_funcall(str, id_uminus, 0);
+
+ /* freeze,since it speeds up MRI slightly */
+ OBJ_FREEZE(str);
+ return str;
+}
+
+static VALUE str_new_dd_freeze(const char *ptr, long len)
+{
+ return str_dd_freeze(rb_str_new(ptr, len));
+}
+
static VALUE stripped_str_new(const char *str, long len)
{
long end;
for (end = len - 1; end >= 0 && is_lws(str[end]); end--);
return rb_str_new(str, end + 1);
}
-static void finalize_header(struct http_parser *hp)
+static VALUE request_host_val(struct http_parser *hp)
{
- if ((HP_FL_TEST(hp, HASTRAILER) && ! HP_FL_TEST(hp, CHUNKED)))
+ assert(hp->is_request == 1 && "not a request");
+ return NIL_P(hp->v.host) ? Qfalse : hp->v.host;
+}
+
+static void set_server_vars(struct http_parser *hp, VALUE env, VALUE host)
+{
+ char *host_ptr = RSTRING_PTR(host);
+ long host_len = RSTRING_LEN(host);
+ char *colon;
+ VALUE server_name = host;
+ VALUE server_port = hp->has_scheme ? (hp->is_https ? g_443 : g_80) : Qfalse;
+
+ if (*host_ptr == '[') { /* ipv6 address format */
+ char *rbracket = memchr(host_ptr + 1, ']', host_len - 1);
+
+ if (rbracket)
+ colon = (rbracket[1] == ':') ? rbracket + 1 : NULL;
+ else
+ colon = memchr(host_ptr + 1, ':', host_len - 1);
+ } else {
+ colon = memchr(host_ptr, ':', host_len);
+ }
+
+ if (colon) {
+ long port_start = colon - host_ptr + 1;
+ long port_len = host_len - port_start;
+
+ server_name = rb_str_substr(host, 0, colon - host_ptr);
+ server_name = str_dd_freeze(server_name);
+ if (port_len > 0) {
+ server_port = rb_str_substr(host, port_start, port_len);
+ server_port = str_dd_freeze(server_port);
+ }
+ }
+ rb_hash_aset(env, g_SERVER_NAME, server_name);
+ if (server_port != Qfalse)
+ rb_hash_aset(env, g_SERVER_PORT, server_port);
+}
+
+static void finalize_header(struct http_parser *hp, VALUE hdr)
+{
+ if (hp->has_trailer && !hp->chunked)
rb_raise(eParserError, "trailer but not chunked");
+ if (hp->is_request) {
+ if (hp->chunked) {
+ if (hp->len.chunk >= 0)
+ rb_raise(eParserError, "Content-Length set with chunked encoding");
+ else
+ hp->len.chunk = 0;
+ } else if (hp->len.content < 0) {
+ hp->len.content = 0;
+ }
+
+ if (!hp->has_query)
+ rb_hash_aset(hdr, g_QUERY_STRING, rb_str_new(NULL, 0));
+ if (hp->has_header) {
+ VALUE host = request_host_val(hp);
+ if (host != Qfalse)
+ set_server_vars(hp, hdr, host);
+ }
+ }
}
/*
* handles values of the "Connection:" header, keepalive is implied
* for HTTP/1.1 but needs to be explicitly enabled with HTTP/1.0
@@ -107,55 +222,143 @@
static void hp_keepalive_connection(struct http_parser *hp, VALUE val)
{
/* REQUEST_METHOD is always set before any headers */
if (STR_CSTR_CASE_EQ(val, "keep-alive")) {
/* basically have HTTP/1.0 masquerade as HTTP/1.1+ */
- HP_FL_SET(hp, KEEPALIVE);
+ hp->persistent = 1;
} else if (STR_CSTR_CASE_EQ(val, "close")) {
/*
* it doesn't matter what HTTP version or request method we have,
* if a server says "Connection: close", we disable keepalive
*/
- HP_FL_UNSET(hp, KEEPALIVE);
+ hp->persistent = 0;
} else {
/*
* server could've sent anything, ignore it for now. Maybe
- * "HP_FL_UNSET(hp, KEEPALIVE);" just in case?
+ * "hp->persistent = 0;" just in case?
* Raising an exception might be too mean...
*/
}
}
static void
-http_version(struct http_parser *hp, VALUE hdr, const char *ptr, size_t len)
+request_method(VALUE env, const char *ptr, size_t len)
{
+ rb_hash_aset(env, g_REQUEST_METHOD, str_new_dd_freeze(ptr, len));
+}
+
+static void
+url_scheme(struct http_parser *hp, VALUE env, const char *ptr, size_t len)
+{
+ VALUE val;
+
+ hp->has_scheme = 1;
+ /* Ragel machine downcases and enforces this as "http" or "https" */
+ if (len == 5) {
+ hp->is_https = 1;
+ assert(CONST_MEM_EQ("https", ptr, len) && "len == 5 but not 'https'");
+ val = g_https;
+ } else {
+ assert(CONST_MEM_EQ("http", ptr, len) && "len != 4 but not 'http'");
+ val = g_http;
+ }
+ rb_hash_aset(env, g_rack_url_scheme, val);
+}
+
+static void
+request_host(struct http_parser *hp, VALUE env, const char *ptr, size_t len)
+{
+ VALUE val = rb_str_new(ptr, len);
+
+ rb_hash_aset(env, g_HTTP_HOST, val);
+ hp->v.host = val;
+}
+
+static void
+set_fragment(VALUE env, const char *ptr, size_t len)
+{
+ VALUE val = rb_str_new(ptr, len);
+ rb_hash_aset(env, g_FRAGMENT, val);
+}
+
+static void
+request_uri(VALUE env, const char *ptr, size_t len)
+{
+ VALUE val;
+
+ VALIDATE_MAX_URI_LENGTH(len, REQUEST_URI);
+ val = rb_str_new(ptr, len);
+ rb_hash_aset(env, g_REQUEST_URI, val);
+
+ /*
+ * rack says PATH_INFO must start with "/" or be empty,
+ * but "OPTIONS *" is a valid request
+ */
+ if (CONST_MEM_EQ("*", ptr, len)) {
+ val = rb_str_new(NULL, 0);
+ rb_hash_aset(env, g_PATH_INFO, val);
+ rb_hash_aset(env, g_REQUEST_PATH, val);
+ }
+}
+
+static void
+query_string(struct http_parser *hp, VALUE env, const char *ptr, size_t len)
+{
+ VALIDATE_MAX_URI_LENGTH(len, QUERY_STRING);
+
+ hp->has_query = 1;
+ rb_hash_aset(env, g_QUERY_STRING, rb_str_new(ptr, len));
+}
+
+static void
+request_path(VALUE env, const char *ptr, size_t len)
+{
+ VALUE val;
+
+ VALIDATE_MAX_URI_LENGTH(len, REQUEST_PATH);
+ val = rb_str_new(ptr, len);
+
+ rb_hash_aset(env, g_REQUEST_PATH, val);
+ rb_hash_aset(env, g_PATH_INFO, val);
+}
+
+static void
+http_version(struct http_parser *hp, VALUE env, const char *ptr, size_t len)
+{
if (CONST_MEM_EQ("HTTP/1.1", ptr, len)) {
/* HTTP/1.1 implies keepalive unless "Connection: close" is set */
- HP_FL_SET(hp, KEEPALIVE);
+ hp->persistent = 1;
}
+ if (hp->is_request) {
+ VALUE v = str_new_dd_freeze(ptr, len);
+ hp->has_header = 1;
+
+ rb_hash_aset(env, g_SERVER_PROTOCOL, v);
+ rb_hash_aset(env, g_HTTP_VERSION, v);
+ }
}
static void
status_phrase(struct http_parser *hp, VALUE hdr, const char *ptr, size_t len)
{
long nr;
- hp->status = rb_str_new(ptr, len);
+ hp->v.status = str_new_dd_freeze(ptr, len);
/* RSTRING_PTR is null terminated, ptr is not */
- nr = strtol(RSTRING_PTR(hp->status), NULL, 10);
+ nr = strtol(RSTRING_PTR(hp->v.status), NULL, 10);
if (nr < 100 || nr > 999)
- rb_raise(eParserError, "invalid status: %s", RSTRING_PTR(hp->status));
+ rb_raise(eParserError, "invalid status: %s", RSTRING_PTR(hp->v.status));
if ( !((nr >= 100 && nr <= 199) || nr == 204 || nr == 304) )
- HP_FL_SET(hp, HASBODY);
+ hp->has_body = 1;
}
static inline void invalid_if_trailer(struct http_parser *hp)
{
- if (HP_FL_TEST(hp, INTRAILER))
+ if (hp->in_trailer)
rb_raise(eParserError, "invalid Trailer");
}
static void write_cont_value(struct http_parser *hp,
char *buffer, const char *p)
@@ -185,28 +388,28 @@
vptr = PTR_TO(mark);
/* normalize tab to space */
if (cont_len > 0) {
- assert((' ' == *vptr || '\t' == *vptr) && "invalid leading white space");
+ assert(is_lws(*vptr) && "invalid leading white space");
*vptr = ' ';
}
for (end = len - 1; end >= 0 && is_lws(vptr[end]); end--);
rb_str_buf_cat(hp->cont, vptr, end + 1);
}
-static void write_value(VALUE hdr, struct http_parser *hp,
- const char *buffer, const char *p)
+static void write_response_value(struct http_parser *hp, VALUE hdr,
+ const char *buffer, const char *p)
{
VALUE f, v;
VALUE hclass;
const char *fptr = PTR_TO(start.field);
size_t flen = hp->s.field_len;
const char *vptr;
size_t vlen;
- HP_FL_SET(hp, HASHEADER);
+ hp->has_header = 1;
/* Rack does not like Status headers, so we never send them */
if (CSTR_CASE_EQ(fptr, flen, "status")) {
hp->cont = Qnil;
return;
@@ -214,11 +417,11 @@
vptr = PTR_TO(mark);
vlen = LEN(mark, p);
VALIDATE_MAX_LENGTH(vlen, FIELD_VALUE);
VALIDATE_MAX_LENGTH(flen, FIELD_NAME);
- f = rb_str_new(fptr, (long)flen);
+ f = str_new_dd_freeze(fptr, (long)flen);
v = stripped_str_new(vptr, (long)vlen);
/* needs more tests for error-checking here */
/*
* TODO:
@@ -226,38 +429,38 @@
* report real-world examples as we find them:
*/
if (STR_CSTR_CASE_EQ(f, "connection")) {
hp_keepalive_connection(hp, v);
} else if (STR_CSTR_CASE_EQ(f, "content-length")) {
- if (! HP_FL_TEST(hp, HASBODY))
+ if (!hp->has_body)
rb_raise(eParserError, "Content-Length with no body expected");
- if (HP_FL_TEST(hp, CHUNKED))
+ if (hp->chunked)
rb_raise(eParserError,
"Content-Length when chunked Transfer-Encoding is set");
hp->len.content = parse_length(vptr, vlen);
if (hp->len.content < 0)
rb_raise(eParserError, "invalid Content-Length");
invalid_if_trailer(hp);
} else if (STR_CSTR_CASE_EQ(f, "transfer-encoding")) {
if (STR_CSTR_CASE_EQ(v, "chunked")) {
- if (! HP_FL_TEST(hp, HASBODY))
+ if (!hp->has_body)
rb_raise(eParserError,
"chunked Transfer-Encoding with no body expected");
if (hp->len.content >= 0)
rb_raise(eParserError,
"chunked Transfer-Encoding when Content-Length is set");
hp->len.chunk = 0;
- HP_FL_SET(hp, CHUNKED);
+ hp->chunked = 1;
}
invalid_if_trailer(hp);
} else if (STR_CSTR_CASE_EQ(f, "trailer")) {
- if (! HP_FL_TEST(hp, HASBODY))
+ if (!hp->has_body)
rb_raise(eParserError, "trailer with no body");
- HP_FL_SET(hp, HASTRAILER);
+ hp->has_trailer = 1;
invalid_if_trailer(hp);
}
hclass = CLASS_OF(hdr);
if (hclass == rb_cArray) {
@@ -272,13 +475,10 @@
e = rb_hash_aref(hdr, f);
else
e = rb_funcall(hdr, id_sq, 1, f);
if (NIL_P(e)) {
- /* new value, freeze it since it speeds up MRI slightly */
- OBJ_FREEZE(f);
-
if (hclass == rb_cHash)
rb_hash_aset(hdr, f, v);
else
rb_funcall(hdr, id_sq_set, 2, f, v);
@@ -295,45 +495,151 @@
hp->cont = rb_str_buf_append(e, v);
}
}
}
+static VALUE req_field(const char *ptr, size_t len)
+{
+ size_t pfxlen = sizeof("HTTP_") - 1;
+ VALUE str = rb_str_new(NULL, pfxlen + len);
+ char *dst = RSTRING_PTR(str);
+
+ memcpy(dst, "HTTP_", pfxlen);
+ memcpy(dst + pfxlen, ptr, len);
+ assert(*(dst + RSTRING_LEN(str)) == '\0' &&
+ "string didn't end with \\0"); /* paranoia */
+
+ return str;
+}
+
+static void snake_upcase(char *ptr, size_t len)
+{
+ char *c;
+
+ for (c = ptr; len--; c++) {
+ if (*c >= 'a' && *c <= 'z')
+ *c &= ~0x20;
+ else if (*c == '-')
+ *c = '_';
+ }
+}
+
+static void write_request_value(struct http_parser *hp, VALUE env,
+ char *buffer, const char *p)
+{
+ char *fptr = PTR_TO(start.field);
+ size_t flen = hp->s.field_len;
+ char *vptr = PTR_TO(mark);
+ size_t vlen = LEN(mark, p);
+ VALUE key, val;
+ VALUE existing;
+
+ VALIDATE_MAX_LENGTH(flen, FIELD_NAME);
+ VALIDATE_MAX_LENGTH(LEN(mark, p), FIELD_VALUE);
+ snake_upcase(fptr, flen);
+
+ /*
+ * ignore "Version" headers since they conflict with the HTTP_VERSION
+ * rack env variable.
+ */
+ if (CONST_MEM_EQ("VERSION", fptr, flen)) {
+ hp->cont = Qnil;
+ return;
+ }
+ val = vlen == 0 ? rb_str_new(0, 0) : stripped_str_new(vptr, vlen);
+
+ if (CONST_MEM_EQ("CONNECTION", fptr, flen)) {
+ key = g_HTTP_CONNECTION;
+ hp_keepalive_connection(hp, val);
+ } else if (CONST_MEM_EQ("CONTENT_LENGTH", fptr, flen)) {
+ key = g_CONTENT_LENGTH;
+ hp->len.content = parse_length(vptr, vlen);
+ if (hp->len.content < 0)
+ rb_raise(eParserError, "invalid Content-Length");
+ if (hp->len.content != 0)
+ hp->has_body = 1;
+ invalid_if_trailer(hp);
+ } else if (CONST_MEM_EQ("CONTENT_TYPE", fptr, flen)) {
+ key = g_CONTENT_TYPE;
+ } else if (CONST_MEM_EQ("TRANSFER_ENCODING", fptr, flen)) {
+ key = g_HTTP_TRANSFER_ENCODING;
+ if (STR_CSTR_CASE_EQ(val, "chunked")) {
+ hp->chunked = 1;
+ hp->has_body = 1;
+ }
+ invalid_if_trailer(hp);
+ } else if (CONST_MEM_EQ("TRAILER", fptr, flen)) {
+ key = g_HTTP_TRAILER;
+ hp->has_trailer = 1;
+ invalid_if_trailer(hp);
+ } else if (CONST_MEM_EQ("HOST", fptr, flen)) {
+ key = g_HTTP_HOST;
+ if (NIL_P(hp->v.host))
+ hp->v.host = val;
+ } else {
+ key = req_field(fptr, flen);
+ if (!HASH_ASET_DEDUPE)
+ key = str_dd_freeze(key);
+ }
+ existing = rb_hash_aref(env, key);
+ if (NIL_P(existing)) {
+ hp->cont = rb_hash_aset(env, key, val);
+ /*
+ * Ignore repeated Host headers and favor host set by absolute URIs.
+ * absoluteURI Request-URI takes precedence over
+ * the Host: header (ref: rfc 2616, section 5.2.1)
+ */
+ } else if (key == g_HTTP_HOST) {
+ hp->cont = Qnil;
+ } else {
+ rb_str_buf_cat(existing, ",", 1);
+ hp->cont = rb_str_buf_append(existing, val);
+ }
+}
+
+static void write_value(struct http_parser *hp, VALUE hdr,
+ char *buf, const char *p)
+{
+ hp->is_request ? write_request_value(hp, hdr, buf, p) :
+ write_response_value(hp, hdr, buf, p);
+}
+
/** Machine **/
-#line 363 "kcar.rl"
+#line 681 "kcar.rl"
/** Data **/
-#line 309 "kcar.c"
+#line 615 "kcar.c"
static const int http_parser_start = 1;
-static const int http_parser_first_final = 44;
+static const int http_parser_first_final = 134;
static const int http_parser_error = 0;
-static const int http_parser_en_ChunkedBody = 22;
-static const int http_parser_en_ChunkedBody_chunk_chunk_end = 27;
-static const int http_parser_en_Trailers = 36;
+static const int http_parser_en_ChunkedBody = 112;
+static const int http_parser_en_ChunkedBody_chunk_chunk_end = 117;
+static const int http_parser_en_Trailers = 126;
static const int http_parser_en_main = 1;
-#line 367 "kcar.rl"
+#line 685 "kcar.rl"
static void http_parser_init(struct http_parser *hp)
{
int cs = 0;
memset(hp, 0, sizeof(struct http_parser));
hp->cont = Qfalse; /* zero on MRI, should be optimized away by above */
- hp->status = Qnil;
+ hp->v.status = Qnil;
hp->len.content = -1;
-#line 330 "kcar.c"
+#line 636 "kcar.c"
{
cs = http_parser_start;
}
-#line 376 "kcar.rl"
+#line 694 "kcar.rl"
hp->cs = cs;
}
/** exec **/
static void http_parser_execute(struct http_parser *hp,
@@ -352,878 +658,3048 @@
pe = buffer+len;
assert((void *)(pe - p) == (void *)(len - off) &&
"pointers aren't same distance");
- if (HP_FL_TEST(hp, INCHUNK)) {
- HP_FL_UNSET(hp, INCHUNK);
+ if (hp->in_chunk) {
+ hp->in_chunk = 0;
goto skip_chunk_data_hack;
}
-#line 363 "kcar.c"
+#line 669 "kcar.c"
{
if ( p == pe )
goto _test_eof;
switch ( cs )
{
case 1:
- if ( (*p) == 72 )
+ switch( (*p) ) {
+ case 33: goto tr0;
+ case 71: goto tr2;
+ case 72: goto tr3;
+ case 124: goto tr0;
+ case 126: goto tr0;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto tr0;
+ } else if ( (*p) >= 35 )
+ goto tr0;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr0;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto tr0;
+ } else
+ goto tr0;
+ } else
goto tr0;
goto st0;
st0:
cs = 0;
goto _out;
tr0:
-#line 303 "kcar.rl"
+#line 609 "kcar.rl"
{MARK(mark, p); }
goto st2;
st2:
if ( ++p == pe )
goto _test_eof2;
case 2:
-#line 384 "kcar.c"
- if ( (*p) == 84 )
- goto st3;
+#line 712 "kcar.c"
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st49;
+ case 124: goto st49;
+ case 126: goto st49;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st49;
+ } else if ( (*p) >= 35 )
+ goto st49;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st49;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st49;
+ } else
+ goto st49;
+ } else
+ goto st49;
goto st0;
+tr4:
+#line 613 "kcar.rl"
+ { request_method(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st3;
st3:
if ( ++p == pe )
goto _test_eof3;
case 3:
- if ( (*p) == 84 )
- goto st4;
+#line 745 "kcar.c"
+ switch( (*p) ) {
+ case 42: goto tr6;
+ case 47: goto tr7;
+ case 72: goto tr8;
+ case 104: goto tr8;
+ }
goto st0;
+tr6:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st4;
st4:
if ( ++p == pe )
goto _test_eof4;
case 4:
- if ( (*p) == 80 )
- goto st5;
+#line 761 "kcar.c"
+ switch( (*p) ) {
+ case 32: goto tr9;
+ case 35: goto tr10;
+ }
goto st0;
+tr9:
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st5;
+tr43:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+#line 617 "kcar.rl"
+ { set_fragment(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st5;
+tr46:
+#line 617 "kcar.rl"
+ { set_fragment(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st5;
+tr50:
+#line 622 "kcar.rl"
+ { request_path(hdr, PTR_TO(mark), LEN(mark, p)); }
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st5;
+tr56:
+#line 618 "kcar.rl"
+ { MARK(start.query, p); }
+#line 619 "kcar.rl"
+ {
+ query_string(hp, hdr, PTR_TO(start.query), LEN(start.query, p));
+ }
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st5;
+tr60:
+#line 619 "kcar.rl"
+ {
+ query_string(hp, hdr, PTR_TO(start.query), LEN(start.query, p));
+ }
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st5;
st5:
if ( ++p == pe )
goto _test_eof5;
case 5:
- if ( (*p) == 47 )
- goto st6;
+#line 809 "kcar.c"
+ if ( (*p) == 72 )
+ goto tr11;
goto st0;
+tr11:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st6;
st6:
if ( ++p == pe )
goto _test_eof6;
case 6:
- if ( 48 <= (*p) && (*p) <= 57 )
+#line 821 "kcar.c"
+ if ( (*p) == 84 )
goto st7;
goto st0;
st7:
if ( ++p == pe )
goto _test_eof7;
case 7:
- if ( (*p) == 46 )
+ if ( (*p) == 84 )
goto st8;
- if ( 48 <= (*p) && (*p) <= 57 )
- goto st7;
goto st0;
st8:
if ( ++p == pe )
goto _test_eof8;
case 8:
- if ( 48 <= (*p) && (*p) <= 57 )
+ if ( (*p) == 80 )
goto st9;
goto st0;
st9:
if ( ++p == pe )
goto _test_eof9;
case 9:
- if ( (*p) == 32 )
- goto tr9;
- if ( 48 <= (*p) && (*p) <= 57 )
- goto st9;
+ if ( (*p) == 47 )
+ goto st10;
goto st0;
-tr9:
-#line 310 "kcar.rl"
- { http_version(hp, hdr, PTR_TO(mark), LEN(mark, p)); }
- goto st10;
st10:
if ( ++p == pe )
goto _test_eof10;
case 10:
-#line 449 "kcar.c"
- if ( (*p) == 32 )
- goto st10;
if ( 48 <= (*p) && (*p) <= 57 )
- goto tr11;
+ goto st11;
goto st0;
-tr11:
-#line 303 "kcar.rl"
- {MARK(mark, p); }
- goto st11;
st11:
if ( ++p == pe )
goto _test_eof11;
case 11:
-#line 463 "kcar.c"
+ if ( (*p) == 46 )
+ goto st12;
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st11;
+ goto st0;
+st12:
+ if ( ++p == pe )
+ goto _test_eof12;
+case 12:
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st13;
+ goto st0;
+st13:
+ if ( ++p == pe )
+ goto _test_eof13;
+case 13:
switch( (*p) ) {
- case 10: goto tr12;
- case 13: goto tr13;
- case 32: goto st20;
+ case 10: goto tr19;
+ case 13: goto tr20;
}
if ( 48 <= (*p) && (*p) <= 57 )
- goto st11;
+ goto st13;
goto st0;
-tr12:
-#line 311 "kcar.rl"
- { status_phrase(hp, hdr, PTR_TO(mark), LEN(mark, p)); }
- goto st12;
-tr22:
-#line 307 "kcar.rl"
+tr19:
+#line 628 "kcar.rl"
+ { http_version(hp, hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st14;
+tr27:
+#line 625 "kcar.rl"
{ MARK(mark, p); }
-#line 309 "kcar.rl"
+#line 627 "kcar.rl"
{ write_cont_value(hp, buffer, p); }
- goto st12;
-tr25:
-#line 309 "kcar.rl"
+ goto st14;
+tr30:
+#line 627 "kcar.rl"
{ write_cont_value(hp, buffer, p); }
- goto st12;
-tr32:
-#line 307 "kcar.rl"
+ goto st14;
+tr37:
+#line 625 "kcar.rl"
{ MARK(mark, p); }
-#line 308 "kcar.rl"
- { write_value(hdr, hp, buffer, p); }
- goto st12;
-tr35:
-#line 308 "kcar.rl"
- { write_value(hdr, hp, buffer, p); }
- goto st12;
-st12:
+#line 626 "kcar.rl"
+ { write_value(hp, hdr, buffer, p); }
+ goto st14;
+tr40:
+#line 626 "kcar.rl"
+ { write_value(hp, hdr, buffer, p); }
+ goto st14;
+tr162:
+#line 629 "kcar.rl"
+ { status_phrase(hp, hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st14;
+st14:
if ( ++p == pe )
- goto _test_eof12;
-case 12:
-#line 500 "kcar.c"
+ goto _test_eof14;
+case 14:
+#line 912 "kcar.c"
switch( (*p) ) {
- case 9: goto st13;
- case 10: goto tr17;
- case 13: goto st16;
- case 32: goto st13;
- case 33: goto tr19;
- case 124: goto tr19;
- case 126: goto tr19;
+ case 9: goto st15;
+ case 10: goto tr22;
+ case 13: goto st18;
+ case 32: goto st15;
+ case 33: goto tr24;
+ case 124: goto tr24;
+ case 126: goto tr24;
}
if ( (*p) < 45 ) {
if ( (*p) > 39 ) {
if ( 42 <= (*p) && (*p) <= 43 )
- goto tr19;
+ goto tr24;
} else if ( (*p) >= 35 )
- goto tr19;
+ goto tr24;
} else if ( (*p) > 46 ) {
if ( (*p) < 65 ) {
if ( 48 <= (*p) && (*p) <= 57 )
- goto tr19;
+ goto tr24;
} else if ( (*p) > 90 ) {
if ( 94 <= (*p) && (*p) <= 122 )
- goto tr19;
+ goto tr24;
} else
- goto tr19;
+ goto tr24;
} else
- goto tr19;
+ goto tr24;
goto st0;
-tr21:
-#line 307 "kcar.rl"
+tr26:
+#line 625 "kcar.rl"
{ MARK(mark, p); }
- goto st13;
-st13:
+ goto st15;
+st15:
if ( ++p == pe )
- goto _test_eof13;
-case 13:
-#line 536 "kcar.c"
+ goto _test_eof15;
+case 15:
+#line 948 "kcar.c"
switch( (*p) ) {
- case 9: goto tr21;
- case 10: goto tr22;
- case 13: goto tr23;
- case 32: goto tr21;
+ case 9: goto tr26;
+ case 10: goto tr27;
+ case 13: goto tr28;
+ case 32: goto tr26;
+ case 127: goto st0;
}
- goto tr20;
-tr20:
-#line 307 "kcar.rl"
+ if ( 0 <= (*p) && (*p) <= 31 )
+ goto st0;
+ goto tr25;
+tr25:
+#line 625 "kcar.rl"
{ MARK(mark, p); }
- goto st14;
-st14:
+ goto st16;
+st16:
if ( ++p == pe )
- goto _test_eof14;
-case 14:
-#line 552 "kcar.c"
+ goto _test_eof16;
+case 16:
+#line 967 "kcar.c"
switch( (*p) ) {
- case 10: goto tr25;
- case 13: goto tr26;
+ case 10: goto tr30;
+ case 13: goto tr31;
+ case 127: goto st0;
}
- goto st14;
-tr13:
-#line 311 "kcar.rl"
- { status_phrase(hp, hdr, PTR_TO(mark), LEN(mark, p)); }
- goto st15;
-tr23:
-#line 307 "kcar.rl"
+ if ( (*p) > 8 ) {
+ if ( 11 <= (*p) && (*p) <= 31 )
+ goto st0;
+ } else if ( (*p) >= 0 )
+ goto st0;
+ goto st16;
+tr20:
+#line 628 "kcar.rl"
+ { http_version(hp, hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st17;
+tr28:
+#line 625 "kcar.rl"
{ MARK(mark, p); }
-#line 309 "kcar.rl"
+#line 627 "kcar.rl"
{ write_cont_value(hp, buffer, p); }
- goto st15;
-tr26:
-#line 309 "kcar.rl"
+ goto st17;
+tr31:
+#line 627 "kcar.rl"
{ write_cont_value(hp, buffer, p); }
- goto st15;
-tr33:
-#line 307 "kcar.rl"
+ goto st17;
+tr38:
+#line 625 "kcar.rl"
{ MARK(mark, p); }
-#line 308 "kcar.rl"
- { write_value(hdr, hp, buffer, p); }
- goto st15;
-tr36:
-#line 308 "kcar.rl"
- { write_value(hdr, hp, buffer, p); }
- goto st15;
-st15:
+#line 626 "kcar.rl"
+ { write_value(hp, hdr, buffer, p); }
+ goto st17;
+tr41:
+#line 626 "kcar.rl"
+ { write_value(hp, hdr, buffer, p); }
+ goto st17;
+tr163:
+#line 629 "kcar.rl"
+ { status_phrase(hp, hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st17;
+st17:
if ( ++p == pe )
- goto _test_eof15;
-case 15:
-#line 586 "kcar.c"
+ goto _test_eof17;
+case 17:
+#line 1011 "kcar.c"
if ( (*p) == 10 )
- goto st12;
+ goto st14;
goto st0;
-tr17:
-#line 318 "kcar.rl"
+tr22:
+#line 636 "kcar.rl"
{
- finalize_header(hp);
+ finalize_header(hp, hdr);
cs = http_parser_first_final;
- if (HP_FL_TEST(hp, CHUNKED))
+ if (hp->chunked)
cs = http_parser_en_ChunkedBody;
/*
* go back to Ruby so we can call the Rack application, we'll reenter
* the parser iff the body needs to be processed.
*/
goto post_exec;
}
- goto st44;
-st44:
+ goto st134;
+tr105:
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+#line 636 "kcar.rl"
+ {
+ finalize_header(hp, hdr);
+ cs = http_parser_first_final;
+
+ if (hp->chunked)
+ cs = http_parser_en_ChunkedBody;
+
+ /*
+ * go back to Ruby so we can call the Rack application, we'll reenter
+ * the parser iff the body needs to be processed.
+ */
+ goto post_exec;
+ }
+ goto st134;
+tr109:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+#line 617 "kcar.rl"
+ { set_fragment(hdr, PTR_TO(mark), LEN(mark, p)); }
+#line 636 "kcar.rl"
+ {
+ finalize_header(hp, hdr);
+ cs = http_parser_first_final;
+
+ if (hp->chunked)
+ cs = http_parser_en_ChunkedBody;
+
+ /*
+ * go back to Ruby so we can call the Rack application, we'll reenter
+ * the parser iff the body needs to be processed.
+ */
+ goto post_exec;
+ }
+ goto st134;
+tr113:
+#line 617 "kcar.rl"
+ { set_fragment(hdr, PTR_TO(mark), LEN(mark, p)); }
+#line 636 "kcar.rl"
+ {
+ finalize_header(hp, hdr);
+ cs = http_parser_first_final;
+
+ if (hp->chunked)
+ cs = http_parser_en_ChunkedBody;
+
+ /*
+ * go back to Ruby so we can call the Rack application, we'll reenter
+ * the parser iff the body needs to be processed.
+ */
+ goto post_exec;
+ }
+ goto st134;
+tr118:
+#line 622 "kcar.rl"
+ { request_path(hdr, PTR_TO(mark), LEN(mark, p)); }
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+#line 636 "kcar.rl"
+ {
+ finalize_header(hp, hdr);
+ cs = http_parser_first_final;
+
+ if (hp->chunked)
+ cs = http_parser_en_ChunkedBody;
+
+ /*
+ * go back to Ruby so we can call the Rack application, we'll reenter
+ * the parser iff the body needs to be processed.
+ */
+ goto post_exec;
+ }
+ goto st134;
+tr125:
+#line 618 "kcar.rl"
+ { MARK(start.query, p); }
+#line 619 "kcar.rl"
+ {
+ query_string(hp, hdr, PTR_TO(start.query), LEN(start.query, p));
+ }
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+#line 636 "kcar.rl"
+ {
+ finalize_header(hp, hdr);
+ cs = http_parser_first_final;
+
+ if (hp->chunked)
+ cs = http_parser_en_ChunkedBody;
+
+ /*
+ * go back to Ruby so we can call the Rack application, we'll reenter
+ * the parser iff the body needs to be processed.
+ */
+ goto post_exec;
+ }
+ goto st134;
+tr130:
+#line 619 "kcar.rl"
+ {
+ query_string(hp, hdr, PTR_TO(start.query), LEN(start.query, p));
+ }
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+#line 636 "kcar.rl"
+ {
+ finalize_header(hp, hdr);
+ cs = http_parser_first_final;
+
+ if (hp->chunked)
+ cs = http_parser_en_ChunkedBody;
+
+ /*
+ * go back to Ruby so we can call the Rack application, we'll reenter
+ * the parser iff the body needs to be processed.
+ */
+ goto post_exec;
+ }
+ goto st134;
+st134:
if ( ++p == pe )
- goto _test_eof44;
-case 44:
-#line 610 "kcar.c"
+ goto _test_eof134;
+case 134:
+#line 1157 "kcar.c"
goto st0;
-st16:
+tr106:
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st18;
+tr110:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+#line 617 "kcar.rl"
+ { set_fragment(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st18;
+tr114:
+#line 617 "kcar.rl"
+ { set_fragment(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st18;
+tr119:
+#line 622 "kcar.rl"
+ { request_path(hdr, PTR_TO(mark), LEN(mark, p)); }
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st18;
+tr126:
+#line 618 "kcar.rl"
+ { MARK(start.query, p); }
+#line 619 "kcar.rl"
+ {
+ query_string(hp, hdr, PTR_TO(start.query), LEN(start.query, p));
+ }
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st18;
+tr131:
+#line 619 "kcar.rl"
+ {
+ query_string(hp, hdr, PTR_TO(start.query), LEN(start.query, p));
+ }
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st18;
+st18:
if ( ++p == pe )
- goto _test_eof16;
-case 16:
+ goto _test_eof18;
+case 18:
+#line 1201 "kcar.c"
if ( (*p) == 10 )
- goto tr17;
+ goto tr22;
goto st0;
-tr19:
-#line 305 "kcar.rl"
+tr24:
+#line 623 "kcar.rl"
{ MARK(start.field, p); }
- goto st17;
-st17:
+ goto st19;
+st19:
if ( ++p == pe )
- goto _test_eof17;
-case 17:
-#line 627 "kcar.c"
+ goto _test_eof19;
+case 19:
+#line 1213 "kcar.c"
switch( (*p) ) {
- case 33: goto st17;
- case 58: goto tr29;
- case 124: goto st17;
- case 126: goto st17;
+ case 33: goto st19;
+ case 58: goto tr34;
+ case 124: goto st19;
+ case 126: goto st19;
}
if ( (*p) < 45 ) {
if ( (*p) > 39 ) {
if ( 42 <= (*p) && (*p) <= 43 )
- goto st17;
+ goto st19;
} else if ( (*p) >= 35 )
- goto st17;
+ goto st19;
} else if ( (*p) > 46 ) {
if ( (*p) < 65 ) {
if ( 48 <= (*p) && (*p) <= 57 )
- goto st17;
+ goto st19;
} else if ( (*p) > 90 ) {
if ( 94 <= (*p) && (*p) <= 122 )
- goto st17;
+ goto st19;
} else
- goto st17;
+ goto st19;
} else
- goto st17;
+ goto st19;
goto st0;
-tr31:
-#line 307 "kcar.rl"
+tr36:
+#line 625 "kcar.rl"
{ MARK(mark, p); }
- goto st18;
-tr29:
-#line 306 "kcar.rl"
+ goto st20;
+tr34:
+#line 624 "kcar.rl"
{ hp->s.field_len = LEN(start.field, p); }
- goto st18;
-st18:
- if ( ++p == pe )
- goto _test_eof18;
-case 18:
-#line 664 "kcar.c"
- switch( (*p) ) {
- case 9: goto tr31;
- case 10: goto tr32;
- case 13: goto tr33;
- case 32: goto tr31;
- }
- goto tr30;
-tr30:
-#line 307 "kcar.rl"
- { MARK(mark, p); }
- goto st19;
-st19:
- if ( ++p == pe )
- goto _test_eof19;
-case 19:
-#line 680 "kcar.c"
- switch( (*p) ) {
- case 10: goto tr35;
- case 13: goto tr36;
- }
- goto st19;
+ goto st20;
st20:
if ( ++p == pe )
goto _test_eof20;
case 20:
- if ( (*p) == 10 )
+#line 1250 "kcar.c"
+ switch( (*p) ) {
+ case 9: goto tr36;
+ case 10: goto tr37;
+ case 13: goto tr38;
+ case 32: goto tr36;
+ case 127: goto st0;
+ }
+ if ( 0 <= (*p) && (*p) <= 31 )
goto st0;
+ goto tr35;
+tr35:
+#line 625 "kcar.rl"
+ { MARK(mark, p); }
goto st21;
st21:
if ( ++p == pe )
goto _test_eof21;
case 21:
+#line 1269 "kcar.c"
switch( (*p) ) {
- case 10: goto tr12;
- case 13: goto tr13;
+ case 10: goto tr40;
+ case 13: goto tr41;
+ case 127: goto st0;
}
+ if ( (*p) > 8 ) {
+ if ( 11 <= (*p) && (*p) <= 31 )
+ goto st0;
+ } else if ( (*p) >= 0 )
+ goto st0;
goto st21;
+tr10:
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st22;
+tr51:
+#line 622 "kcar.rl"
+ { request_path(hdr, PTR_TO(mark), LEN(mark, p)); }
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st22;
+tr57:
+#line 618 "kcar.rl"
+ { MARK(start.query, p); }
+#line 619 "kcar.rl"
+ {
+ query_string(hp, hdr, PTR_TO(start.query), LEN(start.query, p));
+ }
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st22;
+tr61:
+#line 619 "kcar.rl"
+ {
+ query_string(hp, hdr, PTR_TO(start.query), LEN(start.query, p));
+ }
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st22;
st22:
if ( ++p == pe )
goto _test_eof22;
case 22:
+#line 1313 "kcar.c"
+ switch( (*p) ) {
+ case 32: goto tr43;
+ case 35: goto st0;
+ case 37: goto tr44;
+ case 127: goto st0;
+ }
+ if ( 0 <= (*p) && (*p) <= 31 )
+ goto st0;
+ goto tr42;
+tr42:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st23;
+st23:
+ if ( ++p == pe )
+ goto _test_eof23;
+case 23:
+#line 1331 "kcar.c"
+ switch( (*p) ) {
+ case 32: goto tr46;
+ case 35: goto st0;
+ case 37: goto st24;
+ case 127: goto st0;
+ }
+ if ( 0 <= (*p) && (*p) <= 31 )
+ goto st0;
+ goto st23;
+tr44:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st24;
+st24:
+ if ( ++p == pe )
+ goto _test_eof24;
+case 24:
+#line 1349 "kcar.c"
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st25;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st25;
+ } else
+ goto st25;
+ goto st0;
+st25:
+ if ( ++p == pe )
+ goto _test_eof25;
+case 25:
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st23;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st23;
+ } else
+ goto st23;
+ goto st0;
+tr7:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st26;
+tr77:
+#line 615 "kcar.rl"
+ { request_host(hp, hdr, PTR_TO(mark), LEN(mark, p)); }
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st26;
+st26:
+ if ( ++p == pe )
+ goto _test_eof26;
+case 26:
+#line 1386 "kcar.c"
+ switch( (*p) ) {
+ case 32: goto tr50;
+ case 35: goto tr51;
+ case 37: goto st27;
+ case 63: goto tr53;
+ case 127: goto st0;
+ }
+ if ( 0 <= (*p) && (*p) <= 31 )
+ goto st0;
+ goto st26;
+st27:
+ if ( ++p == pe )
+ goto _test_eof27;
+case 27:
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st28;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st28;
+ } else
+ goto st28;
+ goto st0;
+st28:
+ if ( ++p == pe )
+ goto _test_eof28;
+case 28:
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st26;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st26;
+ } else
+ goto st26;
+ goto st0;
+tr53:
+#line 622 "kcar.rl"
+ { request_path(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st29;
+st29:
+ if ( ++p == pe )
+ goto _test_eof29;
+case 29:
+#line 1431 "kcar.c"
+ switch( (*p) ) {
+ case 32: goto tr56;
+ case 35: goto tr57;
+ case 37: goto tr58;
+ case 127: goto st0;
+ }
+ if ( 0 <= (*p) && (*p) <= 31 )
+ goto st0;
+ goto tr55;
+tr55:
+#line 618 "kcar.rl"
+ { MARK(start.query, p); }
+ goto st30;
+st30:
+ if ( ++p == pe )
+ goto _test_eof30;
+case 30:
+#line 1449 "kcar.c"
+ switch( (*p) ) {
+ case 32: goto tr60;
+ case 35: goto tr61;
+ case 37: goto st31;
+ case 127: goto st0;
+ }
+ if ( 0 <= (*p) && (*p) <= 31 )
+ goto st0;
+ goto st30;
+tr58:
+#line 618 "kcar.rl"
+ { MARK(start.query, p); }
+ goto st31;
+st31:
+ if ( ++p == pe )
+ goto _test_eof31;
+case 31:
+#line 1467 "kcar.c"
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st32;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st32;
+ } else
+ goto st32;
+ goto st0;
+st32:
+ if ( ++p == pe )
+ goto _test_eof32;
+case 32:
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st30;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st30;
+ } else
+ goto st30;
+ goto st0;
+tr8:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+#line 612 "kcar.rl"
+ { downcase_char(deconst(p)); }
+ goto st33;
+st33:
+ if ( ++p == pe )
+ goto _test_eof33;
+case 33:
+#line 1500 "kcar.c"
+ switch( (*p) ) {
+ case 84: goto tr64;
+ case 116: goto tr64;
+ }
+ goto st0;
+tr64:
+#line 612 "kcar.rl"
+ { downcase_char(deconst(p)); }
+ goto st34;
+st34:
+ if ( ++p == pe )
+ goto _test_eof34;
+case 34:
+#line 1514 "kcar.c"
+ switch( (*p) ) {
+ case 84: goto tr65;
+ case 116: goto tr65;
+ }
+ goto st0;
+tr65:
+#line 612 "kcar.rl"
+ { downcase_char(deconst(p)); }
+ goto st35;
+st35:
+ if ( ++p == pe )
+ goto _test_eof35;
+case 35:
+#line 1528 "kcar.c"
+ switch( (*p) ) {
+ case 80: goto tr66;
+ case 112: goto tr66;
+ }
+ goto st0;
+tr66:
+#line 612 "kcar.rl"
+ { downcase_char(deconst(p)); }
+ goto st36;
+st36:
+ if ( ++p == pe )
+ goto _test_eof36;
+case 36:
+#line 1542 "kcar.c"
+ switch( (*p) ) {
+ case 58: goto tr67;
+ case 83: goto tr68;
+ case 115: goto tr68;
+ }
+ goto st0;
+tr67:
+#line 614 "kcar.rl"
+ { url_scheme(hp, hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st37;
+st37:
+ if ( ++p == pe )
+ goto _test_eof37;
+case 37:
+#line 1557 "kcar.c"
+ if ( (*p) == 47 )
+ goto st38;
+ goto st0;
+st38:
+ if ( ++p == pe )
+ goto _test_eof38;
+case 38:
+ if ( (*p) == 47 )
+ goto st39;
+ goto st0;
+st39:
+ if ( ++p == pe )
+ goto _test_eof39;
+case 39:
+ switch( (*p) ) {
+ case 37: goto st41;
+ case 47: goto st0;
+ case 60: goto st0;
+ case 91: goto tr74;
+ case 95: goto tr73;
+ case 127: goto st0;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 32 ) {
+ if ( 34 <= (*p) && (*p) <= 35 )
+ goto st0;
+ } else if ( (*p) >= 0 )
+ goto st0;
+ } else if ( (*p) > 57 ) {
+ if ( (*p) < 65 ) {
+ if ( 62 <= (*p) && (*p) <= 64 )
+ goto st0;
+ } else if ( (*p) > 90 ) {
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto tr73;
+ } else
+ goto tr73;
+ } else
+ goto tr73;
+ goto st40;
+st40:
+ if ( ++p == pe )
+ goto _test_eof40;
+case 40:
+ switch( (*p) ) {
+ case 37: goto st41;
+ case 47: goto st0;
+ case 60: goto st0;
+ case 64: goto st39;
+ case 127: goto st0;
+ }
+ if ( (*p) < 34 ) {
+ if ( 0 <= (*p) && (*p) <= 32 )
+ goto st0;
+ } else if ( (*p) > 35 ) {
+ if ( 62 <= (*p) && (*p) <= 63 )
+ goto st0;
+ } else
+ goto st0;
+ goto st40;
+st41:
+ if ( ++p == pe )
+ goto _test_eof41;
+case 41:
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st42;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st42;
+ } else
+ goto st42;
+ goto st0;
+st42:
+ if ( ++p == pe )
+ goto _test_eof42;
+case 42:
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st40;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st40;
+ } else
+ goto st40;
+ goto st0;
+tr73:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st43;
+st43:
+ if ( ++p == pe )
+ goto _test_eof43;
+case 43:
+#line 1652 "kcar.c"
+ switch( (*p) ) {
+ case 37: goto st41;
+ case 47: goto tr77;
+ case 58: goto st44;
+ case 60: goto st0;
+ case 64: goto st39;
+ case 95: goto st43;
+ case 127: goto st0;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 32 ) {
+ if ( 34 <= (*p) && (*p) <= 35 )
+ goto st0;
+ } else if ( (*p) >= 0 )
+ goto st0;
+ } else if ( (*p) > 57 ) {
+ if ( (*p) < 65 ) {
+ if ( 62 <= (*p) && (*p) <= 63 )
+ goto st0;
+ } else if ( (*p) > 90 ) {
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st43;
+ } else
+ goto st43;
+ } else
+ goto st43;
+ goto st40;
+st44:
+ if ( ++p == pe )
+ goto _test_eof44;
+case 44:
+ switch( (*p) ) {
+ case 37: goto st41;
+ case 47: goto tr77;
+ case 60: goto st0;
+ case 64: goto st39;
+ case 127: goto st0;
+ }
+ if ( (*p) < 34 ) {
+ if ( 0 <= (*p) && (*p) <= 32 )
+ goto st0;
+ } else if ( (*p) > 35 ) {
+ if ( (*p) > 57 ) {
+ if ( 62 <= (*p) && (*p) <= 63 )
+ goto st0;
+ } else if ( (*p) >= 48 )
+ goto st44;
+ } else
+ goto st0;
+ goto st40;
+tr74:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st45;
+st45:
+ if ( ++p == pe )
+ goto _test_eof45;
+case 45:
+#line 1711 "kcar.c"
+ switch( (*p) ) {
+ case 37: goto st41;
+ case 47: goto st0;
+ case 60: goto st0;
+ case 64: goto st39;
+ case 127: goto st0;
+ }
+ if ( (*p) < 48 ) {
+ if ( (*p) > 32 ) {
+ if ( 34 <= (*p) && (*p) <= 35 )
+ goto st0;
+ } else if ( (*p) >= 0 )
+ goto st0;
+ } else if ( (*p) > 58 ) {
+ if ( (*p) < 65 ) {
+ if ( 62 <= (*p) && (*p) <= 63 )
+ goto st0;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st46;
+ } else
+ goto st46;
+ } else
+ goto st46;
+ goto st40;
+st46:
+ if ( ++p == pe )
+ goto _test_eof46;
+case 46:
+ switch( (*p) ) {
+ case 37: goto st41;
+ case 47: goto st0;
+ case 60: goto st0;
+ case 64: goto st39;
+ case 93: goto st47;
+ case 127: goto st0;
+ }
+ if ( (*p) < 48 ) {
+ if ( (*p) > 32 ) {
+ if ( 34 <= (*p) && (*p) <= 35 )
+ goto st0;
+ } else if ( (*p) >= 0 )
+ goto st0;
+ } else if ( (*p) > 58 ) {
+ if ( (*p) < 65 ) {
+ if ( 62 <= (*p) && (*p) <= 63 )
+ goto st0;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st46;
+ } else
+ goto st46;
+ } else
+ goto st46;
+ goto st40;
+st47:
+ if ( ++p == pe )
+ goto _test_eof47;
+case 47:
+ switch( (*p) ) {
+ case 37: goto st41;
+ case 47: goto tr77;
+ case 58: goto st44;
+ case 60: goto st0;
+ case 64: goto st39;
+ case 127: goto st0;
+ }
+ if ( (*p) < 34 ) {
+ if ( 0 <= (*p) && (*p) <= 32 )
+ goto st0;
+ } else if ( (*p) > 35 ) {
+ if ( 62 <= (*p) && (*p) <= 63 )
+ goto st0;
+ } else
+ goto st0;
+ goto st40;
+tr68:
+#line 612 "kcar.rl"
+ { downcase_char(deconst(p)); }
+ goto st48;
+st48:
+ if ( ++p == pe )
+ goto _test_eof48;
+case 48:
+#line 1796 "kcar.c"
+ if ( (*p) == 58 )
+ goto tr67;
+ goto st0;
+st49:
+ if ( ++p == pe )
+ goto _test_eof49;
+case 49:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st50;
+ case 124: goto st50;
+ case 126: goto st50;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st50;
+ } else if ( (*p) >= 35 )
+ goto st50;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st50;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st50;
+ } else
+ goto st50;
+ } else
+ goto st50;
+ goto st0;
+st50:
+ if ( ++p == pe )
+ goto _test_eof50;
+case 50:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st51;
+ case 124: goto st51;
+ case 126: goto st51;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st51;
+ } else if ( (*p) >= 35 )
+ goto st51;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st51;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st51;
+ } else
+ goto st51;
+ } else
+ goto st51;
+ goto st0;
+st51:
+ if ( ++p == pe )
+ goto _test_eof51;
+case 51:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st52;
+ case 124: goto st52;
+ case 126: goto st52;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st52;
+ } else if ( (*p) >= 35 )
+ goto st52;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st52;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st52;
+ } else
+ goto st52;
+ } else
+ goto st52;
+ goto st0;
+st52:
+ if ( ++p == pe )
+ goto _test_eof52;
+case 52:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st53;
+ case 124: goto st53;
+ case 126: goto st53;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st53;
+ } else if ( (*p) >= 35 )
+ goto st53;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st53;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st53;
+ } else
+ goto st53;
+ } else
+ goto st53;
+ goto st0;
+st53:
+ if ( ++p == pe )
+ goto _test_eof53;
+case 53:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st54;
+ case 124: goto st54;
+ case 126: goto st54;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st54;
+ } else if ( (*p) >= 35 )
+ goto st54;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st54;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st54;
+ } else
+ goto st54;
+ } else
+ goto st54;
+ goto st0;
+st54:
+ if ( ++p == pe )
+ goto _test_eof54;
+case 54:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st55;
+ case 124: goto st55;
+ case 126: goto st55;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st55;
+ } else if ( (*p) >= 35 )
+ goto st55;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st55;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st55;
+ } else
+ goto st55;
+ } else
+ goto st55;
+ goto st0;
+st55:
+ if ( ++p == pe )
+ goto _test_eof55;
+case 55:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st56;
+ case 124: goto st56;
+ case 126: goto st56;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st56;
+ } else if ( (*p) >= 35 )
+ goto st56;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st56;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st56;
+ } else
+ goto st56;
+ } else
+ goto st56;
+ goto st0;
+st56:
+ if ( ++p == pe )
+ goto _test_eof56;
+case 56:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st57;
+ case 124: goto st57;
+ case 126: goto st57;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st57;
+ } else if ( (*p) >= 35 )
+ goto st57;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st57;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st57;
+ } else
+ goto st57;
+ } else
+ goto st57;
+ goto st0;
+st57:
+ if ( ++p == pe )
+ goto _test_eof57;
+case 57:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st58;
+ case 124: goto st58;
+ case 126: goto st58;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st58;
+ } else if ( (*p) >= 35 )
+ goto st58;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st58;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st58;
+ } else
+ goto st58;
+ } else
+ goto st58;
+ goto st0;
+st58:
+ if ( ++p == pe )
+ goto _test_eof58;
+case 58:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st59;
+ case 124: goto st59;
+ case 126: goto st59;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st59;
+ } else if ( (*p) >= 35 )
+ goto st59;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st59;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st59;
+ } else
+ goto st59;
+ } else
+ goto st59;
+ goto st0;
+st59:
+ if ( ++p == pe )
+ goto _test_eof59;
+case 59:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st60;
+ case 124: goto st60;
+ case 126: goto st60;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st60;
+ } else if ( (*p) >= 35 )
+ goto st60;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st60;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st60;
+ } else
+ goto st60;
+ } else
+ goto st60;
+ goto st0;
+st60:
+ if ( ++p == pe )
+ goto _test_eof60;
+case 60:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st61;
+ case 124: goto st61;
+ case 126: goto st61;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st61;
+ } else if ( (*p) >= 35 )
+ goto st61;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st61;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st61;
+ } else
+ goto st61;
+ } else
+ goto st61;
+ goto st0;
+st61:
+ if ( ++p == pe )
+ goto _test_eof61;
+case 61:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st62;
+ case 124: goto st62;
+ case 126: goto st62;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st62;
+ } else if ( (*p) >= 35 )
+ goto st62;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st62;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st62;
+ } else
+ goto st62;
+ } else
+ goto st62;
+ goto st0;
+st62:
+ if ( ++p == pe )
+ goto _test_eof62;
+case 62:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st63;
+ case 124: goto st63;
+ case 126: goto st63;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st63;
+ } else if ( (*p) >= 35 )
+ goto st63;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st63;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st63;
+ } else
+ goto st63;
+ } else
+ goto st63;
+ goto st0;
+st63:
+ if ( ++p == pe )
+ goto _test_eof63;
+case 63:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st64;
+ case 124: goto st64;
+ case 126: goto st64;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st64;
+ } else if ( (*p) >= 35 )
+ goto st64;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st64;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st64;
+ } else
+ goto st64;
+ } else
+ goto st64;
+ goto st0;
+st64:
+ if ( ++p == pe )
+ goto _test_eof64;
+case 64:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st65;
+ case 124: goto st65;
+ case 126: goto st65;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st65;
+ } else if ( (*p) >= 35 )
+ goto st65;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st65;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st65;
+ } else
+ goto st65;
+ } else
+ goto st65;
+ goto st0;
+st65:
+ if ( ++p == pe )
+ goto _test_eof65;
+case 65:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st66;
+ case 124: goto st66;
+ case 126: goto st66;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st66;
+ } else if ( (*p) >= 35 )
+ goto st66;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st66;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st66;
+ } else
+ goto st66;
+ } else
+ goto st66;
+ goto st0;
+st66:
+ if ( ++p == pe )
+ goto _test_eof66;
+case 66:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st67;
+ case 124: goto st67;
+ case 126: goto st67;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st67;
+ } else if ( (*p) >= 35 )
+ goto st67;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st67;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st67;
+ } else
+ goto st67;
+ } else
+ goto st67;
+ goto st0;
+st67:
+ if ( ++p == pe )
+ goto _test_eof67;
+case 67:
+ if ( (*p) == 32 )
+ goto tr4;
+ goto st0;
+tr2:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st68;
+st68:
+ if ( ++p == pe )
+ goto _test_eof68;
+case 68:
+#line 2319 "kcar.c"
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st49;
+ case 69: goto st69;
+ case 124: goto st49;
+ case 126: goto st49;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st49;
+ } else if ( (*p) >= 35 )
+ goto st49;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st49;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st49;
+ } else
+ goto st49;
+ } else
+ goto st49;
+ goto st0;
+st69:
+ if ( ++p == pe )
+ goto _test_eof69;
+case 69:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st50;
+ case 84: goto st70;
+ case 124: goto st50;
+ case 126: goto st50;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st50;
+ } else if ( (*p) >= 35 )
+ goto st50;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st50;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st50;
+ } else
+ goto st50;
+ } else
+ goto st50;
+ goto st0;
+st70:
+ if ( ++p == pe )
+ goto _test_eof70;
+case 70:
+ switch( (*p) ) {
+ case 32: goto tr101;
+ case 33: goto st51;
+ case 124: goto st51;
+ case 126: goto st51;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st51;
+ } else if ( (*p) >= 35 )
+ goto st51;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st51;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st51;
+ } else
+ goto st51;
+ } else
+ goto st51;
+ goto st0;
+tr101:
+#line 613 "kcar.rl"
+ { request_method(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st71;
+st71:
+ if ( ++p == pe )
+ goto _test_eof71;
+case 71:
+#line 2410 "kcar.c"
+ switch( (*p) ) {
+ case 42: goto tr102;
+ case 47: goto tr103;
+ case 72: goto tr104;
+ case 104: goto tr104;
+ }
+ goto st0;
+tr102:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st72;
+st72:
+ if ( ++p == pe )
+ goto _test_eof72;
+case 72:
+#line 2426 "kcar.c"
+ switch( (*p) ) {
+ case 10: goto tr105;
+ case 13: goto tr106;
+ case 32: goto tr9;
+ case 35: goto tr107;
+ }
+ goto st0;
+tr107:
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st73;
+tr120:
+#line 622 "kcar.rl"
+ { request_path(hdr, PTR_TO(mark), LEN(mark, p)); }
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st73;
+tr127:
+#line 618 "kcar.rl"
+ { MARK(start.query, p); }
+#line 619 "kcar.rl"
+ {
+ query_string(hp, hdr, PTR_TO(start.query), LEN(start.query, p));
+ }
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st73;
+tr132:
+#line 619 "kcar.rl"
+ {
+ query_string(hp, hdr, PTR_TO(start.query), LEN(start.query, p));
+ }
+#line 616 "kcar.rl"
+ { request_uri(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st73;
+st73:
+ if ( ++p == pe )
+ goto _test_eof73;
+case 73:
+#line 2466 "kcar.c"
+ switch( (*p) ) {
+ case 10: goto tr109;
+ case 13: goto tr110;
+ case 32: goto tr43;
+ case 35: goto st0;
+ case 37: goto tr111;
+ case 127: goto st0;
+ }
+ if ( 0 <= (*p) && (*p) <= 31 )
+ goto st0;
+ goto tr108;
+tr108:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st74;
+st74:
+ if ( ++p == pe )
+ goto _test_eof74;
+case 74:
+#line 2486 "kcar.c"
+ switch( (*p) ) {
+ case 10: goto tr113;
+ case 13: goto tr114;
+ case 32: goto tr46;
+ case 35: goto st0;
+ case 37: goto st75;
+ case 127: goto st0;
+ }
+ if ( 0 <= (*p) && (*p) <= 31 )
+ goto st0;
+ goto st74;
+tr111:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st75;
+st75:
+ if ( ++p == pe )
+ goto _test_eof75;
+case 75:
+#line 2506 "kcar.c"
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st76;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st76;
+ } else
+ goto st76;
+ goto st0;
+st76:
+ if ( ++p == pe )
+ goto _test_eof76;
+case 76:
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st74;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st74;
+ } else
+ goto st74;
+ goto st0;
+tr103:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st77;
+tr148:
+#line 615 "kcar.rl"
+ { request_host(hp, hdr, PTR_TO(mark), LEN(mark, p)); }
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st77;
+st77:
+ if ( ++p == pe )
+ goto _test_eof77;
+case 77:
+#line 2543 "kcar.c"
+ switch( (*p) ) {
+ case 10: goto tr118;
+ case 13: goto tr119;
+ case 32: goto tr50;
+ case 35: goto tr120;
+ case 37: goto st78;
+ case 63: goto tr122;
+ case 127: goto st0;
+ }
+ if ( 0 <= (*p) && (*p) <= 31 )
+ goto st0;
+ goto st77;
+st78:
+ if ( ++p == pe )
+ goto _test_eof78;
+case 78:
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st79;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st79;
+ } else
+ goto st79;
+ goto st0;
+st79:
+ if ( ++p == pe )
+ goto _test_eof79;
+case 79:
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st77;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st77;
+ } else
+ goto st77;
+ goto st0;
+tr122:
+#line 622 "kcar.rl"
+ { request_path(hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st80;
+st80:
+ if ( ++p == pe )
+ goto _test_eof80;
+case 80:
+#line 2590 "kcar.c"
+ switch( (*p) ) {
+ case 10: goto tr125;
+ case 13: goto tr126;
+ case 32: goto tr56;
+ case 35: goto tr127;
+ case 37: goto tr128;
+ case 127: goto st0;
+ }
+ if ( 0 <= (*p) && (*p) <= 31 )
+ goto st0;
+ goto tr124;
+tr124:
+#line 618 "kcar.rl"
+ { MARK(start.query, p); }
+ goto st81;
+st81:
+ if ( ++p == pe )
+ goto _test_eof81;
+case 81:
+#line 2610 "kcar.c"
+ switch( (*p) ) {
+ case 10: goto tr130;
+ case 13: goto tr131;
+ case 32: goto tr60;
+ case 35: goto tr132;
+ case 37: goto st82;
+ case 127: goto st0;
+ }
+ if ( 0 <= (*p) && (*p) <= 31 )
+ goto st0;
+ goto st81;
+tr128:
+#line 618 "kcar.rl"
+ { MARK(start.query, p); }
+ goto st82;
+st82:
+ if ( ++p == pe )
+ goto _test_eof82;
+case 82:
+#line 2630 "kcar.c"
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st83;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st83;
+ } else
+ goto st83;
+ goto st0;
+st83:
+ if ( ++p == pe )
+ goto _test_eof83;
+case 83:
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st81;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st81;
+ } else
+ goto st81;
+ goto st0;
+tr104:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+#line 612 "kcar.rl"
+ { downcase_char(deconst(p)); }
+ goto st84;
+st84:
+ if ( ++p == pe )
+ goto _test_eof84;
+case 84:
+#line 2663 "kcar.c"
+ switch( (*p) ) {
+ case 84: goto tr135;
+ case 116: goto tr135;
+ }
+ goto st0;
+tr135:
+#line 612 "kcar.rl"
+ { downcase_char(deconst(p)); }
+ goto st85;
+st85:
+ if ( ++p == pe )
+ goto _test_eof85;
+case 85:
+#line 2677 "kcar.c"
+ switch( (*p) ) {
+ case 84: goto tr136;
+ case 116: goto tr136;
+ }
+ goto st0;
+tr136:
+#line 612 "kcar.rl"
+ { downcase_char(deconst(p)); }
+ goto st86;
+st86:
+ if ( ++p == pe )
+ goto _test_eof86;
+case 86:
+#line 2691 "kcar.c"
+ switch( (*p) ) {
+ case 80: goto tr137;
+ case 112: goto tr137;
+ }
+ goto st0;
+tr137:
+#line 612 "kcar.rl"
+ { downcase_char(deconst(p)); }
+ goto st87;
+st87:
+ if ( ++p == pe )
+ goto _test_eof87;
+case 87:
+#line 2705 "kcar.c"
+ switch( (*p) ) {
+ case 58: goto tr138;
+ case 83: goto tr139;
+ case 115: goto tr139;
+ }
+ goto st0;
+tr138:
+#line 614 "kcar.rl"
+ { url_scheme(hp, hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st88;
+st88:
+ if ( ++p == pe )
+ goto _test_eof88;
+case 88:
+#line 2720 "kcar.c"
+ if ( (*p) == 47 )
+ goto st89;
+ goto st0;
+st89:
+ if ( ++p == pe )
+ goto _test_eof89;
+case 89:
+ if ( (*p) == 47 )
+ goto st90;
+ goto st0;
+st90:
+ if ( ++p == pe )
+ goto _test_eof90;
+case 90:
+ switch( (*p) ) {
+ case 37: goto st92;
+ case 47: goto st0;
+ case 60: goto st0;
+ case 91: goto tr145;
+ case 95: goto tr144;
+ case 127: goto st0;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 32 ) {
+ if ( 34 <= (*p) && (*p) <= 35 )
+ goto st0;
+ } else if ( (*p) >= 0 )
+ goto st0;
+ } else if ( (*p) > 57 ) {
+ if ( (*p) < 65 ) {
+ if ( 62 <= (*p) && (*p) <= 64 )
+ goto st0;
+ } else if ( (*p) > 90 ) {
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto tr144;
+ } else
+ goto tr144;
+ } else
+ goto tr144;
+ goto st91;
+st91:
+ if ( ++p == pe )
+ goto _test_eof91;
+case 91:
+ switch( (*p) ) {
+ case 37: goto st92;
+ case 47: goto st0;
+ case 60: goto st0;
+ case 64: goto st90;
+ case 127: goto st0;
+ }
+ if ( (*p) < 34 ) {
+ if ( 0 <= (*p) && (*p) <= 32 )
+ goto st0;
+ } else if ( (*p) > 35 ) {
+ if ( 62 <= (*p) && (*p) <= 63 )
+ goto st0;
+ } else
+ goto st0;
+ goto st91;
+st92:
+ if ( ++p == pe )
+ goto _test_eof92;
+case 92:
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st93;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st93;
+ } else
+ goto st93;
+ goto st0;
+st93:
+ if ( ++p == pe )
+ goto _test_eof93;
+case 93:
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st91;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st91;
+ } else
+ goto st91;
+ goto st0;
+tr144:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st94;
+st94:
+ if ( ++p == pe )
+ goto _test_eof94;
+case 94:
+#line 2815 "kcar.c"
+ switch( (*p) ) {
+ case 37: goto st92;
+ case 47: goto tr148;
+ case 58: goto st95;
+ case 60: goto st0;
+ case 64: goto st90;
+ case 95: goto st94;
+ case 127: goto st0;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 32 ) {
+ if ( 34 <= (*p) && (*p) <= 35 )
+ goto st0;
+ } else if ( (*p) >= 0 )
+ goto st0;
+ } else if ( (*p) > 57 ) {
+ if ( (*p) < 65 ) {
+ if ( 62 <= (*p) && (*p) <= 63 )
+ goto st0;
+ } else if ( (*p) > 90 ) {
+ if ( 97 <= (*p) && (*p) <= 122 )
+ goto st94;
+ } else
+ goto st94;
+ } else
+ goto st94;
+ goto st91;
+st95:
+ if ( ++p == pe )
+ goto _test_eof95;
+case 95:
+ switch( (*p) ) {
+ case 37: goto st92;
+ case 47: goto tr148;
+ case 60: goto st0;
+ case 64: goto st90;
+ case 127: goto st0;
+ }
+ if ( (*p) < 34 ) {
+ if ( 0 <= (*p) && (*p) <= 32 )
+ goto st0;
+ } else if ( (*p) > 35 ) {
+ if ( (*p) > 57 ) {
+ if ( 62 <= (*p) && (*p) <= 63 )
+ goto st0;
+ } else if ( (*p) >= 48 )
+ goto st95;
+ } else
+ goto st0;
+ goto st91;
+tr145:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st96;
+st96:
+ if ( ++p == pe )
+ goto _test_eof96;
+case 96:
+#line 2874 "kcar.c"
+ switch( (*p) ) {
+ case 37: goto st92;
+ case 47: goto st0;
+ case 60: goto st0;
+ case 64: goto st90;
+ case 127: goto st0;
+ }
+ if ( (*p) < 48 ) {
+ if ( (*p) > 32 ) {
+ if ( 34 <= (*p) && (*p) <= 35 )
+ goto st0;
+ } else if ( (*p) >= 0 )
+ goto st0;
+ } else if ( (*p) > 58 ) {
+ if ( (*p) < 65 ) {
+ if ( 62 <= (*p) && (*p) <= 63 )
+ goto st0;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st97;
+ } else
+ goto st97;
+ } else
+ goto st97;
+ goto st91;
+st97:
+ if ( ++p == pe )
+ goto _test_eof97;
+case 97:
+ switch( (*p) ) {
+ case 37: goto st92;
+ case 47: goto st0;
+ case 60: goto st0;
+ case 64: goto st90;
+ case 93: goto st98;
+ case 127: goto st0;
+ }
+ if ( (*p) < 48 ) {
+ if ( (*p) > 32 ) {
+ if ( 34 <= (*p) && (*p) <= 35 )
+ goto st0;
+ } else if ( (*p) >= 0 )
+ goto st0;
+ } else if ( (*p) > 58 ) {
+ if ( (*p) < 65 ) {
+ if ( 62 <= (*p) && (*p) <= 63 )
+ goto st0;
+ } else if ( (*p) > 70 ) {
+ if ( 97 <= (*p) && (*p) <= 102 )
+ goto st97;
+ } else
+ goto st97;
+ } else
+ goto st97;
+ goto st91;
+st98:
+ if ( ++p == pe )
+ goto _test_eof98;
+case 98:
+ switch( (*p) ) {
+ case 37: goto st92;
+ case 47: goto tr148;
+ case 58: goto st95;
+ case 60: goto st0;
+ case 64: goto st90;
+ case 127: goto st0;
+ }
+ if ( (*p) < 34 ) {
+ if ( 0 <= (*p) && (*p) <= 32 )
+ goto st0;
+ } else if ( (*p) > 35 ) {
+ if ( 62 <= (*p) && (*p) <= 63 )
+ goto st0;
+ } else
+ goto st0;
+ goto st91;
+tr139:
+#line 612 "kcar.rl"
+ { downcase_char(deconst(p)); }
+ goto st99;
+st99:
+ if ( ++p == pe )
+ goto _test_eof99;
+case 99:
+#line 2959 "kcar.c"
+ if ( (*p) == 58 )
+ goto tr138;
+ goto st0;
+tr3:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st100;
+st100:
+ if ( ++p == pe )
+ goto _test_eof100;
+case 100:
+#line 2971 "kcar.c"
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st49;
+ case 84: goto st101;
+ case 124: goto st49;
+ case 126: goto st49;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st49;
+ } else if ( (*p) >= 35 )
+ goto st49;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st49;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st49;
+ } else
+ goto st49;
+ } else
+ goto st49;
+ goto st0;
+st101:
+ if ( ++p == pe )
+ goto _test_eof101;
+case 101:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st50;
+ case 84: goto st102;
+ case 124: goto st50;
+ case 126: goto st50;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st50;
+ } else if ( (*p) >= 35 )
+ goto st50;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st50;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st50;
+ } else
+ goto st50;
+ } else
+ goto st50;
+ goto st0;
+st102:
+ if ( ++p == pe )
+ goto _test_eof102;
+case 102:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st51;
+ case 80: goto st103;
+ case 124: goto st51;
+ case 126: goto st51;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st51;
+ } else if ( (*p) >= 35 )
+ goto st51;
+ } else if ( (*p) > 46 ) {
+ if ( (*p) < 65 ) {
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st51;
+ } else if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st51;
+ } else
+ goto st51;
+ } else
+ goto st51;
+ goto st0;
+st103:
+ if ( ++p == pe )
+ goto _test_eof103;
+case 103:
+ switch( (*p) ) {
+ case 32: goto tr4;
+ case 33: goto st52;
+ case 47: goto st104;
+ case 124: goto st52;
+ case 126: goto st52;
+ }
+ if ( (*p) < 45 ) {
+ if ( (*p) > 39 ) {
+ if ( 42 <= (*p) && (*p) <= 43 )
+ goto st52;
+ } else if ( (*p) >= 35 )
+ goto st52;
+ } else if ( (*p) > 57 ) {
+ if ( (*p) > 90 ) {
+ if ( 94 <= (*p) && (*p) <= 122 )
+ goto st52;
+ } else if ( (*p) >= 65 )
+ goto st52;
+ } else
+ goto st52;
+ goto st0;
+st104:
+ if ( ++p == pe )
+ goto _test_eof104;
+case 104:
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st105;
+ goto st0;
+st105:
+ if ( ++p == pe )
+ goto _test_eof105;
+case 105:
+ if ( (*p) == 46 )
+ goto st106;
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st105;
+ goto st0;
+st106:
+ if ( ++p == pe )
+ goto _test_eof106;
+case 106:
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st107;
+ goto st0;
+st107:
+ if ( ++p == pe )
+ goto _test_eof107;
+case 107:
+ if ( (*p) == 32 )
+ goto tr159;
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st107;
+ goto st0;
+tr159:
+#line 628 "kcar.rl"
+ { http_version(hp, hdr, PTR_TO(mark), LEN(mark, p)); }
+ goto st108;
+st108:
+ if ( ++p == pe )
+ goto _test_eof108;
+case 108:
+#line 3121 "kcar.c"
+ if ( (*p) == 32 )
+ goto st108;
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto tr161;
+ goto st0;
+tr161:
+#line 609 "kcar.rl"
+ {MARK(mark, p); }
+ goto st109;
+st109:
+ if ( ++p == pe )
+ goto _test_eof109;
+case 109:
+#line 3135 "kcar.c"
+ switch( (*p) ) {
+ case 10: goto tr162;
+ case 13: goto tr163;
+ case 32: goto st110;
+ }
+ if ( 48 <= (*p) && (*p) <= 57 )
+ goto st109;
+ goto st0;
+st110:
+ if ( ++p == pe )
+ goto _test_eof110;
+case 110:
+ if ( (*p) == 10 )
+ goto st0;
+ goto st111;
+st111:
+ if ( ++p == pe )
+ goto _test_eof111;
+case 111:
+ switch( (*p) ) {
+ case 10: goto tr162;
+ case 13: goto tr163;
+ }
+ goto st111;
+st112:
+ if ( ++p == pe )
+ goto _test_eof112;
+case 112:
if ( (*p) == 48 )
- goto tr38;
+ goto tr167;
if ( (*p) < 65 ) {
if ( 49 <= (*p) && (*p) <= 57 )
- goto tr39;
+ goto tr168;
} else if ( (*p) > 70 ) {
if ( 97 <= (*p) && (*p) <= 102 )
- goto tr39;
+ goto tr168;
} else
- goto tr39;
+ goto tr168;
goto st0;
-tr38:
-#line 313 "kcar.rl"
+tr167:
+#line 631 "kcar.rl"
{
hp->len.chunk = step_incr(hp->len.chunk, (*p), 16);
if (hp->len.chunk < 0)
rb_raise(eParserError, "invalid chunk size");
}
- goto st23;
-st23:
+ goto st113;
+st113:
if ( ++p == pe )
- goto _test_eof23;
-case 23:
-#line 729 "kcar.c"
+ goto _test_eof113;
+case 113:
+#line 3187 "kcar.c"
switch( (*p) ) {
- case 10: goto tr40;
- case 13: goto st24;
- case 48: goto tr38;
- case 59: goto st33;
+ case 10: goto tr169;
+ case 13: goto st114;
+ case 48: goto tr167;
+ case 59: goto st123;
}
if ( (*p) < 65 ) {
if ( 49 <= (*p) && (*p) <= 57 )
- goto tr39;
+ goto tr168;
} else if ( (*p) > 70 ) {
if ( 97 <= (*p) && (*p) <= 102 )
- goto tr39;
+ goto tr168;
} else
- goto tr39;
+ goto tr168;
goto st0;
-tr40:
-#line 337 "kcar.rl"
+tr169:
+#line 655 "kcar.rl"
{
- HP_FL_SET(hp, INTRAILER);
+ hp->in_trailer = 1;
cs = http_parser_en_Trailers;
++p;
assert(p <= pe && "buffer overflow after chunked body");
goto post_exec;
}
- goto st45;
-st45:
+ goto st135;
+st135:
if ( ++p == pe )
- goto _test_eof45;
-case 45:
-#line 759 "kcar.c"
+ goto _test_eof135;
+case 135:
+#line 3217 "kcar.c"
goto st0;
-st24:
+st114:
if ( ++p == pe )
- goto _test_eof24;
-case 24:
+ goto _test_eof114;
+case 114:
if ( (*p) == 10 )
- goto tr40;
+ goto tr169;
goto st0;
-tr39:
-#line 313 "kcar.rl"
+tr168:
+#line 631 "kcar.rl"
{
hp->len.chunk = step_incr(hp->len.chunk, (*p), 16);
if (hp->len.chunk < 0)
rb_raise(eParserError, "invalid chunk size");
}
- goto st25;
-st25:
+ goto st115;
+st115:
if ( ++p == pe )
- goto _test_eof25;
-case 25:
-#line 780 "kcar.c"
+ goto _test_eof115;
+case 115:
+#line 3238 "kcar.c"
switch( (*p) ) {
- case 10: goto st26;
- case 13: goto st29;
- case 59: goto st30;
+ case 10: goto st116;
+ case 13: goto st119;
+ case 59: goto st120;
}
if ( (*p) < 65 ) {
if ( 48 <= (*p) && (*p) <= 57 )
- goto tr39;
+ goto tr168;
} else if ( (*p) > 70 ) {
if ( 97 <= (*p) && (*p) <= 102 )
- goto tr39;
+ goto tr168;
} else
- goto tr39;
+ goto tr168;
goto st0;
-st26:
+st116:
if ( ++p == pe )
- goto _test_eof26;
-case 26:
- goto tr46;
-tr46:
-#line 345 "kcar.rl"
+ goto _test_eof116;
+case 116:
+ goto tr175;
+tr175:
+#line 663 "kcar.rl"
{
skip_chunk_data_hack: {
size_t nr = MIN((size_t)hp->len.chunk, REMAINING);
memcpy(RSTRING_PTR(hdr) + hp->s.dest_offset, p, nr);
hp->s.dest_offset += nr;
hp->len.chunk -= nr;
p += nr;
assert(hp->len.chunk >= 0 && "negative chunk length");
if ((size_t)hp->len.chunk > REMAINING) {
- HP_FL_SET(hp, INCHUNK);
+ hp->in_chunk = 1;
goto post_exec;
} else {
p--;
- {goto st27;}
+ {goto st117;}
}
}}
- goto st27;
-st27:
+ goto st117;
+st117:
if ( ++p == pe )
- goto _test_eof27;
-case 27:
-#line 823 "kcar.c"
+ goto _test_eof117;
+case 117:
+#line 3281 "kcar.c"
switch( (*p) ) {
- case 10: goto st22;
- case 13: goto st28;
+ case 10: goto st112;
+ case 13: goto st118;
}
goto st0;
-st28:
+st118:
if ( ++p == pe )
- goto _test_eof28;
-case 28:
+ goto _test_eof118;
+case 118:
if ( (*p) == 10 )
- goto st22;
+ goto st112;
goto st0;
-st29:
+st119:
if ( ++p == pe )
- goto _test_eof29;
-case 29:
+ goto _test_eof119;
+case 119:
if ( (*p) == 10 )
- goto st26;
+ goto st116;
goto st0;
-st30:
+st120:
if ( ++p == pe )
- goto _test_eof30;
-case 30:
+ goto _test_eof120;
+case 120:
switch( (*p) ) {
- case 10: goto st26;
- case 13: goto st29;
- case 32: goto st30;
- case 33: goto st31;
- case 59: goto st30;
- case 61: goto st32;
- case 124: goto st31;
- case 126: goto st31;
+ case 10: goto st116;
+ case 13: goto st119;
+ case 32: goto st120;
+ case 33: goto st121;
+ case 59: goto st120;
+ case 61: goto st122;
+ case 124: goto st121;
+ case 126: goto st121;
}
if ( (*p) < 45 ) {
if ( (*p) > 39 ) {
if ( 42 <= (*p) && (*p) <= 43 )
- goto st31;
+ goto st121;
} else if ( (*p) >= 35 )
- goto st31;
+ goto st121;
} else if ( (*p) > 46 ) {
if ( (*p) < 65 ) {
if ( 48 <= (*p) && (*p) <= 57 )
- goto st31;
+ goto st121;
} else if ( (*p) > 90 ) {
if ( 94 <= (*p) && (*p) <= 122 )
- goto st31;
+ goto st121;
} else
- goto st31;
+ goto st121;
} else
- goto st31;
+ goto st121;
goto st0;
-st31:
+st121:
if ( ++p == pe )
- goto _test_eof31;
-case 31:
+ goto _test_eof121;
+case 121:
switch( (*p) ) {
- case 10: goto st26;
- case 13: goto st29;
- case 33: goto st31;
- case 59: goto st30;
- case 61: goto st32;
- case 124: goto st31;
- case 126: goto st31;
+ case 10: goto st116;
+ case 13: goto st119;
+ case 33: goto st121;
+ case 59: goto st120;
+ case 61: goto st122;
+ case 124: goto st121;
+ case 126: goto st121;
}
if ( (*p) < 45 ) {
if ( (*p) > 39 ) {
if ( 42 <= (*p) && (*p) <= 43 )
- goto st31;
+ goto st121;
} else if ( (*p) >= 35 )
- goto st31;
+ goto st121;
} else if ( (*p) > 46 ) {
if ( (*p) < 65 ) {
if ( 48 <= (*p) && (*p) <= 57 )
- goto st31;
+ goto st121;
} else if ( (*p) > 90 ) {
if ( 94 <= (*p) && (*p) <= 122 )
- goto st31;
+ goto st121;
} else
- goto st31;
+ goto st121;
} else
- goto st31;
+ goto st121;
goto st0;
-st32:
+st122:
if ( ++p == pe )
- goto _test_eof32;
-case 32:
+ goto _test_eof122;
+case 122:
switch( (*p) ) {
- case 10: goto st26;
- case 13: goto st29;
- case 33: goto st32;
- case 59: goto st30;
- case 124: goto st32;
- case 126: goto st32;
+ case 10: goto st116;
+ case 13: goto st119;
+ case 33: goto st122;
+ case 59: goto st120;
+ case 124: goto st122;
+ case 126: goto st122;
}
if ( (*p) < 45 ) {
if ( (*p) > 39 ) {
if ( 42 <= (*p) && (*p) <= 43 )
- goto st32;
+ goto st122;
} else if ( (*p) >= 35 )
- goto st32;
+ goto st122;
} else if ( (*p) > 46 ) {
if ( (*p) < 65 ) {
if ( 48 <= (*p) && (*p) <= 57 )
- goto st32;
+ goto st122;
} else if ( (*p) > 90 ) {
if ( 94 <= (*p) && (*p) <= 122 )
- goto st32;
+ goto st122;
} else
- goto st32;
+ goto st122;
} else
- goto st32;
+ goto st122;
goto st0;
-st33:
+st123:
if ( ++p == pe )
- goto _test_eof33;
-case 33:
+ goto _test_eof123;
+case 123:
switch( (*p) ) {
- case 10: goto tr40;
- case 13: goto st24;
- case 32: goto st33;
- case 33: goto st34;
- case 59: goto st33;
- case 61: goto st35;
- case 124: goto st34;
- case 126: goto st34;
+ case 10: goto tr169;
+ case 13: goto st114;
+ case 32: goto st123;
+ case 33: goto st124;
+ case 59: goto st123;
+ case 61: goto st125;
+ case 124: goto st124;
+ case 126: goto st124;
}
if ( (*p) < 45 ) {
if ( (*p) > 39 ) {
if ( 42 <= (*p) && (*p) <= 43 )
- goto st34;
+ goto st124;
} else if ( (*p) >= 35 )
- goto st34;
+ goto st124;
} else if ( (*p) > 46 ) {
if ( (*p) < 65 ) {
if ( 48 <= (*p) && (*p) <= 57 )
- goto st34;
+ goto st124;
} else if ( (*p) > 90 ) {
if ( 94 <= (*p) && (*p) <= 122 )
- goto st34;
+ goto st124;
} else
- goto st34;
+ goto st124;
} else
- goto st34;
+ goto st124;
goto st0;
-st34:
+st124:
if ( ++p == pe )
- goto _test_eof34;
-case 34:
+ goto _test_eof124;
+case 124:
switch( (*p) ) {
- case 10: goto tr40;
- case 13: goto st24;
- case 33: goto st34;
- case 59: goto st33;
- case 61: goto st35;
- case 124: goto st34;
- case 126: goto st34;
+ case 10: goto tr169;
+ case 13: goto st114;
+ case 33: goto st124;
+ case 59: goto st123;
+ case 61: goto st125;
+ case 124: goto st124;
+ case 126: goto st124;
}
if ( (*p) < 45 ) {
if ( (*p) > 39 ) {
if ( 42 <= (*p) && (*p) <= 43 )
- goto st34;
+ goto st124;
} else if ( (*p) >= 35 )
- goto st34;
+ goto st124;
} else if ( (*p) > 46 ) {
if ( (*p) < 65 ) {
if ( 48 <= (*p) && (*p) <= 57 )
- goto st34;
+ goto st124;
} else if ( (*p) > 90 ) {
if ( 94 <= (*p) && (*p) <= 122 )
- goto st34;
+ goto st124;
} else
- goto st34;
+ goto st124;
} else
- goto st34;
+ goto st124;
goto st0;
-st35:
+st125:
if ( ++p == pe )
- goto _test_eof35;
-case 35:
+ goto _test_eof125;
+case 125:
switch( (*p) ) {
- case 10: goto tr40;
- case 13: goto st24;
- case 33: goto st35;
- case 59: goto st33;
- case 124: goto st35;
- case 126: goto st35;
+ case 10: goto tr169;
+ case 13: goto st114;
+ case 33: goto st125;
+ case 59: goto st123;
+ case 124: goto st125;
+ case 126: goto st125;
}
if ( (*p) < 45 ) {
if ( (*p) > 39 ) {
if ( 42 <= (*p) && (*p) <= 43 )
- goto st35;
+ goto st125;
} else if ( (*p) >= 35 )
- goto st35;
+ goto st125;
} else if ( (*p) > 46 ) {
if ( (*p) < 65 ) {
if ( 48 <= (*p) && (*p) <= 57 )
- goto st35;
+ goto st125;
} else if ( (*p) > 90 ) {
if ( 94 <= (*p) && (*p) <= 122 )
- goto st35;
+ goto st125;
} else
- goto st35;
+ goto st125;
} else
- goto st35;
+ goto st125;
goto st0;
-tr59:
-#line 307 "kcar.rl"
+tr188:
+#line 625 "kcar.rl"
{ MARK(mark, p); }
-#line 309 "kcar.rl"
+#line 627 "kcar.rl"
{ write_cont_value(hp, buffer, p); }
- goto st36;
-tr62:
-#line 309 "kcar.rl"
+ goto st126;
+tr191:
+#line 627 "kcar.rl"
{ write_cont_value(hp, buffer, p); }
- goto st36;
-tr69:
-#line 307 "kcar.rl"
+ goto st126;
+tr198:
+#line 625 "kcar.rl"
{ MARK(mark, p); }
-#line 308 "kcar.rl"
- { write_value(hdr, hp, buffer, p); }
- goto st36;
-tr72:
-#line 308 "kcar.rl"
- { write_value(hdr, hp, buffer, p); }
- goto st36;
-st36:
+#line 626 "kcar.rl"
+ { write_value(hp, hdr, buffer, p); }
+ goto st126;
+tr201:
+#line 626 "kcar.rl"
+ { write_value(hp, hdr, buffer, p); }
+ goto st126;
+st126:
if ( ++p == pe )
- goto _test_eof36;
-case 36:
-#line 1053 "kcar.c"
+ goto _test_eof126;
+case 126:
+#line 3511 "kcar.c"
switch( (*p) ) {
- case 9: goto st37;
- case 10: goto tr54;
- case 13: goto st40;
- case 32: goto st37;
- case 33: goto tr56;
- case 124: goto tr56;
- case 126: goto tr56;
+ case 9: goto st127;
+ case 10: goto tr183;
+ case 13: goto st130;
+ case 32: goto st127;
+ case 33: goto tr185;
+ case 124: goto tr185;
+ case 126: goto tr185;
}
if ( (*p) < 45 ) {
if ( (*p) > 39 ) {
if ( 42 <= (*p) && (*p) <= 43 )
- goto tr56;
+ goto tr185;
} else if ( (*p) >= 35 )
- goto tr56;
+ goto tr185;
} else if ( (*p) > 46 ) {
if ( (*p) < 65 ) {
if ( 48 <= (*p) && (*p) <= 57 )
- goto tr56;
+ goto tr185;
} else if ( (*p) > 90 ) {
if ( 94 <= (*p) && (*p) <= 122 )
- goto tr56;
+ goto tr185;
} else
- goto tr56;
+ goto tr185;
} else
- goto tr56;
+ goto tr185;
goto st0;
-tr58:
-#line 307 "kcar.rl"
+tr187:
+#line 625 "kcar.rl"
{ MARK(mark, p); }
- goto st37;
-st37:
+ goto st127;
+st127:
if ( ++p == pe )
- goto _test_eof37;
-case 37:
-#line 1089 "kcar.c"
+ goto _test_eof127;
+case 127:
+#line 3547 "kcar.c"
switch( (*p) ) {
- case 9: goto tr58;
- case 10: goto tr59;
- case 13: goto tr60;
- case 32: goto tr58;
+ case 9: goto tr187;
+ case 10: goto tr188;
+ case 13: goto tr189;
+ case 32: goto tr187;
+ case 127: goto st0;
}
- goto tr57;
-tr57:
-#line 307 "kcar.rl"
+ if ( 0 <= (*p) && (*p) <= 31 )
+ goto st0;
+ goto tr186;
+tr186:
+#line 625 "kcar.rl"
{ MARK(mark, p); }
- goto st38;
-st38:
+ goto st128;
+st128:
if ( ++p == pe )
- goto _test_eof38;
-case 38:
-#line 1105 "kcar.c"
+ goto _test_eof128;
+case 128:
+#line 3566 "kcar.c"
switch( (*p) ) {
- case 10: goto tr62;
- case 13: goto tr63;
+ case 10: goto tr191;
+ case 13: goto tr192;
+ case 127: goto st0;
}
- goto st38;
-tr60:
-#line 307 "kcar.rl"
+ if ( (*p) > 8 ) {
+ if ( 11 <= (*p) && (*p) <= 31 )
+ goto st0;
+ } else if ( (*p) >= 0 )
+ goto st0;
+ goto st128;
+tr189:
+#line 625 "kcar.rl"
{ MARK(mark, p); }
-#line 309 "kcar.rl"
+#line 627 "kcar.rl"
{ write_cont_value(hp, buffer, p); }
- goto st39;
-tr63:
-#line 309 "kcar.rl"
+ goto st129;
+tr192:
+#line 627 "kcar.rl"
{ write_cont_value(hp, buffer, p); }
- goto st39;
-tr70:
-#line 307 "kcar.rl"
+ goto st129;
+tr199:
+#line 625 "kcar.rl"
{ MARK(mark, p); }
-#line 308 "kcar.rl"
- { write_value(hdr, hp, buffer, p); }
- goto st39;
-tr73:
-#line 308 "kcar.rl"
- { write_value(hdr, hp, buffer, p); }
- goto st39;
-st39:
+#line 626 "kcar.rl"
+ { write_value(hp, hdr, buffer, p); }
+ goto st129;
+tr202:
+#line 626 "kcar.rl"
+ { write_value(hp, hdr, buffer, p); }
+ goto st129;
+st129:
if ( ++p == pe )
- goto _test_eof39;
-case 39:
-#line 1135 "kcar.c"
+ goto _test_eof129;
+case 129:
+#line 3602 "kcar.c"
if ( (*p) == 10 )
- goto st36;
+ goto st126;
goto st0;
-tr54:
-#line 332 "kcar.rl"
+tr183:
+#line 650 "kcar.rl"
{
cs = http_parser_first_final;
goto post_exec;
}
- goto st46;
-st46:
+ goto st136;
+st136:
if ( ++p == pe )
- goto _test_eof46;
-case 46:
-#line 1150 "kcar.c"
+ goto _test_eof136;
+case 136:
+#line 3617 "kcar.c"
goto st0;
-st40:
+st130:
if ( ++p == pe )
- goto _test_eof40;
-case 40:
+ goto _test_eof130;
+case 130:
if ( (*p) == 10 )
- goto tr54;
+ goto tr183;
goto st0;
-tr56:
-#line 305 "kcar.rl"
+tr185:
+#line 623 "kcar.rl"
{ MARK(start.field, p); }
- goto st41;
-st41:
+ goto st131;
+st131:
if ( ++p == pe )
- goto _test_eof41;
-case 41:
-#line 1167 "kcar.c"
+ goto _test_eof131;
+case 131:
+#line 3634 "kcar.c"
switch( (*p) ) {
- case 33: goto st41;
- case 58: goto tr66;
- case 124: goto st41;
- case 126: goto st41;
+ case 33: goto st131;
+ case 58: goto tr195;
+ case 124: goto st131;
+ case 126: goto st131;
}
if ( (*p) < 45 ) {
if ( (*p) > 39 ) {
if ( 42 <= (*p) && (*p) <= 43 )
- goto st41;
+ goto st131;
} else if ( (*p) >= 35 )
- goto st41;
+ goto st131;
} else if ( (*p) > 46 ) {
if ( (*p) < 65 ) {
if ( 48 <= (*p) && (*p) <= 57 )
- goto st41;
+ goto st131;
} else if ( (*p) > 90 ) {
if ( 94 <= (*p) && (*p) <= 122 )
- goto st41;
+ goto st131;
} else
- goto st41;
+ goto st131;
} else
- goto st41;
+ goto st131;
goto st0;
-tr68:
-#line 307 "kcar.rl"
+tr197:
+#line 625 "kcar.rl"
{ MARK(mark, p); }
- goto st42;
-tr66:
-#line 306 "kcar.rl"
+ goto st132;
+tr195:
+#line 624 "kcar.rl"
{ hp->s.field_len = LEN(start.field, p); }
- goto st42;
-st42:
+ goto st132;
+st132:
if ( ++p == pe )
- goto _test_eof42;
-case 42:
-#line 1204 "kcar.c"
+ goto _test_eof132;
+case 132:
+#line 3671 "kcar.c"
switch( (*p) ) {
- case 9: goto tr68;
- case 10: goto tr69;
- case 13: goto tr70;
- case 32: goto tr68;
+ case 9: goto tr197;
+ case 10: goto tr198;
+ case 13: goto tr199;
+ case 32: goto tr197;
+ case 127: goto st0;
}
- goto tr67;
-tr67:
-#line 307 "kcar.rl"
+ if ( 0 <= (*p) && (*p) <= 31 )
+ goto st0;
+ goto tr196;
+tr196:
+#line 625 "kcar.rl"
{ MARK(mark, p); }
- goto st43;
-st43:
+ goto st133;
+st133:
if ( ++p == pe )
- goto _test_eof43;
-case 43:
-#line 1220 "kcar.c"
+ goto _test_eof133;
+case 133:
+#line 3690 "kcar.c"
switch( (*p) ) {
- case 10: goto tr72;
- case 13: goto tr73;
+ case 10: goto tr201;
+ case 13: goto tr202;
+ case 127: goto st0;
}
- goto st43;
+ if ( (*p) > 8 ) {
+ if ( 11 <= (*p) && (*p) <= 31 )
+ goto st0;
+ } else if ( (*p) >= 0 )
+ goto st0;
+ goto st133;
}
_test_eof2: cs = 2; goto _test_eof;
_test_eof3: cs = 3; goto _test_eof;
_test_eof4: cs = 4; goto _test_eof;
_test_eof5: cs = 5; goto _test_eof;
@@ -1235,20 +3711,19 @@
_test_eof11: cs = 11; goto _test_eof;
_test_eof12: cs = 12; goto _test_eof;
_test_eof13: cs = 13; goto _test_eof;
_test_eof14: cs = 14; goto _test_eof;
_test_eof15: cs = 15; goto _test_eof;
- _test_eof44: cs = 44; goto _test_eof;
_test_eof16: cs = 16; goto _test_eof;
_test_eof17: cs = 17; goto _test_eof;
+ _test_eof134: cs = 134; goto _test_eof;
_test_eof18: cs = 18; goto _test_eof;
_test_eof19: cs = 19; goto _test_eof;
_test_eof20: cs = 20; goto _test_eof;
_test_eof21: cs = 21; goto _test_eof;
_test_eof22: cs = 22; goto _test_eof;
_test_eof23: cs = 23; goto _test_eof;
- _test_eof45: cs = 45; goto _test_eof;
_test_eof24: cs = 24; goto _test_eof;
_test_eof25: cs = 25; goto _test_eof;
_test_eof26: cs = 26; goto _test_eof;
_test_eof27: cs = 27; goto _test_eof;
_test_eof28: cs = 28; goto _test_eof;
@@ -1261,53 +3736,156 @@
_test_eof35: cs = 35; goto _test_eof;
_test_eof36: cs = 36; goto _test_eof;
_test_eof37: cs = 37; goto _test_eof;
_test_eof38: cs = 38; goto _test_eof;
_test_eof39: cs = 39; goto _test_eof;
- _test_eof46: cs = 46; goto _test_eof;
_test_eof40: cs = 40; goto _test_eof;
_test_eof41: cs = 41; goto _test_eof;
_test_eof42: cs = 42; goto _test_eof;
_test_eof43: cs = 43; goto _test_eof;
+ _test_eof44: cs = 44; goto _test_eof;
+ _test_eof45: cs = 45; goto _test_eof;
+ _test_eof46: cs = 46; goto _test_eof;
+ _test_eof47: cs = 47; goto _test_eof;
+ _test_eof48: cs = 48; goto _test_eof;
+ _test_eof49: cs = 49; goto _test_eof;
+ _test_eof50: cs = 50; goto _test_eof;
+ _test_eof51: cs = 51; goto _test_eof;
+ _test_eof52: cs = 52; goto _test_eof;
+ _test_eof53: cs = 53; goto _test_eof;
+ _test_eof54: cs = 54; goto _test_eof;
+ _test_eof55: cs = 55; goto _test_eof;
+ _test_eof56: cs = 56; goto _test_eof;
+ _test_eof57: cs = 57; goto _test_eof;
+ _test_eof58: cs = 58; goto _test_eof;
+ _test_eof59: cs = 59; goto _test_eof;
+ _test_eof60: cs = 60; goto _test_eof;
+ _test_eof61: cs = 61; goto _test_eof;
+ _test_eof62: cs = 62; goto _test_eof;
+ _test_eof63: cs = 63; goto _test_eof;
+ _test_eof64: cs = 64; goto _test_eof;
+ _test_eof65: cs = 65; goto _test_eof;
+ _test_eof66: cs = 66; goto _test_eof;
+ _test_eof67: cs = 67; goto _test_eof;
+ _test_eof68: cs = 68; goto _test_eof;
+ _test_eof69: cs = 69; goto _test_eof;
+ _test_eof70: cs = 70; goto _test_eof;
+ _test_eof71: cs = 71; goto _test_eof;
+ _test_eof72: cs = 72; goto _test_eof;
+ _test_eof73: cs = 73; goto _test_eof;
+ _test_eof74: cs = 74; goto _test_eof;
+ _test_eof75: cs = 75; goto _test_eof;
+ _test_eof76: cs = 76; goto _test_eof;
+ _test_eof77: cs = 77; goto _test_eof;
+ _test_eof78: cs = 78; goto _test_eof;
+ _test_eof79: cs = 79; goto _test_eof;
+ _test_eof80: cs = 80; goto _test_eof;
+ _test_eof81: cs = 81; goto _test_eof;
+ _test_eof82: cs = 82; goto _test_eof;
+ _test_eof83: cs = 83; goto _test_eof;
+ _test_eof84: cs = 84; goto _test_eof;
+ _test_eof85: cs = 85; goto _test_eof;
+ _test_eof86: cs = 86; goto _test_eof;
+ _test_eof87: cs = 87; goto _test_eof;
+ _test_eof88: cs = 88; goto _test_eof;
+ _test_eof89: cs = 89; goto _test_eof;
+ _test_eof90: cs = 90; goto _test_eof;
+ _test_eof91: cs = 91; goto _test_eof;
+ _test_eof92: cs = 92; goto _test_eof;
+ _test_eof93: cs = 93; goto _test_eof;
+ _test_eof94: cs = 94; goto _test_eof;
+ _test_eof95: cs = 95; goto _test_eof;
+ _test_eof96: cs = 96; goto _test_eof;
+ _test_eof97: cs = 97; goto _test_eof;
+ _test_eof98: cs = 98; goto _test_eof;
+ _test_eof99: cs = 99; goto _test_eof;
+ _test_eof100: cs = 100; goto _test_eof;
+ _test_eof101: cs = 101; goto _test_eof;
+ _test_eof102: cs = 102; goto _test_eof;
+ _test_eof103: cs = 103; goto _test_eof;
+ _test_eof104: cs = 104; goto _test_eof;
+ _test_eof105: cs = 105; goto _test_eof;
+ _test_eof106: cs = 106; goto _test_eof;
+ _test_eof107: cs = 107; goto _test_eof;
+ _test_eof108: cs = 108; goto _test_eof;
+ _test_eof109: cs = 109; goto _test_eof;
+ _test_eof110: cs = 110; goto _test_eof;
+ _test_eof111: cs = 111; goto _test_eof;
+ _test_eof112: cs = 112; goto _test_eof;
+ _test_eof113: cs = 113; goto _test_eof;
+ _test_eof135: cs = 135; goto _test_eof;
+ _test_eof114: cs = 114; goto _test_eof;
+ _test_eof115: cs = 115; goto _test_eof;
+ _test_eof116: cs = 116; goto _test_eof;
+ _test_eof117: cs = 117; goto _test_eof;
+ _test_eof118: cs = 118; goto _test_eof;
+ _test_eof119: cs = 119; goto _test_eof;
+ _test_eof120: cs = 120; goto _test_eof;
+ _test_eof121: cs = 121; goto _test_eof;
+ _test_eof122: cs = 122; goto _test_eof;
+ _test_eof123: cs = 123; goto _test_eof;
+ _test_eof124: cs = 124; goto _test_eof;
+ _test_eof125: cs = 125; goto _test_eof;
+ _test_eof126: cs = 126; goto _test_eof;
+ _test_eof127: cs = 127; goto _test_eof;
+ _test_eof128: cs = 128; goto _test_eof;
+ _test_eof129: cs = 129; goto _test_eof;
+ _test_eof136: cs = 136; goto _test_eof;
+ _test_eof130: cs = 130; goto _test_eof;
+ _test_eof131: cs = 131; goto _test_eof;
+ _test_eof132: cs = 132; goto _test_eof;
+ _test_eof133: cs = 133; goto _test_eof;
_test_eof: {}
_out: {}
}
-#line 403 "kcar.rl"
+#line 721 "kcar.rl"
post_exec: /* "_out:" also goes here */
if (hp->cs != http_parser_error)
hp->cs = cs;
- hp->offset = p - buffer;
+ hp->offset = ulong2uint(p - buffer);
assert(p <= pe && "buffer overflow after parsing execute");
assert(hp->offset <= len && "offset longer than length");
}
-static struct http_parser *data_get(VALUE self)
+static void kcar_mark(void *ptr)
{
- struct http_parser *hp;
+ struct http_parser *hp = ptr;
- Data_Get_Struct(self, struct http_parser, hp);
- assert(hp && "failed to extract http_parser struct");
- return hp;
+ rb_gc_mark(hp->cont);
+ rb_gc_mark(hp->v.status);
}
-static void mark(void *ptr)
+static size_t kcar_memsize(const void *ptr)
{
- struct http_parser *hp = ptr;
+ return sizeof(struct http_parser);
+}
- rb_gc_mark(hp->cont);
- rb_gc_mark(hp->status);
+static const rb_data_type_t kcar_type = {
+ "kcar_parser",
+ { kcar_mark, RUBY_TYPED_DEFAULT_FREE, kcar_memsize, /* reserved */ },
+ /* parent, data, [ flags ] */
+};
+
+static VALUE kcar_alloc(VALUE klass)
+{
+ struct http_parser *hp;
+ return TypedData_Make_Struct(klass, struct http_parser, &kcar_type, hp);
}
-static VALUE alloc(VALUE klass)
+static struct http_parser *data_get(VALUE self)
{
struct http_parser *hp;
- return Data_Make_Struct(klass, struct http_parser, mark, -1, hp);
+
+ TypedData_Get_Struct(self, struct http_parser, &kcar_type, hp);
+ assert(hp && "failed to extract http_parser struct");
+ return hp;
}
+
/**
* call-seq:
* Kcar::Parser.new => parser
*
* Creates a new parser.
@@ -1357,11 +3935,11 @@
*/
static VALUE body_bytes_left(VALUE self)
{
struct http_parser *hp = data_get(self);
- if (HP_FL_TEST(hp, CHUNKED))
+ if (hp->chunked)
return Qnil;
if (hp->len.content >= 0)
return OFFT2NUM(hp->len.content);
return Qnil;
@@ -1377,13 +3955,15 @@
*/
static VALUE body_bytes_left_set(VALUE self, VALUE bytes)
{
struct http_parser *hp = data_get(self);
- if (HP_FL_TEST(hp, CHUNKED))
+ if (hp->chunked)
rb_raise(rb_eRuntimeError, "body_bytes_left= is not for chunked bodies");
hp->len.content = NUM2OFFT(bytes);
+ if (hp->len.content == 0)
+ hp->body_eof_seen = 1;
return bytes;
}
/**
* Document-method: chunked
@@ -1394,13 +3974,36 @@
*/
static VALUE chunked(VALUE self)
{
struct http_parser *hp = data_get(self);
- return HP_FL_TEST(hp, CHUNKED) ? Qtrue : Qfalse;
+ return hp->chunked ? Qtrue : Qfalse;
}
+static void check_buffer_size(long dlen)
+{
+ if ((uint64_t)dlen > UINT_MAX)
+ rb_raise(rb_eRangeError, "headers too large to process (%ld bytes)", dlen);
+}
+
+static void parser_execute(struct http_parser *hp, VALUE hdr, VALUE buf)
+{
+ char *ptr;
+ long len;
+
+ Check_Type(buf, T_STRING);
+ rb_str_modify(buf);
+ ptr = RSTRING_PTR(buf);
+ len = RSTRING_LEN(buf);
+ check_buffer_size(len);
+
+ http_parser_execute(hp, hdr, ptr, len);
+
+ if (hp->cs == http_parser_error)
+ rb_raise(eParserError, "Invalid HTTP format, parsing fails.");
+}
+
/**
* Document-method: headers
* call-seq:
* parser.headers(hdr, data) => hdr or nil
*
@@ -1413,32 +4016,53 @@
*/
static VALUE headers(VALUE self, VALUE hdr, VALUE data)
{
struct http_parser *hp = data_get(self);
- http_parser_execute(hp, hdr, RSTRING_PTR(data), RSTRING_LEN(data));
+ if (hp->is_request)
+ rb_raise(rb_eRuntimeError, "parser is handling a request, not response");
+
+ parser_execute(hp, hdr, data);
VALIDATE_MAX_LENGTH(hp->offset, HEADER);
if (hp->cs == http_parser_first_final ||
hp->cs == http_parser_en_ChunkedBody) {
advance_str(data, hp->offset + 1);
hp->offset = 0;
- if (HP_FL_TEST(hp, INTRAILER))
+ if (hp->in_trailer)
return hdr;
else
- return rb_ary_new3(2, hp->status, hdr);
+ return rb_ary_new3(2, hp->v.status, hdr);
}
- if (hp->cs == http_parser_error)
- rb_raise(eParserError, "Invalid HTTP format, parsing fails.");
-
return Qnil;
}
+static VALUE request(VALUE self, VALUE env, VALUE buf)
+{
+ struct http_parser *hp = data_get(self);
+
+ hp->is_request = 1;
+ Check_Type(buf, T_STRING);
+ parser_execute(hp, env, buf);
+
+ if (hp->cs == http_parser_first_final ||
+ hp->cs == http_parser_en_ChunkedBody) {
+ advance_str(buf, hp->offset + 1);
+ hp->offset = 0;
+ if (hp->in_trailer)
+ hp->body_eof_seen = 1;
+
+ return env;
+ }
+ return Qnil; /* incomplete */
+}
+
+
static int chunked_eof(struct http_parser *hp)
{
- return ((hp->cs == http_parser_first_final) || HP_FL_TEST(hp, INTRAILER));
+ return ((hp->cs == http_parser_first_final) || hp->in_trailer);
}
/**
* call-seq:
* parser.body_eof? => true or false
@@ -1448,17 +4072,17 @@
*/
static VALUE body_eof(VALUE self)
{
struct http_parser *hp = data_get(self);
- if (!HP_FL_TEST(hp, HASHEADER) && HP_FL_ALL(hp, KEEPALIVE))
+ if (!hp->has_header && hp->persistent)
return Qtrue;
- if (HP_FL_TEST(hp, CHUNKED))
+ if (hp->chunked)
return chunked_eof(hp) ? Qtrue : Qfalse;
- if (! HP_FL_TEST(hp, HASBODY))
+ if (!hp->has_body)
return Qtrue;
return hp->len.content == 0 ? Qtrue : Qfalse;
}
@@ -1476,14 +4100,18 @@
*/
static VALUE keepalive(VALUE self)
{
struct http_parser *hp = data_get(self);
- if (HP_FL_ALL(hp, KEEPALIVE)) {
- if (HP_FL_TEST(hp, HASHEADER) && HP_FL_TEST(hp, HASBODY) ) {
- if (HP_FL_TEST(hp, CHUNKED) || (hp->len.content >= 0))
- return Qtrue;
+ if (hp->persistent) {
+ if (hp->has_header && hp->has_body) {
+ if (hp->chunked || (hp->len.content >= 0)) {
+ if (!hp->is_request)
+ return Qtrue;
+ else
+ return hp->body_eof_seen ? Qtrue : Qfalse;
+ }
/* unknown Content-Length and not chunked, we must assume close */
return Qfalse;
} else {
/* 100 Continue, 304 Not Modified, etc... */
@@ -1493,70 +4121,103 @@
return Qfalse;
}
/**
* call-seq:
- * parser.filter_body(buf, data) => nil/data
+ * parser.filter_body(dst, src) => nil/dst
*
- * Takes a String of +data+, will modify data if dechunking is done.
- * Returns +nil+ if there is more data left to process. Returns
- * +data+ if body processing is complete. When returning +data+,
- * it may modify +data+ so the start of the string points to where
+ * Takes a String of +src+, will modify src if dechunking is done.
+ * Returns +nil+ if there is more +src+ left to process. Returns
+ * +dst+ if body processing is complete. When returning +dst+,
+ * it may modify +src+ so the start of the string points to where
* the body ended so that trailer processing can begin.
*
* Raises ParserError if there are dechunking errors.
- * Basically this is a glorified memcpy(3) that copies +data+
- * into +buf+ while filtering it through the dechunker.
+ * Basically this is a glorified memcpy(3) that copies +src+
+ * into +dst+ while filtering it through the dechunker.
*/
-static VALUE filter_body(VALUE self, VALUE buf, VALUE data)
+static VALUE filter_body(VALUE self, VALUE dst, VALUE src)
{
struct http_parser *hp = data_get(self);
- char *dptr;
- long dlen;
+ char *sptr;
+ long slen;
- dptr = RSTRING_PTR(data);
- dlen = RSTRING_LEN(data);
+ sptr = RSTRING_PTR(src);
+ slen = RSTRING_LEN(src);
+ check_buffer_size(slen);
- StringValue(buf);
- rb_str_modify(buf);
- rb_str_resize(buf, dlen); /* we can never copy more than dlen bytes */
- OBJ_TAINT(buf); /* keep weirdo $SAFE users happy */
+ StringValue(dst);
+ rb_str_modify(dst);
+ OBJ_TAINT(dst); /* keep weirdo $SAFE users happy */
- if (!HP_FL_TEST(hp, CHUNKED))
+ /*
+ * for now, only support filter_body for identity requests,
+ * not responses; it's rather inefficient to blindly memcpy
+ * giant request bodies; on the other hand, it simplifies
+ * server-side code.
+ */
+ if (hp->is_request && !hp->chunked) {
+ /* no need to enter the Ragel machine for unchunked transfers */
+ assert(hp->len.content >= 0 && "negative Content-Length");
+ if (hp->len.content > 0) {
+ long nr = MIN(slen, hp->len.content);
+
+ rb_str_resize(dst, nr);
+ memcpy(RSTRING_PTR(dst), sptr, nr);
+ hp->len.content -= nr;
+ if (hp->len.content == 0)
+ hp->body_eof_seen = 1;
+ advance_str(src, nr);
+ }
+ return dst;
+ }
+
+ if (!hp->chunked)
rb_raise(rb_eRuntimeError, "filter_body is only for chunked bodies");
+ rb_str_resize(dst, slen); /* we can never copy more than slen bytes */
if (!chunked_eof(hp)) {
hp->s.dest_offset = 0;
- http_parser_execute(hp, buf, dptr, dlen);
+ http_parser_execute(hp, dst, sptr, slen);
if (hp->cs == http_parser_error)
rb_raise(eParserError, "Invalid HTTP format, parsing fails.");
assert(hp->s.dest_offset <= hp->offset &&
"destination buffer overflow");
- advance_str(data, hp->offset);
- rb_str_set_len(buf, hp->s.dest_offset);
+ advance_str(src, hp->offset);
+ rb_str_set_len(dst, hp->s.dest_offset);
- if (RSTRING_LEN(buf) == 0 && chunked_eof(hp)) {
+ if (RSTRING_LEN(dst) == 0 && chunked_eof(hp)) {
assert(hp->len.chunk == 0 && "chunk at EOF but more to parse");
} else {
- data = Qnil;
+ dst = Qnil;
}
}
hp->offset = 0; /* for trailer parsing */
- return data;
+ return dst;
}
void Init_kcar_ext(void)
{
VALUE mKcar = rb_define_module("Kcar");
VALUE cParser = rb_define_class_under(mKcar, "Parser", rb_cObject);
+ /*
+ * Document-class: Kcar::ParserError
+ *
+ * This is raised if there are parsing errors.
+ */
eParserError = rb_define_class_under(mKcar, "ParserError", rb_eIOError);
+ e413 = rb_define_class_under(mKcar, "RequestEntityTooLargeError",
+ eParserError);
+ e414 = rb_define_class_under(mKcar, "RequestURITooLongError",
+ eParserError);
- rb_define_alloc_func(cParser, alloc);
+ rb_define_alloc_func(cParser, kcar_alloc);
rb_define_method(cParser, "initialize", initialize, 0);
rb_define_method(cParser, "reset", initialize, 0);
+ rb_define_method(cParser, "request", request, 2);
rb_define_method(cParser, "headers", headers, 2);
rb_define_method(cParser, "trailers", headers, 2);
rb_define_method(cParser, "filter_body", filter_body, 2);
rb_define_method(cParser, "body_bytes_left", body_bytes_left, 0);
rb_define_method(cParser, "body_bytes_left=", body_bytes_left_set, 1);
@@ -1578,6 +4239,36 @@
* to the limits of the file system used for +Dir.tmpdir+.
*/
rb_define_const(cParser, "LENGTH_MAX", OFFT2NUM(UH_OFF_T_MAX));
id_sq = rb_intern("[]");
id_sq_set = rb_intern("[]=");
+ id_uminus = rb_intern("-@");
+
+ /* TODO: gperf to make a perfect hash of common strings */
+#define C(var, cstr) do { \
+ var = str_new_dd_freeze((cstr), sizeof(cstr) - 1); \
+ rb_gc_register_mark_object((var)); \
+} while (0);
+
+ C(g_CONTENT_LENGTH, "CONTENT_LENGTH");
+ C(g_CONTENT_TYPE, "CONTENT_TYPE");
+ C(g_FRAGMENT, "FRAGMENT");
+ C(g_HTTP_HOST, "HTTP_HOST");
+ C(g_HTTP_CONNECTION, "HTTP_CONNECTION");
+ C(g_HTTP_TRAILER, "HTTP_TRAILER");
+ C(g_HTTP_TRANSFER_ENCODING, "HTTP_TRANSFER_ENCODING");
+ C(g_HTTP_VERSION, "HTTP_VERSION");
+ C(g_PATH_INFO, "PATH_INFO");
+ C(g_QUERY_STRING, "QUERY_STRING");
+ C(g_REQUEST_METHOD, "REQUEST_METHOD");
+ C(g_REQUEST_PATH, "REQUEST_PATH");
+ C(g_REQUEST_URI, "REQUEST_URI");
+ C(g_SERVER_NAME, "SERVER_NAME");
+ C(g_SERVER_PORT, "SERVER_PORT");
+ C(g_SERVER_PROTOCOL, "SERVER_PROTOCOL");
+ C(g_rack_url_scheme, "rack.url_scheme");
+ C(g_http, "http");
+ C(g_https, "https");
+ C(g_80, "80");
+ C(g_443, "443");
+#undef C
}