Here's a patch of http_parser.rl against r358 that allows these three
characters and associated unit tests.

On 10/16/06, Eden Li <[EMAIL PROTECTED]> wrote:
Hmm.  It looks like a plugin can't handle this.  The plugin I tested
never got its process method called.

Tracing through lib/mongrel.rb, the HttpParser#execute method throws
an HttpParserError before it has a chance to pass the request off to
the plugin.  Looks like this'll have to be patched in the Ragel or C
code.

FWIW, the URI parsing libraries of both Perl and Python, which claim
to be RFC compliant, parse these out 'properly' without throwing an
error.

Also, from rfc2396:

   The angle-bracket "<" and ">" and double-quote (") characters are
   excluded because they are often used as the delimiters around URI in
   text documents and protocol fields.

Which makes sense from the standards point of view, but if the request
has already gotten to your server, it shouldn't barf on it.

On 10/16/06, Rick Olson <[EMAIL PROTECTED]> wrote:
> On 10/15/06, philippe lachaise <[EMAIL PROTECTED]> wrote:
> > >> You could probably write a mongrel handler to cuddle with the params.
> >
> > Aren't people likely to blame it on Mongrel, even if it is most unfair ?
> >
> > The usual conclusion is "this server can't handle that".
> >
> > My gut feeling is that a web server should handle gracefully ill-behaved
> > clients or complain explicitely.
> >
> > (But, since I'm not the one who can write the code, take my remark as a mere
> > whisper ;-)
>
> That's up to Zed I guess.  But, a plugin serves many purposes:
>
> - lets you get on with your life since you don't have to wait for a new 
release
> - lets others on older versions of mongrel easily upgrade
> - provides Zed with working code (hopefully) being used in production.
>  i'm sure that says a lot more than a feature request.
>
> As much as I dislike the notion, I too think Mongrel should handle this stuff.
>
> --
> Rick Olson
> http://weblog.techno-weenie.net
> http://mephistoblog.com
> _______________________________________________
> Mongrel-users mailing list
> [email protected]
> http://rubyforge.org/mailman/listinfo/mongrel-users
>

Index: test/test_http11.rb
===================================================================
--- test/test_http11.rb	(revision 358)
+++ test/test_http11.rb	(working copy)
@@ -36,6 +36,24 @@
     assert parser.finished?
     assert !parser.error?
   end
+
+  def test_parse_ie6_urls
+    %w(/some/random/path"
+       /some/random/path>
+       /some/random/path<
+       /we/love/you/ie6?q=<"">
+       /url?<="&>="
+       /mal"formed"?
+    ).each do |path|
+      parser = HttpParser.new
+      req = {}
+      sorta_safe = %(GET #{path} HTTP/1.1\r\n\r\n)
+      nread = parser.execute(req, sorta_safe, 0)
+      assert_equal sorta_safe.length, nread
+      assert parser.finished?
+      assert !parser.error?
+    end
+  end
   
   def test_parse_error
     parser = HttpParser.new
Index: ext/http11/http11_parser.rl
===================================================================
--- ext/http11/http11_parser.rl	(revision 358)
+++ ext/http11/http11_parser.rl	(working copy)
@@ -73,11 +73,12 @@
   safe = ("$" | "-" | "_" | ".");
   extra = ("!" | "*" | "'" | "(" | ")" | ",");
   reserved = (";" | "/" | "?" | ":" | "@" | "&" | "=" | "+");
-  unsafe = (CTL | " " | "\"" | "#" | "%" | "<" | ">");
+  sorta_safe = ("\"" | "<" | ">");
+  unsafe = (CTL | " " | "#" | "%" | sorta_safe);
   national = any -- (alpha | digit | reserved | extra | safe | unsafe);
   unreserved = (alpha | digit | safe | extra | national);
   escape = ("%" xdigit xdigit);
-  uchar = (unreserved | escape);
+  uchar = (unreserved | escape | sorta_safe);
   pchar = (uchar | ":" | "@" | "&" | "=" | "+");
   tspecials = ("(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\\" | "\"" | "/" | "[" | "]" | "?" | "=" | "{" | "}" | " " | "\t");
 
Index: ext/http11/http11_parser.c
===================================================================
--- ext/http11/http11_parser.c	(revision 358)
+++ ext/http11/http11_parser.c	(working copy)
@@ -15,7 +15,7 @@
 #define PTR_TO(F) (buffer + parser->F)
 
 /** machine **/
-#line 114 "ext/http11/http11_parser.rl"
+#line 115 "ext/http11/http11_parser.rl"
 
 
 /** Data **/
@@ -27,7 +27,7 @@
 
 static const int http_parser_error = 1;
 
-#line 118 "ext/http11/http11_parser.rl"
+#line 119 "ext/http11/http11_parser.rl"
 
 int http_parser_init(http_parser *parser)  {
   int cs = 0;
@@ -36,7 +36,7 @@
 	{
 	cs = http_parser_start;
 	}
-#line 122 "ext/http11/http11_parser.rl"
+#line 123 "ext/http11/http11_parser.rl"
   parser->cs = cs;
   parser->body_start = 0;
   parser->content_len = 0;
@@ -440,15 +440,11 @@
 #line 441 "ext/http11/http11_parser.c"
 	switch( (*p) ) {
 		case 32: goto tr19;
+		case 35: goto st1;
 		case 37: goto st22;
-		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 )
+	if ( 0 <= (*p) && (*p) <= 31 )
 		goto st1;
 	goto st21;
 st22:
@@ -485,20 +481,16 @@
 	if ( ++p == pe )
 		goto _out24;
 case 24:
-#line 489 "ext/http11/http11_parser.c"
+#line 485 "ext/http11/http11_parser.c"
 	switch( (*p) ) {
 		case 32: goto tr31;
+		case 35: goto st1;
 		case 37: goto st25;
 		case 59: goto tr33;
-		case 60: goto st1;
-		case 62: goto st1;
 		case 63: goto tr34;
 		case 127: goto st1;
 	}
-	if ( (*p) > 31 ) {
-		if ( 34 <= (*p) && (*p) <= 35 )
-			goto st1;
-	} else if ( (*p) >= 0 )
+	if ( 0 <= (*p) && (*p) <= 31 )
 		goto st1;
 	goto st24;
 st25:
@@ -538,19 +530,15 @@
 	if ( ++p == pe )
 		goto _out27;
 case 27:
-#line 542 "ext/http11/http11_parser.c"
+#line 534 "ext/http11/http11_parser.c"
 	switch( (*p) ) {
 		case 32: goto tr19;
+		case 35: goto st1;
 		case 37: goto st28;
-		case 60: goto st1;
-		case 62: goto st1;
 		case 63: goto st30;
 		case 127: goto st1;
 	}
-	if ( (*p) > 31 ) {
-		if ( 34 <= (*p) && (*p) <= 35 )
-			goto st1;
-	} else if ( (*p) >= 0 )
+	if ( 0 <= (*p) && (*p) <= 31 )
 		goto st1;
 	goto st27;
 st28:
@@ -590,18 +578,14 @@
 	if ( ++p == pe )
 		goto _out30;
 case 30:
-#line 594 "ext/http11/http11_parser.c"
+#line 582 "ext/http11/http11_parser.c"
 	switch( (*p) ) {
 		case 32: goto tr40;
+		case 35: goto st1;
 		case 37: goto tr41;
-		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 )
+	if ( 0 <= (*p) && (*p) <= 31 )
 		goto st1;
 	goto tr39;
 tr39:
@@ -612,18 +596,14 @@
 	if ( ++p == pe )
 		goto _out31;
 case 31:
-#line 616 "ext/http11/http11_parser.c"
+#line 600 "ext/http11/http11_parser.c"
 	switch( (*p) ) {
 		case 32: goto tr28;
+		case 35: goto st1;
 		case 37: goto st32;
-		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 )
+	if ( 0 <= (*p) && (*p) <= 31 )
 		goto st1;
 	goto st31;
 tr41:
@@ -634,7 +614,7 @@
 	if ( ++p == pe )
 		goto _out32;
 case 32:
-#line 638 "ext/http11/http11_parser.c"
+#line 618 "ext/http11/http11_parser.c"
 	if ( (*p) < 65 ) {
 		if ( 48 <= (*p) && (*p) <= 57 )
 			goto st33;
@@ -1045,7 +1025,7 @@
 
 	_out: {}
 	}
-#line 149 "ext/http11/http11_parser.rl"
+#line 150 "ext/http11/http11_parser.rl"
 
   parser->cs = cs;
   parser->nread += p - (buffer + off);
@@ -1060,8 +1040,8 @@
   if(parser->body_start) {
     /* final \r\n combo encountered so stop right here */
     
-#line 1064 "ext/http11/http11_parser.c"
-#line 163 "ext/http11/http11_parser.rl"
+#line 1044 "ext/http11/http11_parser.c"
+#line 164 "ext/http11/http11_parser.rl"
     parser->nread++;
   }
 
@@ -1073,8 +1053,8 @@
   int cs = parser->cs;
 
   
-#line 1077 "ext/http11/http11_parser.c"
-#line 174 "ext/http11/http11_parser.rl"
+#line 1057 "ext/http11/http11_parser.c"
+#line 175 "ext/http11/http11_parser.rl"
 
   parser->cs = cs;
 
_______________________________________________
Mongrel-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/mongrel-users

Reply via email to