I’m writing a simple client in OCaml to access the Wallabag api, and I’m stuck at the part where I need to send a get request with an arbitrary header. For context, here is what I’m trying to reproduce in OCaml: https://app.wallabag.it/developer/howto/first-app
I can get the token doing this:
let site = "https://app.wallabag.it/"
let token_url = "oauth/v2/token"
let params = [
("grant_type", "password");
("client_id", !id);
("client_secret", !secret);
("username", !user);
("password", !pass)
]
let () = Nettls_gnutls.init()
let res = Nethttp_client.Convenience.http_post (site ^ token_url) params
let token =
let json = Yojson.Basic.from_string res in
let open Yojson.Basic.Util in
json |> member "access_token" |> to_string
but I don’t know how to do the next call, where I need to set a header in the HTTP request with name “Authorization” and value “Bearer $token” (if I understand https://github.com/jakubroztocil/httpie#request-items correctly). Is there a way to do this with ocamlnet? Or do you have another library I could use for such simple GET and POST HTTP requests?
I usually use cohttp as client, the following should do more or less what you need:
open Lwt
let uri = Uri.of_string (site ^ token_url) in
let headers = Cohttp.Header.init_with "Bearer" token in
let body = params
|> List.map (fun (k,v) -> Printf.sprintf {|"%s": "%s"|} k v)
|> String.concat ", "
|> Printf.sprintf "{%s}"
|> Cohttp_lwt_body.of_string
in
Cohttp_lwt_unix.Client.post ~headers ~body uri >>= fun (resp, body) ->
...
As a follow-up, I managed to make things work. The server I’m working with does not seem to accept json encoded data for post, so I had to do this:
open Lwt
open Cohttp
open Cohttp_lwt_unix
let id = ref ""
let secret = ref ""
let user = ref ""
let pass = ref ""
let spec = [
("-id", Arg.Set_string id, "the client_id");
("-secret", Arg.Set_string secret, "the client_secret");
("-user", Arg.Set_string user, "the username");
("-pass", Arg.Set_string pass, "the password")
]
let () = Arg.parse spec (fun _ -> ()) "wbml -id client_id -secret client_secret -user username -pass password"
let site = "https://app.wallabag.it/"
let token_url = "oauth/v2/token"
let keyvallist_to_form_urlencoded p =
p |> List.map (fun (k,v) -> Printf.sprintf "%s=%s" k v)
|> String.concat "&"
|> Cohttp_lwt.Body.of_string
let params = [
("grant_type", "password");
("client_id", !id);
("client_secret", !secret);
("username", !user);
("password", !pass)
]
let get_token =
let body = keyvallist_to_form_urlencoded params in
let headers =
Header.init ()
|> fun h -> Header.add h "content-type" "application/x-www-form-urlencoded"
in
Client.post ~headers ~body (Uri.of_string (site ^ token_url)) >>= fun (resp, body) ->
body |> Cohttp_lwt.Body.to_string
let token =
let body = Lwt_main.run get_token in
let open Yojson.Basic.Util in
body |> Yojson.Basic.from_string |>
member "access_token" |> to_string