- with End_of_file ->
- if !line = "" then
- raise End_of_file
- else
- !line
-
- (** given an input channel, reads from it a GET HTTP request and
- @return a pair <path, query_params> where path is a string representing the
- requested path and query_params is a list of pairs <name, value> (the GET
- parameters)
- *)
-let parse_request =
- let patch_empty_path s = (if s = "" then "/" else s) in
- let pieces_sep = Pcre.regexp " " in
- fun ic ->
- let request_line = generic_input_line ~sep:Http_common.crlf ~ic in
- match Pcre.split ~rex:pieces_sep request_line with
- | [meth; request_uri_raw; http_version] ->
- if meth <> "GET" then
- raise (Unsupported_method meth);
- (match http_version with
- | "HTTP/1.0" | "HTTP/1.1" -> ()
- | _ -> raise (Unsupported_HTTP_version http_version));
- let request_uri =
+ with Line_completed -> !line
+
+let patch_empty_path = function "" -> "/" | s -> s
+let debug_dump_request path params =
+ debug_print
+ (sprintf
+ "recevied request; path: %s; params: %s"
+ path
+ (String.concat ", " (List.map (fun (n, v) -> n ^ "=" ^ v) params)))
+
+let parse_request_fst_line ic =
+ let request_line = generic_input_line ~sep:crlf ~ic in
+ debug_print (sprintf "HTTP request line (not yet parsed): %s" request_line);
+ try
+ (match Pcre.split ~rex:pieces_sep request_line with
+ | [ meth_raw; uri_raw ] -> (* ancient HTTP request line *)
+ (method_of_string meth_raw, (* method *)
+ Http_parser_sanity.url_of_string uri_raw, (* uri *)
+ None) (* no version given *)
+ | [ meth_raw; uri_raw; http_version_raw ] -> (* HTTP 1.{0,1} *)
+ (method_of_string meth_raw, (* method *)
+ Http_parser_sanity.url_of_string uri_raw, (* uri *)
+ Some (version_of_string http_version_raw)) (* version *)
+ | _ -> raise (Malformed_request request_line))
+ with Malformed_URL url -> raise (Malformed_request_URI url)
+
+let parse_response_fst_line ic =
+ let response_line = generic_input_line ~sep:crlf ~ic in
+ debug_print (sprintf "HTTP response line (not yet parsed): %s" response_line);
+ try
+ (match Pcre.split ~rex:pieces_sep response_line with
+ | [ version_raw; code_raw; _ ] ->
+ (version_of_string version_raw, (* method *)
+ status_of_code (int_of_string code_raw)) (* status *)
+ | _ -> raise (Malformed_response response_line))
+ with
+ | Malformed_URL _ | Invalid_code _ | Failure "int_of_string" ->
+ raise (Malformed_response response_line)
+
+let parse_path uri = patch_empty_path (String.concat "/" (Neturl.url_path uri))
+let parse_query_get_params uri =
+ try (* act on HTTP encoded URIs *)
+ split_query_params (Neturl.url_query ~encoded:true uri)
+ with Not_found -> []
+
+let parse_headers ic =
+ (* consume also trailing "^\r\n$" line *)
+ let rec parse_headers' headers =
+ match generic_input_line ~sep:crlf ~ic with
+ | "" -> List.rev headers
+ | line ->
+ (let subs =