diff options
Diffstat (limited to 'ext/kcar/kcar_http_common.rl')
-rw-r--r-- | ext/kcar/kcar_http_common.rl | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/ext/kcar/kcar_http_common.rl b/ext/kcar/kcar_http_common.rl new file mode 100644 index 0000000..54206ed --- /dev/null +++ b/ext/kcar/kcar_http_common.rl @@ -0,0 +1,56 @@ +%%{ + + machine kcar_http_common; + +#### HTTP PROTOCOL GRAMMAR +# line endings, some sites (notably http://news.ycombinator.com as of +# April 2010) do not send '\r', only '\n', so we need to accomodate them. + CRLF = ("\r")? "\n"; + +# character types + CTL = (cntrl | 127); + safe = ("$" | "-" | "_" | "."); + extra = ("!" | "*" | "'" | "(" | ")" | ","); + reserved = (";" | "/" | "?" | ":" | "@" | "&" | "=" | "+"); + 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 | sorta_safe); + pchar = (uchar | ":" | "@" | "&" | "=" | "+"); + tspecials = ("(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\\" | "\"" | "/" | "[" | "]" | "?" | "=" | "{" | "}" | " " | "\t"); + lws = (" " | "\t"); + +# elements + token = (ascii -- (CTL | tspecials)); + phrase = (any -- CRLF)+; + Status_Phrase = (digit+ (" "+ phrase)?) >mark %status_phrase ; + http_number = (digit+ "." digit+) ; + HTTP_Version = ("HTTP/" http_number) >mark %http_version ; + Status_Line = HTTP_Version " "+ Status_Phrase :> CRLF; + + field_name = ( token -- ":" )+ >start_field %write_field; + + field_value = any* >start_value %write_value; + + value_cont = lws+ any* >start_value %write_cont_value; + + message_header = ((field_name ":" " "* field_value)|value_cont) :> CRLF; + chunk_ext_val = token*; + chunk_ext_name = token*; + chunk_extension = ( ";" " "* chunk_ext_name ("=" chunk_ext_val)? )*; + last_chunk = "0"+ chunk_extension CRLF; + chunk_size = (xdigit* [1-9a-fA-F] xdigit*) $add_to_chunk_size; + chunk_end = CRLF; + chunk_body = any >skip_chunk_data; + chunk_begin = chunk_size chunk_extension CRLF; + chunk = chunk_begin chunk_body chunk_end; + ChunkedBody := chunk* last_chunk @end_chunked_body; + Trailers := (message_header)* CRLF @end_trailers; + + FullResponse = Status_Line (message_header)* CRLF @header_done; + +main := FullResponse; + +}%% |