You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

62 lines
1.7 KiB

type response = {
body: string,
status: int,
};
let body = response => response.body;
let status = response => response.status;
let rec getBody = listOfStrings =>
switch (listOfStrings) {
| [] => ""
| ["", ...rest] => String.concat("\n", rest)
| [_, ...xs] => getBody(xs)
};
let getStatus = string =>
List.nth(String.split_on_char(' ', string), 1) |> int_of_string;
exception Unknown_status_code(int, response);
exception Not_found(response);
exception Internal_server_error(response);
let verifyStatus = response =>
switch (response.status) {
| 200 => Lwt.return(response)
| x when x / 100 == 4 => Lwt.fail(Not_found(response))
| x when x / 100 == 5 => Lwt.fail(Internal_server_error(response))
| x => Lwt.fail(Unknown_status_code(response.status, response))
};
let rec skipRedirects = (~skipping=false, lines) =>
switch (skipping, lines) {
| (_, []) => failwith("Response is empty")
| (true, ["", ...xs]) => skipRedirects(~skipping=false, xs)
| (true, [x, ...xs]) => skipRedirects(~skipping=true, xs)
| (false, [x, ...xs])
when Str.first_chars(x, 4) == "HTTP" && getStatus(x) / 100 == 3 =>
skipRedirects(~skipping=true, xs)
| (false, xs) => xs
};
let parseResponse = lines => {
let linesAfterRedirect = skipRedirects(lines);
let body = getBody(linesAfterRedirect);
let status = getStatus(linesAfterRedirect |> List.hd);
{body, status};
};
let makeRequest = url => {
let%lwt response =
System.unix_exec("curl", ~args=[|url, "-D", "-", "--silent"|]);
response |> parseResponse |> verifyStatus;
};
let download = (url, ~into) => {
let%lwt response =
System.unix_exec(
"curl",
~args=[|url, "-L", "-D", "-", "--silent", "-o", into|],
);
response |> parseResponse |> verifyStatus;
};