let send_CRLF = send_raw ~data:crlf
let send_header ~header ~value =
- Http_parser.heal_header (header, value);
+ Http_parser_sanity.heal_header (header, value);
send_raw ~data:(header ^ ": " ^ value ^ crlf)
let send_headers ~headers outchan =
of an HTTP response; body, if given, will be appended to the body *)
let send_foo_body code body = send_raw ~data:(foo_body code body)
- (* TODO add the computation of Content-Length header *)
let respond
(* Warning: keep default values in sync with Http_response.response class *)
?(body = "") ?(headers = [])
in
send_basic_headers ~version ~code outchan;
send_headers ~headers outchan;
+ send_header "Content-Length" (string_of_int (String.length body)) outchan;
send_CRLF outchan;
send_raw ~data:body outchan
let safe_parse_request = wrap_parse_request_w_safety parse_request
(* as above but for OO version (Http_parser.parse_request') *)
-let safe_parse_request' = wrap_parse_request_w_safety parse_request'
+let safe_parse_request' = wrap_parse_request_w_safety (new Http_request.request)
let chdir_to_document_root = function (* chdir to document root *)
| Some dir -> Sys.chdir dir
| None -> ()
+let server_of_mode = function
+ | `Single -> Http_tcp_server.simple
+ | `Fork -> Http_tcp_server.ocaml_builtin
+ | `Thread -> Http_tcp_server.thread
+
(* TODO support also chroot to 'root', not only chdir *)
(* curried request *)
let start
flush outchan
with Again -> ()
in
- match mode with
- | `Single -> Http_tcp_server.simple ~sockaddr ~timeout daemon_callback
- | `Fork -> Http_tcp_server.ocaml_builtin ~sockaddr ~timeout daemon_callback
- | `Thread -> Http_tcp_server.thread ~sockaddr ~timeout daemon_callback
+ (server_of_mode mode) ~sockaddr ~timeout daemon_callback
(* OO request *)
let start'
?(addr = default_addr) ?(port = default_port)
?(timeout = Some default_timeout) ?(mode = default_mode) ?root callback
=
- let wrapper path params outchan =
- let clisockaddr = Http_misc.peername_of_out_channel outchan in
- let req = new Http_request.request ~path ~params ~clisockaddr in
- callback req outchan
+ chdir_to_document_root root;
+ let sockaddr = Http_misc.build_sockaddr (addr, port) in
+ let daemon_callback inchan outchan =
+ try
+ let req = safe_parse_request' inchan outchan in
+ callback req outchan;
+ flush outchan
+ with Again -> ()
in
- match root with
- | None -> start ~addr ~port ~timeout ~mode wrapper
- | Some root -> start ~addr ~port ~timeout ~mode ~root wrapper
+ (server_of_mode mode) ~sockaddr ~timeout daemon_callback
module Trivial =
struct
(if 'file' is given) or as a file name (if 'name' is given) *)
val send_file: ?name:string -> ?file:in_channel -> out_channel -> unit
- (** high level response function, respond on outchan sending: basic headers,
- headers probided via 'headers' argument, body given via 'body' argument.
- Default response status is 200, default response HTTP version is
- Http_common.http_version *)
+ (** high level response function, respond on outchan sending: basic headers
+ (including Content-Length computed using 'body' argument), headers probided
+ via 'headers' argument, body given via 'body' argument. Default response
+ status is 200, default response HTTP version is Http_common.http_version *)
val respond:
?body:string -> ?headers:(string * string) list ->
?version:Http_types.version -> ?code:int -> ?status:Http_types.status ->