Update changelog and prepare upload to unstable
[pkg-ocaml-ocsigen.git] / http / http_parser.mly
blob37095606044cf5100302a12a708d2436510502f2
1 %{
2 (* Ocsigen
3  * http://www.ocsigen.org
4  * http_parser.mly Copyright (C) 2005 Denis Berthod
5  * Laboratoire PPS - CNRS Université Paris Diderot
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation, with linking exception;
10  * either version 2.1 of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  *)
22   open Ocsigen_http_frame
23   open Http_header
25   let mode = ref Nofirstline
26   let proto = ref HTTP11
27   let headers = ref Http_headers.empty
29   let reset_header () = headers := Http_headers.empty
31   let add_header (n, v) = headers := Http_headers.add n v !headers
33   let make_header() =
34     {mode = !mode;
35      proto= !proto;
36      headers= !headers}
38   let meth_of_string =
39     function
40       | "GET" -> GET
41       | "POST" -> POST
42       | "HEAD" -> HEAD
43       | "PUT" -> PUT
44       | "DELETE" -> DELETE
45       | "TRACE" -> TRACE
46       | "OPTIONS" -> OPTIONS
47       | "CONNECT" -> CONNECT
48       | "LINK" -> LINK
49       | "UNLINK" -> UNLINK
50       | "PATCH" -> PATCH
51       | s -> assert false
53   let proto_of_string =
54     function
55       | "HTTP/1.1" -> HTTP11
56       | "HTTP/1.0" -> HTTP10
57       | s -> raise (Http_error.Http_exception (505, None, None))
60   let split_string s =
61     try
62     let ind = String.index s ':' in
63     (String.lowercase (String.sub s 0 ind )),
64       String.lowercase (String.sub s (ind+1) ((String.length s) - ind-1) )
65     with Not_found  ->
66       raise (Http_error.Http_exception (Some 400,["bad header format"]))
70 %token COLON EOL
71 %token <string>METHOD
72 %token <string>PROTO
73 %token <string>STRING
74 %token <string>CODE
76 %start header nofirstline
77 %type <Ocsigen_http_frame.Http_header.http_header>header
78 %type <Ocsigen_http_frame.Http_header.http_header>nofirstline
81 header :
82   | firstline EOL                {make_header()}
83   | firstline lines EOL          {make_header()}
85 firstline :
86   | METHOD STRING end_of_firstline   {reset_header ();
87                                       let (a, b) = $3 in
88                                       mode := Query (meth_of_string($1), $2^a);
89                                       proto := b}
90   | PROTO CODE strings EOL       {reset_header ();
91                                  mode := Answer (int_of_string $2);
92                                  proto:=(proto_of_string $1)
93                                }
95 nofirstline :
96   | EOL                          {mode := Nofirstline;
97                                   proto := HTTP11;
98                                   make_header()}
99   | lines EOL                    {mode := Nofirstline;
100                                   proto := HTTP11;
101                                   make_header()}
103 lines :
104   | line                         {add_header $1}
105   | line lines                   {add_header $1;$2}
106   | strings EOL                  {}
107   | strings EOL lines            {$3}
109 line :
110   | STRING COLON strings EOL    {(Http_headers.name $1,$3)}
111   | CODE COLON strings EOL      {(Http_headers.name $1,$3)  (*XXX Check*)}
112   | STRING COLON EOL            {(Http_headers.name $1,"")}
113   | CODE COLON EOL              {(Http_headers.name $1,"")  (*XXX Check*)}
114   /* EOL                  {split_string $1}*/
116 strings :
117   | COLON                        {":"}
118   | STRING                       {$1}
119   | STRING COLON strings         {$1^":"^$3}
120   | STRING strings               {$1^" "^$2}
121   | PROTO                        {$1}
122   | PROTO COLON strings          {$1^":"^$3}
123   | PROTO strings                {$1^" "^$2}
124   | METHOD                       {$1}
125   | METHOD COLON strings         {$1^":"^$3}
126   | METHOD strings               {$1^" "^$2}
127   | CODE                         {$1}
128   | CODE strings                 {$1^" "^$2}
129   | CODE COLON strings           {$1^":"^$3}
131 end_of_firstline:
132   | PROTO EOL                      {("", proto_of_string $1)}
133   | COLON end_of_firstline         {let (a, b) = $2 in (":"^a, b)}
134   | STRING end_of_firstline        {let (a, b) = $2 in ($1^a, b)}
139 let nofirstline a =
140   reset_header ();
141   nofirstline a