1 /*********************************************************************
3 This is a port of the Mongrel/Thin parser for HTTP, which was
4 originally written in Ragel. Mongrel and Thin use it for handling
5 incoming HTTP requests, and its main design goals are speed and
8 Here is the original parser, from which this port is based:
9 http://github.com/macournoyer/thin/tree/master/ext/thin_parser/common.rl
11 *********************************************************************/
20 CTL: [ #{std.cntrl} \x7f ];
22 extra: [ ! * ' ( ) , ];
23 reserved: [ ; / ? : @ & = + ];
24 sorta_safe: [ " < > ];
25 unsafe: [ ${CTL} \s # % ${sorta_safe} ];
26 national: [^${std.alpha} ${std.digit} ${reserved} ${extra} ${safe} ${unsafe} ];
27 unreserved: [ ${std.alpha} ${std.digit} ${safe} ${extra} ${national} ];
29 escape: / % [0-9A-Fa-f]{2} /;
30 uchar: / ${unreserved} | ${escape} | ${sorta_safe} /;
31 pchar: / ${uchar} | [ : @ & = + ] /;
32 tspecials: [ ( ) < > @ , ; : \\ " / [ \] ? = { } \s \t ];
35 token: [ ${std.ascii} ^ ${CTL} ${tspecials} ];
37 // URI schemes and absolute paths
38 scheme: / [ ${alpha} ${digit} + - . ]* /;
39 absolute_uri: / ( ${scheme} ) ":" ([${uchar} | ${reserved}]*) /;
41 path -> /${pchar}+/ ( "/" /${pchar}*/ )*;
42 query: /[ ${uchar} | ${reserved} ]*/;
43 param: /[ ${pchar} / ]*/;
45 rel_path -> path? (";" params)? ("?" query)?;
46 absolute_path -> "/"+ rel_path;
48 Request_URI -> "*" | absolute_uri | absolute_path;
49 Fragment: / [${uchar} ${reserved}]* /;
50 Method: / [${upper} ${digit} ${safe}]{1,20} /;
52 http_number: / ${digit}+ \. ${digit}+/;
53 HTTP_Version -> "HTTP/" http_number;
54 Request_Line -> Method " " Request_URI ("#" Fragment)? " " HTTP_Version CRLF;
56 field_name: / (${token} -- ":")+ /;
58 message_header -> field_name ":" " "* /[^\r]*/ CRLF;
60 Request -> Request_Line message_header* CRLF;