kcar.git  about / heads / tags
bytestream to Rack response converter
blob 36752b0a867e1d8bdf80774103ef71492c932199 2034 bytes (raw)
$ git show v0.3.0:ext/kcar/kcar_http_common.rl	# shows this blob on the CLI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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 ":" lws* 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;

}%%

git clone https://yhbt.net/kcar.git