Skip to content

Instantly share code, notes, and snippets.

@ulrikstrid
Created August 8, 2019 13:54
Show Gist options
  • Save ulrikstrid/ffdf3bf87fd6005255245227d05500ba to your computer and use it in GitHub Desktop.
Save ulrikstrid/ffdf3bf87fd6005255245227d05500ba to your computer and use it in GitHub Desktop.
Fetch implementation in reason
let fetch = (~meth=`GET, ~body=?, ~headers=[], url) => {
let uri = Uri.of_string(url);
let url_host = Uri.host_with_default(~default="", uri);
let url_scheme =
Uri.scheme(uri)
|> (
fun
| Some(scheme) => scheme
| None => "https"
);
let url_port =
Uri.port(uri)
|> (
fun
| Some(port) => string_of_int(port)
| None when url_scheme == "https" => "443"
| None => "80"
);
let url_path = Uri.path(uri);
Lwt_unix.getaddrinfo(url_host, url_port, [Unix.(AI_FAMILY(PF_INET))])
>>= (
addresses => {
let socket = Lwt_unix.socket(Unix.PF_INET, Unix.SOCK_STREAM, 0);
Lwt_unix.connect(socket, List.hd(addresses).Unix.ai_addr)
>>= (
() => {
let (finished, notify_finished) = Lwt.wait();
let response_handler = read_response(~notify_finished);
let headers =
Httpaf.Headers.of_list([
(
"Content-Length",
switch (body) {
| Some(body) => string_of_int(String.length(body))
| None => "0"
},
),
("Connection", "close"),
("Host", url_host),
...headers,
]);
let client =
Lwt_ssl.embed_uninitialized_socket(
socket,
Ssl.create_context(Ssl.TLSv1_2, Ssl.Client_context),
);
let () =
Ssl.set_client_SNI_hostname(
Lwt_ssl.ssl_socket_of_uninitialized_socket(client),
url_host,
);
Lwt_ssl.ssl_perform_handshake(client)
>>= (
client =>
Httpaf_lwt_unix.Client.SSL.create_connection(
~client,
Lwt_ssl.get_fd(client),
)
>>= (
connection => {
let request_body =
Httpaf_lwt_unix.Client.SSL.request(
connection,
~error_handler,
~response_handler,
Httpaf.Request.create(~headers, meth, url_path),
);
switch (body) {
| Some(body) =>
Httpaf.Body.write_string(request_body, body)
| None => ()
};
Httpaf.Body.close_writer(request_body);
finished;
}
)
);
}
);
}
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment