let uri_str = Neturl.string_of_url uri in
let path = Http_parser.parse_path uri in
let query_get_params = Http_parser.parse_query_get_params uri in
- let headers = Http_parser.parse_headers ic in (* trailing \r\n consumed! *)
+ let headers =
+ List.map (* lowercase header names to ease lookups before having a request
+ object *)
+ (fun (h,v) -> (String.lowercase h, v))
+ (Http_parser.parse_headers ic) (* trailing \r\n consumed! *)
+ in
let body =
(* TODO fallback on Transfer-Encoding if Content-Length isn't defined *)
if meth = `POST then
(try (* read only Content-Length bytes *)
let limit_raw =
(try
- (snd (List.find
- (fun (h,v) -> String.lowercase h = "content-length") headers))
+ List.assoc "content-length" headers
with Not_found -> raise Fallback)
in
let limit =
(try (* TODO supports only a maximum content-length of 1Gb *)
int_of_string limit_raw
with Failure "int_of_string" ->
- raise (Invalid_header ("Content-Length: " ^ limit_raw)))
+ raise (Invalid_header ("content-length: " ^ limit_raw)))
in
Http_misc.buf_of_inchan ~limit ic
with Fallback -> Http_misc.buf_of_inchan ic) (* read until EOF *)
else "" (* TODO empty body for methods other than POST, is what we want? *)
in
- (* TODO brave assumption: when meth = `POST, Content-Type is
- application/x-www-form-urlencoded and is therefore one-liner parsed as a GET
- query *)
let query_post_params =
match meth with
- | `POST -> Http_parser.split_query_params body
+ | `POST ->
+ let ct = try List.assoc "content-type" headers with Not_found -> "" in
+ if ct = "application/x-www-form-urlencoded" then
+ Http_parser.split_query_params body
+ else []
| _ -> []
in
let params = query_post_params @ query_get_params in (* prefers POST params *)