When using Cohttp_async
to perform a request, I'm handling an HTTP response code of 302 (Temporary Redirect) in the following manner:
let rec download uri =
Cohttp_async.Client.get uri
>>= fun (response, body) ->
let http_code = Cohttp.Code.code_of_status (Cohttp.Response.status response) in
if Cohttp.Code.is_redirection http_code then
(* Code to handle the redirect *)
else Cohttp_async.Body.to_string body
This seems to work alright (at least in the simple cases I'm using it). I'm mainly curious to see if there's a better way of doing this. I think there might be a better way to handle this, like by matching on Cohttp.Code.status
. Something like:
match http_code with
| Ok -> Cohttp_async.Body.to_string body
| Temporary_redirect -> (* Code to handle the redirect *)
| _ -> (* Failure here, possibly *)
So far, I haven't had much luck with this, as it seems like I'm not matching the right constructors.
As a second side question, does Cohttp have a better way to handle with HTTP redirects are given back as part of the response? Maybe the way I'm going about this is wrong, and there's a simpler way.
I believe the short answer to my question is that I was referring to the wrong type when trying to match on response
. There are two polymorphic types that exist - Ok
and OK
, where the latter is the Cohttp
type for an HTTP 200 response code. In my situation, I also had to handle a few kinds of redirects, which I added in.
So, the code ends up looking something like this:
let rec download uri =
Cohttp_async.Client.get uri
>>= fun (response, body) ->
let http_code = Cohttp.Response.status response in
match http_code with
| `OK -> Cohttp_async.Body.to_string body (* If we get a status of OK *)
| `Temporary_redirect | `Found -> (* Handle redirection *)
| _ -> return "" (* Catch-all for other scenarios. Not great. *)
Omitting the last case will make the compiler complain about non-exhaustive checks.