Skip to content

Instantly share code, notes, and snippets.

@Chimrod
Created February 26, 2016 12:00
Show Gist options
  • Save Chimrod/cd35eb3f08a6f8a4e89e to your computer and use it in GitHub Desktop.
Save Chimrod/cd35eb3f08a6f8a4e89e to your computer and use it in GitHub Desktop.
This code will create a request, and allow to reuse the same connexion for sending more data.
let pipe_request
?socket
?headers ?(https=false) ?port ~content ?content_length
~http_method ~host ~inet_addr ~uri () =
let port = match port with
| None -> if https then 443 else 80
| Some p -> p
in
let sockaddr = Unix.ADDR_INET (inet_addr, port) in
let fd = (
match socket with
| None -> (
let s = Lwt_unix.socket (Unix.domain_of_sockaddr sockaddr) Unix.SOCK_STREAM 0 in
Lwt_unix.set_close_on_exec s;
s)
| Some x -> x
) in
let initialize_conn () =
(if https then
let s = Lwt_ssl.embed_uninitialized_socket fd !sslcontext in
Ssl.set_client_SNI_hostname
(Lwt_ssl.ssl_socket_of_uninitialized_socket s) host;
Lwt_ssl.ssl_perform_handshake s
else
Lwt.return (Lwt_ssl.plain fd))
in
Lwt.catch
(fun () ->
match socket with
| None -> Lwt_unix.connect fd sockaddr >>= initialize_conn
| Some x -> initialize_conn ()
)
(handle_connection_error fd)
>>= fun socket ->
let query = Ocsigen_http_frame.Http_header.Query (http_method, uri) in
let conn = Ocsigen_http_com.create_receiver
(Ocsigen_config.get_server_timeout ())
Ocsigen_http_com.Answer socket in
let headers =
Http_headers.replace
(Http_headers.name "host")
host
(match headers with
| None -> Http_headers.empty
| Some h -> h)
in
let f slot =
match content with
| None ->
let empty_result = Ocsigen_http_frame.Result.empty () in
Ocsigen_http_com.send
slot
~mode:query
~clientproto:Ocsigen_http_frame.Http_header.HTTP11
~head:false
~keep_alive:false
~sender:request_sender
(Ocsigen_http_frame.Result.update empty_result
~headers ())
| Some stream ->
Ocsigen_senders.Stream_content.result_of_content stream >>= fun r ->
Ocsigen_http_com.send
slot
~mode:query
~clientproto:Ocsigen_http_frame.Http_header.HTTP11
~head:false
~keep_alive:false
~sender:request_sender
(Ocsigen_http_frame.Result.update r
~content_length
~headers ())
in
Ocsigen_http_com.start_processing conn f; (* starting the request *)
(* Ocsigen_http_com.wait_all_senders conn >>= fun () -> (* not needed *) *)
Lwt.catch
(fun () ->
Ocsigen_http_com.get_http_frame
~head:(http_method = Ocsigen_http_frame.Http_header.HEAD)
conn
>>= fun http_frame ->
(match http_frame.Ocsigen_http_frame.frame_content with
| None -> Lwt_ssl.close socket
| Some c ->
Ocsigen_stream.add_finalizer c (fun _ -> Lwt_ssl.close socket);
Lwt.return ())
>>= fun () -> Lwt.return (fd, http_frame))
(fun e -> Lwt_ssl.close socket >>= fun () -> Lwt.fail e)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment