Changeset 995

Show
Ignore:
Timestamp:
03/23/08 22:48:10 (7 months ago)
Author:
evanweaver
Message:

Backport Eric's changes to the http parser from trunk (Eric Wong).
Apply fix for Ragel 6 (Eric Wong, Ry Dahl).

Two tests fail with the new parser (1 failed with the old parser). Needs investigation.

Close #12 (mongrel_rails send_signal leaves a filehandle open until gc).
Close #14 (mongrel_rails command line option --num-procs does not change the max number of procs).
Close #15 (mongrel squashes helpful exception in register method).
Close #16, XXX needs audit! (CGIWrapper "options" attr_reader has no corresponding @options variable).
Close #20 (Mongrel doesn't erase temporary files during it's operation on windows).
Close #19, XXX needs audit! (HttpResponse#reset? does not properly reset HeaderOut?).
Close #22 (gem_plugin should load gems from Gem.path not Gem.dir).
Close #23 (mongrel_cluster's mongrel_rails configuration option isn't fully respected).

If I had git, being offline wouldn't have resulted in one massive commit.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/stable_1-2/Rakefile

    r985 r995  
    5454    target = "http11_parser.c" 
    5555    File.unlink target if File.exist? target 
    56     sh "ragel http11_parser.rl | rlgen-cd -G2 -o #{target}" 
     56    sh "ragel http11_parser.rl -C -G2 -o #{target}" 
    5757    raise "Failed to build C source" unless File.exist? target 
    5858  end 
     
    6060    target = "../../ext/http11_java/org/jruby/mongrel/Http11Parser.java" 
    6161    File.unlink target if File.exist? target 
    62     sh "ragel -J http11_parser.java.rl | rlgen-java -o #{target}" 
     62    sh "ragel http11_parser.rl -J -o #{target}" 
    6363    raise "Failed to build Java source" unless File.exist? target 
    6464  end 
  • branches/stable_1-2/bin/mongrel_rails

    r877 r995  
    195195 
    196196  def Mongrel::send_signal(signal, pid_file) 
    197     pid = open(pid_file).read.to_i 
     197    pid = File.read(pid_file).to_i  
    198198    print "Sending #{signal} to Mongrel at PID #{pid}..." 
    199199    begin 
  • branches/stable_1-2/ext/http11/ext_help.h

    r4 r995  
    55#define DATA_GET(from,type,name) Data_Get_Struct(from,type,name); RAISE_NOT_NULL(name); 
    66#define REQUIRE_TYPE(V, T) if(TYPE(V) != T) rb_raise(rb_eTypeError, "Wrong argument type for " # V " required " # T); 
     7#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) 
    78 
    89#ifdef DEBUG 
  • branches/stable_1-2/ext/http11/http11.c

    r980 r995  
    88#include <string.h> 
    99#include "http11_parser.h" 
    10 #include <ctype.h> 
     10 
     11#ifndef RSTRING_PTR 
     12#define RSTRING_PTR(s) (RSTRING(s)->ptr) 
     13#endif 
     14#ifndef RSTRING_LEN 
     15#define RSTRING_LEN(s) (RSTRING(s)->len) 
     16#endif 
    1117 
    1218static VALUE mMongrel; 
     
    1622#define id_handler_map rb_intern("@handler_map") 
    1723#define id_http_body rb_intern("@http_body") 
    18  
    19 static VALUE global_http_prefix; 
     24#define HTTP_PREFIX "HTTP_" 
     25#define HTTP_PREFIX_LEN (sizeof(HTTP_PREFIX) - 1) 
     26 
    2027static VALUE global_request_method; 
    2128static VALUE global_request_uri; 
     
    6067DEF_MAX_LENGTH(HEADER, (1024 * (80 + 32))); 
    6168 
     69struct common_field { 
     70        const signed long len; 
     71        const char *name; 
     72        VALUE value; 
     73}; 
     74 
     75/* 
     76 * A list of common HTTP headers we expect to receive. 
     77 * This allows us to avoid repeatedly creating identical string 
     78 * objects to be used with rb_hash_aset(). 
     79 */ 
     80static struct common_field common_http_fields[] = { 
     81# define f(N) { (sizeof(N) - 1), N, Qnil } 
     82        f("ACCEPT"), 
     83        f("ACCEPT_CHARSET"), 
     84        f("ACCEPT_ENCODING"), 
     85        f("ACCEPT_LANGUAGE"), 
     86        f("ALLOW"), 
     87        f("AUTHORIZATION"), 
     88        f("CACHE_CONTROL"), 
     89        f("CONNECTION"), 
     90        f("CONTENT_ENCODING"), 
     91        f("CONTENT_LENGTH"), 
     92        f("CONTENT_TYPE"), 
     93        f("COOKIE"), 
     94        f("DATE"), 
     95        f("EXPECT"), 
     96        f("FROM"), 
     97        f("HOST"), 
     98        f("IF_MATCH"), 
     99        f("IF_MODIFIED_SINCE"), 
     100        f("IF_NONE_MATCH"), 
     101        f("IF_RANGE"), 
     102        f("IF_UNMODIFIED_SINCE"), 
     103        f("KEEP_ALIVE"), /* Firefox sends this */ 
     104        f("MAX_FORWARDS"), 
     105        f("PRAGMA"), 
     106        f("PROXY_AUTHORIZATION"), 
     107        f("RANGE"), 
     108        f("REFERER"), 
     109        f("TE"), 
     110        f("TRAILER"), 
     111        f("TRANSFER_ENCODING"), 
     112        f("UPGRADE"), 
     113        f("USER_AGENT"), 
     114        f("VIA"), 
     115        f("X_FORWARDED_FOR"), /* common for proxies */ 
     116        f("X_REAL_IP"), /* common for proxies */ 
     117        f("WARNING") 
     118# undef f 
     119}; 
     120 
     121/* 
     122 * qsort(3) and bsearch(3) improve average performance slightly, but may 
     123 * not be worth it for lack of portability to certain platforms... 
     124 */ 
     125#if defined(HAVE_QSORT_BSEARCH) 
     126/* sort by length, then by name if there's a tie */ 
     127static int common_field_cmp(const void *a, const void *b) 
     128{ 
     129  struct common_field *cfa = (struct common_field *)a; 
     130  struct common_field *cfb = (struct common_field *)b; 
     131  signed long diff = cfa->len - cfb->len; 
     132  return diff ? diff : memcmp(cfa->name, cfb->name, cfa->len); 
     133} 
     134#endif /* HAVE_QSORT_BSEARCH */ 
     135 
     136static void init_common_fields(void) 
     137{ 
     138  int i; 
     139  struct common_field *cf = common_http_fields; 
     140  char tmp[256]; /* MAX_FIELD_NAME_LENGTH */ 
     141  memcpy(tmp, HTTP_PREFIX, HTTP_PREFIX_LEN); 
     142 
     143  for(i = 0; i < ARRAY_SIZE(common_http_fields); cf++, i++) { 
     144    memcpy(tmp + HTTP_PREFIX_LEN, cf->name, cf->len + 1); 
     145    cf->value = rb_obj_freeze(rb_str_new(tmp, HTTP_PREFIX_LEN + cf->len)); 
     146    rb_global_variable(&cf->value); 
     147  } 
     148 
     149#if defined(HAVE_QSORT_BSEARCH) 
     150  qsort(common_http_fields, 
     151        ARRAY_SIZE(common_http_fields), 
     152        sizeof(struct common_field), 
     153        common_field_cmp); 
     154#endif /* HAVE_QSORT_BSEARCH */ 
     155} 
     156 
     157static VALUE find_common_field_value(const char *field, size_t flen) 
     158{ 
     159#if defined(HAVE_QSORT_BSEARCH) 
     160  struct common_field key; 
     161  struct common_field *found; 
     162  key.name = field; 
     163  key.len = (signed long)flen; 
     164  found = (struct common_field *)bsearch(&key, common_http_fields, 
     165                                         ARRAY_SIZE(common_http_fields), 
     166                                         sizeof(struct common_field), 
     167                                         common_field_cmp); 
     168  return found ? found->value : Qnil; 
     169#else /* !HAVE_QSORT_BSEARCH */ 
     170  int i; 
     171  struct common_field *cf = common_http_fields; 
     172  for(i = 0; i < ARRAY_SIZE(common_http_fields); i++, cf++) { 
     173    if (cf->len == flen && !memcmp(cf->name, field, flen)) 
     174      return cf->value; 
     175  } 
     176  return Qnil; 
     177#endif /* !HAVE_QSORT_BSEARCH */ 
     178} 
    62179 
    63180void http_field(void *data, const char *field, size_t flen, const char *value, size_t vlen) 
    64181{ 
    65   char *ch, *end; 
    66182  VALUE req = (VALUE)data; 
    67183  VALUE v = Qnil; 
     
    72188 
    73189  v = rb_str_new(value, vlen); 
    74   f = rb_str_dup(global_http_prefix); 
    75   f = rb_str_buf_cat(f, field, flen);  
    76  
    77   for(ch = RSTRING(f)->ptr, end = ch + RSTRING(f)->len; ch < end; ch++) { 
    78     if(*ch == '-') { 
    79       *ch = '_'; 
    80     } else { 
    81       *ch = toupper(*ch); 
    82     } 
     190 
     191  f = find_common_field_value(field, flen); 
     192 
     193  if (f == Qnil) { 
     194    /* 
     195     * We got a strange header that we don't have a memoized value for. 
     196     * Fallback to creating a new string to use as a hash key. 
     197     * 
     198     * using rb_str_new(NULL, len) here is faster than rb_str_buf_new(len) 
     199     * in my testing, because: there's no minimum allocation length (and 
     200     * no check for it, either), RSTRING_LEN(f) does not need to be 
     201     * written twice, and and RSTRING_PTR(f) will already be 
     202     * null-terminated for us. 
     203     */ 
     204    f = rb_str_new(NULL, HTTP_PREFIX_LEN + flen); 
     205    memcpy(RSTRING_PTR(f), HTTP_PREFIX, HTTP_PREFIX_LEN); 
     206    memcpy(RSTRING_PTR(f) + HTTP_PREFIX_LEN, field, flen); 
     207    assert(*(RSTRING_PTR(f) + RSTRING_LEN(f)) == '\0'); /* paranoia */ 
     208    /* fprintf(stderr, "UNKNOWN HEADER <%s>\n", RSTRING_PTR(f)); */ 
    83209  } 
    84210 
     
    169295  rb_hash_aset(req, global_gateway_interface, global_gateway_interface_value); 
    170296  if((temp = rb_hash_aref(req, global_http_host)) != Qnil) { 
    171     /* ruby better close strings off with a '\0' dammit */ 
    172     colon = strchr(RSTRING(temp)->ptr, ':'); 
     297    colon = memchr(RSTRING_PTR(temp), ':', RSTRING_LEN(temp)); 
    173298    if(colon != NULL) { 
    174       rb_hash_aset(req, global_server_name, rb_str_substr(temp, 0, colon - RSTRING(temp)->ptr)); 
     299      rb_hash_aset(req, global_server_name, rb_str_substr(temp, 0, colon - RSTRING_PTR(temp))); 
    175300      rb_hash_aset(req, global_server_port,  
    176           rb_str_substr(temp, colon - RSTRING(temp)->ptr+1,  
    177             RSTRING(temp)->len)); 
     301          rb_str_substr(temp, colon - RSTRING_PTR(temp)+1,  
     302            RSTRING_LEN(temp))); 
    178303    } else { 
    179304      rb_hash_aset(req, global_server_name, temp); 
     
    296421 
    297422  from = FIX2INT(start); 
    298   dptr = RSTRING(data)->ptr
    299   dlen = RSTRING(data)->len
     423  dptr = RSTRING_PTR(data)
     424  dlen = RSTRING_LEN(data)
    300425 
    301426  if(from >= dlen) { 
     
    367492  mMongrel = rb_define_module("Mongrel"); 
    368493 
    369   DEF_GLOBAL(http_prefix, "HTTP_"); 
    370494  DEF_GLOBAL(request_method, "REQUEST_METHOD"); 
    371495  DEF_GLOBAL(request_uri, "REQUEST_URI"); 
     
    385509  DEF_GLOBAL(server_protocol_value, "HTTP/1.1"); 
    386510  DEF_GLOBAL(http_host, "HTTP_HOST"); 
    387   DEF_GLOBAL(mongrel_version, "Mongrel 1.2.0"); /* XXX Why is this defined here? */ 
     511  DEF_GLOBAL(mongrel_version, "Mongrel 1.2"); /* XXX Why is this defined here? */ 
    388512  DEF_GLOBAL(server_software, "SERVER_SOFTWARE"); 
    389513  DEF_GLOBAL(port_80, "80"); 
     
    400524  rb_define_method(cHttpParser, "finished?", HttpParser_is_finished,0); 
    401525  rb_define_method(cHttpParser, "nread", HttpParser_nread,0); 
    402 
     526  init_common_fields(); 
     527
  • branches/stable_1-2/ext/http11/http11_parser.c

    r675 r995  
    1111#include <string.h> 
    1212 
     13/* 
     14 * capitalizes all lower-case ASCII characters, 
     15 * converts dashes to underscores. 
     16 */ 
     17static void snake_upcase_char(char *c) 
     18{ 
     19    if (*c >= 'a' && *c <= 'z') 
     20      *c &= ~0x20; 
     21    else if (*c == '-') 
     22      *c = '_'; 
     23} 
     24 
    1325#define LEN(AT, FPC) (FPC - buffer - parser->AT) 
    1426#define MARK(M,FPC) (parser->M = (FPC) - buffer) 
     
    1729/** Machine **/ 
    1830 
    19 #line 74 "http11_parser.rl" 
     31#line 87 "http11_parser.rl" 
    2032 
    2133 
    2234/** Data **/ 
    2335 
    24 #line 25 "http11_parser.c" 
     36#line 37 "http11_parser.c" 
    2537static const int http_parser_start = 1; 
    2638static const int http_parser_first_final = 57; 
     
    2941static const int http_parser_en_main = 1; 
    3042 
    31 #line 78 "http11_parser.rl" 
     43#line 91 "http11_parser.rl" 
    3244 
    3345int http_parser_init(http_parser *parser)  { 
    3446  int cs = 0; 
    3547   
    36 #line 37 "http11_parser.c" 
     48#line 49 "http11_parser.c" 
    3749        { 
    3850        cs = http_parser_start; 
    3951        } 
    40 #line 82 "http11_parser.rl" 
     52#line 95 "http11_parser.rl" 
    4153  parser->cs = cs; 
    4254  parser->body_start = 0; 
     
    6173  pe = buffer+len; 
    6274 
    63   assert(*pe == '\0' && "pointer does not end on NUL"); 
     75  /* assert(*pe == '\0' && "pointer does not end on NUL"); */ 
    6476  assert(pe - p == len - off && "pointers aren't same distance"); 
    6577 
    6678 
    6779   
    68 #line 69 "http11_parser.c" 
     80#line 81 "http11_parser.c" 
    6981        { 
    7082        if ( p == pe ) 
    71                 goto _out
     83                goto _test_eof
    7284        switch ( cs ) 
    7385        { 
     
    8799        goto st0; 
    88100st0: 
    89         goto _out0; 
     101cs = 0; 
     102        goto _out; 
    90103tr0: 
    91 #line 22 "http11_parser.rl" 
     104#line 34 "http11_parser.rl" 
    92105        {MARK(mark, p); } 
    93106        goto st2; 
    94107st2: 
    95108        if ( ++p == pe ) 
    96                 goto _out2; 
     109                goto _test_eof2; 
    97110case 2: 
    98 #line 99 "http11_parser.c" 
     111#line 112 "http11_parser.c" 
    99112        switch( (*p) ) { 
    100113                case 32: goto tr2; 
     
    112125        goto st0; 
    113126tr2: 
    114 #line 36 "http11_parser.rl" 
     127#line 49 "http11_parser.rl" 
    115128        {  
    116129    if(parser->request_method != NULL)  
     
    120133st3: 
    121134        if ( ++p == pe ) 
    122                 goto _out3; 
     135                goto _test_eof3; 
    123136case 3: 
    124 #line 125 "http11_parser.c" 
     137#line 138 "http11_parser.c" 
    125138        switch( (*p) ) { 
    126139                case 42: goto tr4; 
     
    139152        goto st0; 
    140153tr4: 
    141 #line 22 "http11_parser.rl" 
     154#line 34 "http11_parser.rl" 
    142155        {MARK(mark, p); } 
    143156        goto st4; 
    144157st4: 
    145158        if ( ++p == pe ) 
    146                 goto _out4; 
     159                goto _test_eof4; 
    147160case 4: 
    148 #line 149 "http11_parser.c" 
     161#line 162 "http11_parser.c" 
    149162        switch( (*p) ) { 
    150163                case 32: goto tr8; 
     
    153166        goto st0; 
    154167tr8: 
    155 #line 40 "http11_parser.rl" 
     168#line 53 "http11_parser.rl" 
    156169        {  
    157170    if(parser->request_uri != NULL) 
     
    159172  } 
    160173        goto st5; 
    161 tr30: 
    162 #line 44 "http11_parser.rl" 
     174tr31: 
     175#line 34 "http11_parser.rl" 
     176        {MARK(mark, p); } 
     177#line 57 "http11_parser.rl" 
    163178        {  
    164179    if(parser->fragment != NULL) 
     
    166181  } 
    167182        goto st5; 
    168 tr40: 
    169 #line 60 "http11_parser.rl" 
     183tr34: 
     184#line 57 "http11_parser.rl" 
     185        {  
     186    if(parser->fragment != NULL) 
     187      parser->fragment(parser->data, PTR_TO(mark), LEN(mark, p)); 
     188  } 
     189        goto st5; 
     190tr42: 
     191#line 73 "http11_parser.rl" 
    170192        { 
    171193    if(parser->request_path != NULL) 
    172194      parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p)); 
    173195  } 
    174 #line 40 "http11_parser.rl" 
     196#line 53 "http11_parser.rl" 
    175197        {  
    176198    if(parser->request_uri != NULL) 
     
    178200  } 
    179201        goto st5; 
    180 tr51
    181 #line 49 "http11_parser.rl" 
     202tr53
     203#line 62 "http11_parser.rl" 
    182204        {MARK(query_start, p); } 
    183 #line 50 "http11_parser.rl" 
     205#line 63 "http11_parser.rl" 
    184206        {  
    185207    if(parser->query_string != NULL) 
    186208      parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p)); 
    187209  } 
    188 #line 40 "http11_parser.rl" 
     210#line 53 "http11_parser.rl" 
    189211        {  
    190212    if(parser->request_uri != NULL) 
     
    192214  } 
    193215        goto st5; 
    194 tr55
    195 #line 50 "http11_parser.rl" 
     216tr57
     217#line 63 "http11_parser.rl" 
    196218        {  
    197219    if(parser->query_string != NULL) 
    198220      parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p)); 
    199221  } 
    200 #line 40 "http11_parser.rl" 
     222#line 53 "http11_parser.rl" 
    201223        {  
    202224    if(parser->request_uri != NULL) 
     
    206228st5: 
    207229        if ( ++p == pe ) 
    208                 goto _out5; 
     230                goto _test_eof5; 
    209231case 5: 
    210 #line 211 "http11_parser.c" 
     232#line 233 "http11_parser.c" 
    211233        if ( (*p) == 72 ) 
    212234                goto tr10; 
    213235        goto st0; 
    214236tr10: 
    215 #line 22 "http11_parser.rl" 
     237#line 34 "http11_parser.rl" 
    216238        {MARK(mark, p); } 
    217239        goto st6; 
    218240st6: 
    219241        if ( ++p == pe ) 
    220                 goto _out6; 
     242                goto _test_eof6; 
    221243case 6: 
    222 #line 223 "http11_parser.c" 
     244#line 245 "http11_parser.c" 
    223245        if ( (*p) == 84 ) 
    224246                goto st7; 
     
    226248st7: 
    227249        if ( ++p == pe ) 
    228                 goto _out7; 
     250                goto _test_eof7; 
    229251case 7: 
    230252        if ( (*p) == 84 ) 
     
    233255st8: 
    234256        if ( ++p == pe ) 
    235                 goto _out8; 
     257                goto _test_eof8; 
    236258case 8: 
    237259        if ( (*p) == 80 ) 
     
    240262st9: 
    241263        if ( ++p == pe ) 
    242                 goto _out9; 
     264                goto _test_eof9; 
    243265case 9: 
    244266        if ( (*p) == 47 ) 
     
    247269st10: 
    248270        if ( ++p == pe ) 
    249                 goto _out10; 
     271                goto _test_eof10; 
    250272case 10: 
    251273        if ( 48 <= (*p) && (*p) <= 57 ) 
     
    254276st11: 
    255277        if ( ++p == pe ) 
    256                 goto _out11; 
     278                goto _test_eof11; 
    257279case 11: 
    258280        if ( (*p) == 46 ) 
     
    263285st12: 
    264286        if ( ++p == pe ) 
    265                 goto _out12; 
     287                goto _test_eof12; 
    266288case 12: 
    267289        if ( 48 <= (*p) && (*p) <= 57 ) 
     
    270292st13: 
    271293        if ( ++p == pe ) 
    272                 goto _out13; 
     294                goto _test_eof13; 
    273295case 13: 
    274296        if ( (*p) == 13 ) 
     
    278300        goto st0; 
    279301tr18: 
    280 #line 55 "http11_parser.rl" 
     302#line 68 "http11_parser.rl" 
    281303        {        
    282304    if(parser->http_version != NULL) 
     
    285307        goto st14; 
    286308tr26: 
    287 #line 31 "http11_parser.rl" 
     309#line 43 "http11_parser.rl" 
     310        { MARK(mark, p); } 
     311#line 44 "http11_parser.rl" 
    288312        {  
    289313    if(parser->http_field != NULL) { 
     
    292316  } 
    293317        goto st14; 
     318tr29: 
     319#line 44 "http11_parser.rl" 
     320        {  
     321    if(parser->http_field != NULL) { 
     322      parser->http_field(parser->data, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, p)); 
     323    } 
     324  } 
     325        goto st14; 
    294326st14: 
    295327        if ( ++p == pe ) 
    296                 goto _out14; 
     328                goto _test_eof14; 
    297329case 14: 
    298 #line 299 "http11_parser.c" 
     330#line 331 "http11_parser.c" 
    299331        if ( (*p) == 10 ) 
    300332                goto st15; 
     
    302334st15: 
    303335        if ( ++p == pe ) 
    304                 goto _out15; 
     336                goto _test_eof15; 
    305337case 15: 
    306338        switch( (*p) ) { 
     
    330362st16: 
    331363        if ( ++p == pe ) 
    332                 goto _out16; 
     364                goto _test_eof16; 
    333365case 16: 
    334366        if ( (*p) == 10 ) 
     
    336368        goto st0; 
    337369tr22: 
    338 #line 65 "http11_parser.rl" 
     370#line 78 "http11_parser.rl" 
    339371        {  
    340372    parser->body_start = p - buffer + 1;  
    341373    if(parser->header_done != NULL) 
    342374      parser->header_done(parser->data, p + 1, pe - p - 1); 
    343     goto _out57; 
     375    {p++; cs = 57; goto _out;} 
    344376  } 
    345377        goto st57; 
    346378st57: 
    347379        if ( ++p == pe ) 
    348                 goto _out57; 
     380                goto _test_eof57; 
    349381case 57: 
    350 #line 351 "http11_parser.c" 
     382#line 383 "http11_parser.c" 
    351383        goto st0; 
    352384tr21: 
    353 #line 25 "http11_parser.rl" 
     385#line 37 "http11_parser.rl" 
    354386        { MARK(field_start, p); } 
     387#line 38 "http11_parser.rl" 
     388        { snake_upcase_char((char *)p); } 
     389        goto st17; 
     390tr23: 
     391#line 38 "http11_parser.rl" 
     392        { snake_upcase_char((char *)p); } 
    355393        goto st17; 
    356394st17: 
    357395        if ( ++p == pe ) 
    358                 goto _out17; 
     396                goto _test_eof17; 
    359397case 17: 
    360 #line 361 "http11_parser.c" 
    361         switch( (*p) ) { 
    362                 case 33: goto st17
     398#line 399 "http11_parser.c" 
     399        switch( (*p) ) { 
     400                case 33: goto tr23
    363401                case 58: goto tr24; 
    364                 case 124: goto st17
    365                 case 126: goto st17
     402                case 124: goto tr23
     403                case 126: goto tr23
    366404        } 
    367405        if ( (*p) < 45 ) { 
    368406                if ( (*p) > 39 ) { 
    369407                        if ( 42 <= (*p) && (*p) <= 43 ) 
    370                                 goto st17
     408                                goto tr23
    371409                } else if ( (*p) >= 35 ) 
    372                         goto st17
     410                        goto tr23
    373411        } else if ( (*p) > 46 ) { 
    374412                if ( (*p) < 65 ) { 
    375413                        if ( 48 <= (*p) && (*p) <= 57 ) 
    376                                 goto st17
     414                                goto tr23
    377415                } else if ( (*p) > 90 ) { 
    378416                        if ( 94 <= (*p) && (*p) <= 122 ) 
    379                                 goto st17
     417                                goto tr23
    380418                } else 
    381                         goto st17
    382         } else 
    383                 goto st17
     419                        goto tr23
     420        } else 
     421                goto tr23
    384422        goto st0; 
    385423tr24: 
    386 #line 26 "http11_parser.rl" 
     424#line 39 "http11_parser.rl" 
    387425        {  
    388426    parser->field_len = LEN(field_start, p); 
     
    390428        goto st18; 
    391429tr27: 
    392 #line 30 "http11_parser.rl" 
     430#line 43 "http11_parser.rl" 
    393431        { MARK(mark, p); } 
    394432        goto st18; 
    395433st18: 
    396434        if ( ++p == pe ) 
    397                 goto _out18; 
     435                goto _test_eof18; 
    398436case 18: 
    399 #line 400 "http11_parser.c" 
     437#line 438 "http11_parser.c" 
    400438        switch( (*p) ) { 
    401439                case 13: goto tr26; 
     
    404442        goto tr25; 
    405443tr25: 
    406 #line 30 "http11_parser.rl" 
     444#line 43 "http11_parser.rl" 
    407445        { MARK(mark, p); } 
    408446        goto st19; 
    409447st19: 
    410448        if ( ++p == pe ) 
    411                 goto _out19; 
     449                goto _test_eof19; 
    412450case 19: 
    413 #line 414 "http11_parser.c" 
     451#line 452 "http11_parser.c" 
    414452        if ( (*p) == 13 ) 
    415                 goto tr26
     453                goto tr29
    416454        goto st19; 
    417455tr9: 
    418 #line 40 "http11_parser.rl" 
     456#line 53 "http11_parser.rl" 
    419457        {  
    420458    if(parser->request_uri != NULL) 
     
    422460  } 
    423461        goto st20; 
    424 tr41
    425 #line 60 "http11_parser.rl" 
     462tr43
     463#line 73 "http11_parser.rl" 
    426464        { 
    427465    if(parser->request_path != NULL) 
    428466      parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p)); 
    429467  } 
    430 #line 40 "http11_parser.rl" 
     468#line 53 "http11_parser.rl" 
    431469        {  
    432470    if(parser->request_uri != NULL) 
     
    434472  } 
    435473        goto st20; 
    436 tr52
    437 #line 49 "http11_parser.rl" 
     474tr54
     475#line 62 "http11_parser.rl" 
    438476        {MARK(query_start, p); } 
    439 #line 50 "http11_parser.rl" 
     477#line 63 "http11_parser.rl" 
    440478        {  
    441479    if(parser->query_string != NULL) 
    442480      parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p)); 
    443481  } 
    444 #line 40 "http11_parser.rl" 
     482#line 53 "http11_parser.rl" 
    445483        {  
    446484    if(parser->request_uri != NULL) 
     
    448486  } 
    449487        goto st20; 
    450 tr56
    451 #line 50 "http11_parser.rl" 
     488tr58
     489#line 63 "http11_parser.rl" 
    452490        {  
    453491    if(parser->query_string != NULL) 
    454492      parser->query_string(parser->data, PTR_TO(query_start), LEN(query_start, p)); 
    455493  } 
    456 #line 40 "http11_parser.rl" 
     494#line 53 "http11_parser.rl" 
    457495        {  
    458496    if(parser->request_uri != NULL) 
     
    462500st20: 
    463501        if ( ++p == pe ) 
    464                 goto _out20; 
     502                goto _test_eof20; 
    465503case 20: 
    466 #line 467 "http11_parser.c" 
    467         switch( (*p) ) { 
    468                 case 32: goto tr30
    469                 case 37: goto tr31
     504#line 505 "http11_parser.c" 
     505        switch( (*p) ) { 
     506                case 32: goto tr31
     507                case 37: goto tr32
    470508                case 60: goto st0; 
    471509                case 62: goto st0; 
     
    477515        } else if ( (*p) >= 0 ) 
    478516                goto st0; 
    479         goto tr29
    480 tr29
    481 #line 22 "http11_parser.rl" 
     517        goto tr30
     518tr30
     519#line 34 "http11_parser.rl" 
    482520        {MARK(mark, p); } 
    483521        goto st21; 
    484522st21: 
    485523        if ( ++p == pe ) 
    486                 goto _out21; 
     524                goto _test_eof21; 
    487525case 21: 
    488 #line 489 "http11_parser.c" 
    489         switch( (*p) ) { 
    490                 case 32: goto tr30
     526#line 527 "http11_parser.c" 
     527        switch( (*p) ) { 
     528                case 32: goto tr34
    491529                case 37: goto st22; 
    492530                case 60: goto st0; 
     
    500538                goto st0; 
    501539        goto st21; 
    502 tr31
    503 #line 22 "http11_parser.rl" 
     540tr32
     541#line 34 "http11_parser.rl" 
    504542        {MARK(mark, p); } 
    505543        goto st22; 
    506544st22: 
    507545        if ( ++p == pe ) 
    508                 goto _out22; 
     546                goto _test_eof22; 
    509547case 22: 
    510 #line 511 "http11_parser.c" 
     548#line 549 "http11_parser.c" 
    511549        if ( (*p) < 65 ) { 
    512550                if ( 48 <= (*p) && (*p) <= 57 ) 
     
    520558st23: 
    521559        if ( ++p == pe ) 
    522                 goto _out23; 
     560                goto _test_eof23; 
    523561case 23: 
    524562        if ( (*p) < 65 ) { 
     
    532570        goto st0; 
    533571tr5: 
    534 #line 22 "http11_parser.rl" 
     572#line 34 "http11_parser.rl" 
    535573        {MARK(mark, p); } 
    536574        goto st24; 
    537575st24: 
    538576        if ( ++p == pe ) 
    539                 goto _out24; 
     577                goto _test_eof24; 
    540578case 24: 
    541 #line 542 "http11_parser.c" 
     579#line 580 "http11_parser.c" 
    542580        switch( (*p) ) { 
    543581                case 43: goto st24; 
     
    557595        goto st0; 
    558596tr7: 
    559 #line 22 "http11_parser.rl" 
     597#line 34 "http11_parser.rl" 
    560598        {MARK(mark, p); } 
    561599        goto st25; 
    562600st25: 
    563601        if ( ++p == pe ) 
    564                 goto _out25; 
     602                goto _test_eof25; 
    565603case 25: 
    566 #line 567 "http11_parser.c" 
     604#line 605 "http11_parser.c" 
    567605        switch( (*p) ) { 
    568606                case 32: goto tr8; 
     
    579617st26: 
    580618        if ( ++p == pe ) 
    581                 goto _out26; 
     619                goto _test_eof26; 
    582620case 26: 
    583621        if ( (*p) < 65 ) { 
     
    592630st27: 
    593631        if ( ++p == pe ) 
    594                 goto _out27; 
     632                goto _test_eof27; 
    595633case 27: 
    596634        if ( (*p) < 65 ) { 
     
    604642        goto st0; 
    605643tr6: 
    606 #line 22 "http11_parser.rl" 
     644#line 34 "http11_parser.rl" 
    607645        {MARK(mark, p); } 
    608646        goto st28; 
    609647st28: 
    610648        if ( ++p == pe ) 
    611                 goto _out28; 
     649                goto _test_eof28; 
    612650case 28: 
    613 #line 614 "http11_parser.c" 
    614         switch( (*p) ) { 
    615                 case 32: goto tr40
     651#line 652 "http11_parser.c" 
     652        switch( (*p) ) { 
     653                case 32: goto tr42
    616654                case 34: goto st0; 
    617                 case 35: goto tr41
     655                case 35: goto tr43
    618656                case 37: goto st29; 
    619                 case 59: goto tr43
     657                case 59: goto tr45
    620658                case 60: goto st0; 
    621659                case 62: goto st0; 
    622                 case 63: goto tr44
     660                case 63: goto tr46
    623661                case 127: goto st0; 
    624662        } 
     
    628666st29: 
    629667        if ( ++p == pe ) 
    630                 goto _out29; 
     668                goto _test_eof29; 
    631669case 29: 
    632670        if ( (*p) < 65 ) { 
     
    641679st30: 
    642680        if ( ++p == pe ) 
    643                 goto _out30; 
     681                goto _test_eof30; 
    644682case 30: 
    645683        if ( (*p) < 65 ) { 
     
    652690                goto st28; 
    653691        goto st0; 
    654 tr43
    655 #line 60 "http11_parser.rl" 
     692tr45
     693#line 73 "http11_parser.rl" 
    656694        { 
    657695    if(parser->request_path != NULL) 
     
    661699st31: 
    662700        if ( ++p == pe ) 
    663                 goto _out31; 
     701                goto _test_eof31; 
    664702case 31: 
    665 #line 666 "http11_parser.c" 
     703#line 704 "http11_parser.c" 
    666704        switch( (*p) ) { 
    667705                case 32: goto tr8; 
     
    679717st32: 
    680718        if ( ++p == pe ) 
    681                 goto _out32; 
     719                goto _test_eof32; 
    682720case 32: 
    683721        if ( (*p) < 65 ) { 
     
    692730st33: 
    693731        if ( ++p == pe ) 
    694                 goto _out33; 
     732                goto _test_eof33; 
    695733case 33: 
    696734        if ( (*p) < 65 ) { 
     
    703741                goto st31; 
    704742        goto st0; 
    705 tr44
    706 #line 60 "http11_parser.rl" 
     743tr46
     744#line 73 "http11_parser.rl" 
    707745        { 
    708746    if(parser->request_path != NULL) 
     
    712750st34: 
    713751        if ( ++p == pe ) 
    714                 goto _out34; 
     752                goto _test_eof34; 
    715753case 34: 
    716 #line 717 "http11_parser.c" 
    717         switch( (*p) ) { 
    718                 case 32: goto tr51
     754#line 755 "http11_parser.c" 
     755        switch( (*p) ) { 
     756                case 32: goto tr53
    719757                case 34: goto st0; 
    720                 case 35: goto tr52
    721                 case 37: goto tr53
     758                case 35: goto tr54
     759                case 37: goto tr55
    722760                case 60: goto st0; 
    723761                case 62: goto st0; 
     
    726764        if ( 0 <= (*p) && (*p) <= 31 ) 
    727765                goto st0; 
    72