From ee675d5a703efaab60ef90a8b41f87348d928db7 Mon Sep 17 00:00:00 2001 From: zedshaw Date: Tue, 8 Aug 2006 09:26:23 +0000 Subject: Fixes the differences between mongrel and webrick around request URI, path_info, etc. Adds REQUEST_PATH to disambiguate the whole problem as well. git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@311 19e92222-5c0b-0410-8929-a290d50e31e9 --- ext/http11/http11.c | 16 ++- ext/http11/http11_parser.c | 294 ++++++++++++++++++++++++++++---------------- ext/http11/http11_parser.h | 1 + ext/http11/http11_parser.rl | 11 +- 4 files changed, 209 insertions(+), 113 deletions(-) (limited to 'ext') diff --git a/ext/http11/http11.c b/ext/http11/http11.c index 0a0fef7..46a47be 100644 --- a/ext/http11/http11.c +++ b/ext/http11/http11.c @@ -25,6 +25,7 @@ static VALUE global_query_string; static VALUE global_http_version; static VALUE global_content_length; static VALUE global_http_content_length; +static VALUE global_request_path; static VALUE global_content_type; static VALUE global_http_content_type; static VALUE global_gateway_interface; @@ -53,7 +54,8 @@ static VALUE global_port_80; /* 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(REQUEST_URI, 1024); +DEF_MAX_LENGTH(REQUEST_URI, 1024 * 2); +DEF_MAX_LENGTH(REQUEST_PATH, 1024); DEF_MAX_LENGTH(QUERY_STRING, (1024 * 10)); DEF_MAX_LENGTH(HEADER, (1024 * (80 + 32))); @@ -103,6 +105,16 @@ void request_uri(void *data, const char *at, size_t length) rb_hash_aset(req, global_request_uri, val); } +void request_path(void *data, const char *at, size_t length) +{ + VALUE req = (VALUE)data; + VALUE val = Qnil; + + VALIDATE_MAX_LENGTH(length, REQUEST_PATH); + + val = rb_str_new(at, length); + rb_hash_aset(req, global_request_path, val); +} void query_string(void *data, const char *at, size_t length) { @@ -182,6 +194,7 @@ VALUE HttpParser_alloc(VALUE klass) hp->http_field = http_field; hp->request_method = request_method; hp->request_uri = request_uri; + hp->request_path = request_path; hp->query_string = query_string; hp->http_version = http_version; hp->header_done = header_done; @@ -531,6 +544,7 @@ void Init_http11() DEF_GLOBAL(request_uri, "REQUEST_URI"); DEF_GLOBAL(query_string, "QUERY_STRING"); DEF_GLOBAL(http_version, "HTTP_VERSION"); + DEF_GLOBAL(request_path, "REQUEST_PATH"); DEF_GLOBAL(content_length, "CONTENT_LENGTH"); DEF_GLOBAL(http_content_length, "HTTP_CONTENT_LENGTH"); DEF_GLOBAL(content_type, "CONTENT_TYPE"); diff --git a/ext/http11/http11_parser.c b/ext/http11/http11_parser.c index d18362b..ea2b818 100644 --- a/ext/http11/http11_parser.c +++ b/ext/http11/http11_parser.c @@ -15,7 +15,7 @@ #define PTR_TO(F) (buffer + parser->F) /** machine **/ -#line 109 "ext/http11/http11_parser.rl" +#line 114 "ext/http11/http11_parser.rl" /** Data **/ @@ -23,11 +23,11 @@ #line 24 "ext/http11/http11_parser.c" static int http_parser_start = 0; -static int http_parser_first_final = 51; +static int http_parser_first_final = 54; static int http_parser_error = 1; -#line 113 "ext/http11/http11_parser.rl" +#line 118 "ext/http11/http11_parser.rl" int http_parser_init(http_parser *parser) { int cs = 0; @@ -36,7 +36,7 @@ int http_parser_init(http_parser *parser) { { cs = http_parser_start; } -#line 117 "ext/http11/http11_parser.rl" +#line 122 "ext/http11/http11_parser.rl" parser->cs = cs; parser->body_start = 0; parser->content_len = 0; @@ -98,17 +98,17 @@ case 2: #line 99 "ext/http11/http11_parser.c" switch( (*p) ) { case 32: goto tr18; - case 36: goto st32; - case 95: goto st32; + case 36: goto st35; + case 95: goto st35; } if ( (*p) < 48 ) { if ( 45 <= (*p) && (*p) <= 46 ) - goto st32; + goto st35; } else if ( (*p) > 57 ) { if ( 65 <= (*p) && (*p) <= 90 ) - goto st32; + goto st35; } else - goto st32; + goto st35; goto st1; tr18: #line 34 "ext/http11/http11_parser.rl" @@ -168,11 +168,23 @@ tr29: parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); } goto st5; +tr32: +#line 54 "ext/http11/http11_parser.rl" + { + if(parser->request_path != NULL) + parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p)); + } +#line 38 "ext/http11/http11_parser.rl" + { + if(parser->request_uri != NULL) + parser->request_uri(parser->data, PTR_TO(mark), LEN(mark, p)); + } + goto st5; st5: if ( ++p == pe ) goto _out5; case 5: -#line 176 "ext/http11/http11_parser.c" +#line 188 "ext/http11/http11_parser.c" if ( (*p) == 72 ) goto tr3; goto st1; @@ -184,7 +196,7 @@ st6: if ( ++p == pe ) goto _out6; case 6: -#line 188 "ext/http11/http11_parser.c" +#line 200 "ext/http11/http11_parser.c" if ( (*p) == 84 ) goto st7; goto st1; @@ -248,7 +260,7 @@ tr23: parser->http_version(parser->data, PTR_TO(mark), LEN(mark, p)); } goto st14; -tr32: +tr37: #line 29 "ext/http11/http11_parser.rl" { if(parser->http_field != NULL) { @@ -260,7 +272,7 @@ st14: if ( ++p == pe ) goto _out14; case 14: -#line 264 "ext/http11/http11_parser.c" +#line 276 "ext/http11/http11_parser.c" if ( (*p) == 10 ) goto st15; goto st1; @@ -300,19 +312,19 @@ case 16: goto tr26; goto st1; tr26: -#line 54 "ext/http11/http11_parser.rl" +#line 59 "ext/http11/http11_parser.rl" { parser->body_start = p - buffer + 1; if(parser->header_done != NULL) parser->header_done(parser->data, p + 1, pe - p - 1); - goto _out51; + goto _out54; } - goto st51; -st51: + goto st54; +st54: if ( ++p == pe ) - goto _out51; -case 51: -#line 316 "ext/http11/http11_parser.c" + goto _out54; +case 54: +#line 328 "ext/http11/http11_parser.c" goto st1; tr22: #line 23 "ext/http11/http11_parser.rl" @@ -322,7 +334,7 @@ st17: if ( ++p == pe ) goto _out17; case 17: -#line 326 "ext/http11/http11_parser.c" +#line 338 "ext/http11/http11_parser.c" switch( (*p) ) { case 33: goto st17; case 58: goto tr16; @@ -357,7 +369,7 @@ st18: if ( ++p == pe ) goto _out18; case 18: -#line 361 "ext/http11/http11_parser.c" +#line 373 "ext/http11/http11_parser.c" if ( (*p) == 32 ) goto st19; goto st1; @@ -366,9 +378,9 @@ st19: goto _out19; case 19: if ( (*p) == 13 ) - goto tr32; - goto tr33; -tr33: + goto tr37; + goto tr38; +tr38: #line 28 "ext/http11/http11_parser.rl" { MARK(mark, p); } goto st20; @@ -376,9 +388,9 @@ st20: if ( ++p == pe ) goto _out20; case 20: -#line 380 "ext/http11/http11_parser.c" +#line 392 "ext/http11/http11_parser.c" if ( (*p) == 13 ) - goto tr32; + goto tr37; goto st20; tr11: #line 20 "ext/http11/http11_parser.rl" @@ -388,7 +400,7 @@ st21: if ( ++p == pe ) goto _out21; case 21: -#line 392 "ext/http11/http11_parser.c" +#line 404 "ext/http11/http11_parser.c" switch( (*p) ) { case 43: goto st21; case 58: goto st22; @@ -413,7 +425,7 @@ st22: if ( ++p == pe ) goto _out22; case 22: -#line 417 "ext/http11/http11_parser.c" +#line 429 "ext/http11/http11_parser.c" switch( (*p) ) { case 32: goto tr20; case 37: goto st23; @@ -461,13 +473,14 @@ st25: if ( ++p == pe ) goto _out25; case 25: -#line 465 "ext/http11/http11_parser.c" +#line 477 "ext/http11/http11_parser.c" switch( (*p) ) { - case 32: goto tr20; + case 32: goto tr32; case 37: goto st26; + case 59: goto tr34; case 60: goto st1; case 62: goto st1; - case 63: goto st28; + case 63: goto tr35; case 127: goto st1; } if ( (*p) > 31 ) { @@ -502,15 +515,24 @@ case 27: } else goto st25; goto st1; +tr34: +#line 54 "ext/http11/http11_parser.rl" + { + if(parser->request_path != NULL) + parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p)); + } + goto st28; st28: if ( ++p == pe ) goto _out28; case 28: +#line 530 "ext/http11/http11_parser.c" switch( (*p) ) { - case 32: goto tr29; - case 37: goto tr35; + case 32: goto tr20; + case 37: goto st29; case 60: goto st1; case 62: goto st1; + case 63: goto st31; case 127: goto st1; } if ( (*p) > 31 ) { @@ -518,92 +540,94 @@ case 28: goto st1; } else if ( (*p) >= 0 ) goto st1; - goto tr34; -tr34: -#line 43 "ext/http11/http11_parser.rl" - {MARK(query_start, p); } - goto st29; + goto st28; st29: if ( ++p == pe ) goto _out29; case 29: -#line 531 "ext/http11/http11_parser.c" - switch( (*p) ) { - case 32: goto tr29; - case 37: goto st30; - case 60: goto st1; - case 62: goto st1; - case 127: goto st1; - } - if ( (*p) > 31 ) { - if ( 34 <= (*p) && (*p) <= 35 ) - goto st1; - } else if ( (*p) >= 0 ) - goto st1; - goto st29; -tr35: -#line 43 "ext/http11/http11_parser.rl" - {MARK(query_start, p); } - goto st30; + 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 st1; st30: if ( ++p == pe ) goto _out30; case 30: -#line 553 "ext/http11/http11_parser.c" if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) - goto st31; + goto st28; } else if ( (*p) > 70 ) { if ( 97 <= (*p) && (*p) <= 102 ) - goto st31; + goto st28; } else - goto st31; + goto st28; goto st1; +tr35: +#line 54 "ext/http11/http11_parser.rl" + { + if(parser->request_path != NULL) + parser->request_path(parser->data, PTR_TO(mark), LEN(mark,p)); + } + goto st31; st31: if ( ++p == pe ) goto _out31; case 31: - if ( (*p) < 65 ) { - if ( 48 <= (*p) && (*p) <= 57 ) - goto st29; - } else if ( (*p) > 70 ) { - if ( 97 <= (*p) && (*p) <= 102 ) - goto st29; - } else - goto st29; - goto st1; +#line 582 "ext/http11/http11_parser.c" + switch( (*p) ) { + case 32: goto tr29; + case 37: goto tr40; + case 60: goto st1; + case 62: goto st1; + case 127: goto st1; + } + if ( (*p) > 31 ) { + if ( 34 <= (*p) && (*p) <= 35 ) + goto st1; + } else if ( (*p) >= 0 ) + goto st1; + goto tr39; +tr39: +#line 43 "ext/http11/http11_parser.rl" + {MARK(query_start, p); } + goto st32; st32: if ( ++p == pe ) goto _out32; case 32: +#line 604 "ext/http11/http11_parser.c" switch( (*p) ) { - case 32: goto tr18; - case 36: goto st33; - case 95: goto st33; + case 32: goto tr29; + case 37: goto st33; + case 60: goto st1; + case 62: goto st1; + case 127: goto st1; } - if ( (*p) < 48 ) { - if ( 45 <= (*p) && (*p) <= 46 ) - goto st33; - } else if ( (*p) > 57 ) { - if ( 65 <= (*p) && (*p) <= 90 ) - goto st33; - } else - goto st33; - goto st1; + if ( (*p) > 31 ) { + if ( 34 <= (*p) && (*p) <= 35 ) + goto st1; + } else if ( (*p) >= 0 ) + goto st1; + goto st32; +tr40: +#line 43 "ext/http11/http11_parser.rl" + {MARK(query_start, p); } + goto st33; st33: if ( ++p == pe ) goto _out33; case 33: - switch( (*p) ) { - case 32: goto tr18; - case 36: goto st34; - case 95: goto st34; - } - if ( (*p) < 48 ) { - if ( 45 <= (*p) && (*p) <= 46 ) +#line 626 "ext/http11/http11_parser.c" + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) goto st34; - } else if ( (*p) > 57 ) { - if ( 65 <= (*p) && (*p) <= 90 ) + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) goto st34; } else goto st34; @@ -612,19 +636,14 @@ st34: if ( ++p == pe ) goto _out34; case 34: - switch( (*p) ) { - case 32: goto tr18; - case 36: goto st35; - case 95: goto st35; - } - if ( (*p) < 48 ) { - if ( 45 <= (*p) && (*p) <= 46 ) - goto st35; - } else if ( (*p) > 57 ) { - if ( 65 <= (*p) && (*p) <= 90 ) - goto st35; + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto st32; + } else if ( (*p) > 70 ) { + if ( 97 <= (*p) && (*p) <= 102 ) + goto st32; } else - goto st35; + goto st32; goto st1; st35: if ( ++p == pe ) @@ -900,6 +919,60 @@ st50: if ( ++p == pe ) goto _out50; case 50: + switch( (*p) ) { + case 32: goto tr18; + case 36: goto st51; + case 95: goto st51; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st51; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st51; + } else + goto st51; + goto st1; +st51: + if ( ++p == pe ) + goto _out51; +case 51: + switch( (*p) ) { + case 32: goto tr18; + case 36: goto st52; + case 95: goto st52; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st52; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st52; + } else + goto st52; + goto st1; +st52: + if ( ++p == pe ) + goto _out52; +case 52: + switch( (*p) ) { + case 32: goto tr18; + case 36: goto st53; + case 95: goto st53; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st53; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st53; + } else + goto st53; + goto st1; +st53: + if ( ++p == pe ) + goto _out53; +case 53: if ( (*p) == 32 ) goto tr18; goto st1; @@ -920,7 +993,7 @@ case 50: _out14: cs = 14; goto _out; _out15: cs = 15; goto _out; _out16: cs = 16; goto _out; - _out51: cs = 51; goto _out; + _out54: cs = 54; goto _out; _out17: cs = 17; goto _out; _out18: cs = 18; goto _out; _out19: cs = 19; goto _out; @@ -955,10 +1028,13 @@ case 50: _out48: cs = 48; goto _out; _out49: cs = 49; goto _out; _out50: cs = 50; goto _out; + _out51: cs = 51; goto _out; + _out52: cs = 52; goto _out; + _out53: cs = 53; goto _out; _out: {} } -#line 144 "ext/http11/http11_parser.rl" +#line 149 "ext/http11/http11_parser.rl" parser->cs = cs; parser->nread += p - (buffer + off); @@ -973,8 +1049,8 @@ case 50: if(parser->body_start) { /* final \r\n combo encountered so stop right here */ -#line 977 "ext/http11/http11_parser.c" -#line 158 "ext/http11/http11_parser.rl" +#line 1053 "ext/http11/http11_parser.c" +#line 163 "ext/http11/http11_parser.rl" parser->nread++; } @@ -986,8 +1062,8 @@ int http_parser_finish(http_parser *parser) int cs = parser->cs; -#line 990 "ext/http11/http11_parser.c" -#line 169 "ext/http11/http11_parser.rl" +#line 1066 "ext/http11/http11_parser.c" +#line 174 "ext/http11/http11_parser.rl" parser->cs = cs; diff --git a/ext/http11/http11_parser.h b/ext/http11/http11_parser.h index 24cb830..cd6692d 100644 --- a/ext/http11/http11_parser.h +++ b/ext/http11/http11_parser.h @@ -30,6 +30,7 @@ typedef struct http_parser { field_cb http_field; element_cb request_method; element_cb request_uri; + element_cb request_path; element_cb query_string; element_cb http_version; element_cb header_done; diff --git a/ext/http11/http11_parser.rl b/ext/http11/http11_parser.rl index b16946d..e3543c1 100644 --- a/ext/http11/http11_parser.rl +++ b/ext/http11/http11_parser.rl @@ -51,6 +51,11 @@ parser->http_version(parser->data, PTR_TO(mark), LEN(mark, fpc)); } + action request_path { + if(parser->request_path != NULL) + parser->request_path(parser->data, PTR_TO(mark), LEN(mark,fpc)); + } + action done { parser->body_start = fpc - buffer + 1; if(parser->header_done != NULL) @@ -81,16 +86,16 @@ # URI schemes and absolute paths scheme = ( alpha | digit | "+" | "-" | "." )* ; - absolute_uri = (scheme ":" (uchar | reserved )*) >mark %request_uri; + absolute_uri = (scheme ":" (uchar | reserved )*); path = (pchar+ ( "/" pchar* )*) ; query = ( uchar | reserved )* >start_query %query_string ; param = ( pchar | "/" )* ; params = (param ( ";" param )*) ; - rel_path = (path? (";" params)?) ("?" query)?; + rel_path = (path? %request_path (";" params)?) ("?" query)?; absolute_path = ("/"+ rel_path); - Request_URI = ("*" %request_uri | absolute_uri | absolute_path) >mark %request_uri; + Request_URI = ("*" | absolute_uri | absolute_path) >mark %request_uri; Method = (upper | digit | safe){1,20} >mark %request_method; http_number = (digit+ "." digit+) ; -- cgit v1.2.3-24-ge0c7