Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make a simple GET request in OCaml?

Tags:

http

ocaml

I'm trying to do something that should be simple: make a GET request to a url. However, when I search for examples of how to do this I often wind up with near-gibberish like this.

Does anyone know how to make a simple HTTP request using OCaml? I'm an OCaml newbie with some Haskell exp.

NOTE:

A solution using the lowest possible level OCaml would be ideal. I've seen the Cohttp library used, but I'm more interested in a native (?) HTTP OCaml lib or something along those lines.

In response to @antron, a solution using the lowest possible level native OCaml would be much appreciated. I'm led to believe that this will involve the Unix library. But if there is another solution that does not involve 3rd party libraries it would be just as welcome.

like image 428
dopatraman Avatar asked Mar 17 '16 19:03

dopatraman


2 Answers

Use the Cohttp library. See the Client example.

The relevant line is:

Cohttp_lwt_unix.Client.get (Uri.of_string "http://www.reddit.com/")

This gives you a pair of (response, body) inside the Lwt monad. response is basically a record, and body is a stream. The rest of the example is just printing some interesting bits of those.

like image 173
antron Avatar answered Sep 18 '22 12:09

antron


Perhaps the most basic way to send a GET request in OCaml is to use the Unix library and the basic input/output routines from Pervasives.

Here is a very simple example:

let ip = Unix.((gethostbyname "caml.inria.fr").h_addr_list.(0))
let addr = Unix.ADDR_INET (ip, 80)

let sock = Unix.(socket PF_INET SOCK_STREAM 0)
let _ = Unix.connect sock addr

let in_ch = Unix.in_channel_of_descr sock
let out_ch = Unix.out_channel_of_descr sock

let _ =
  output_string out_ch
    "GET /pub/docs/manual-ocaml/index.html HTTP/1.1\r\n\
     Host: caml.inria.fr\r\n\
     User-Agent: OCaml\r\n\
     Connection: close\r\n\
     \r\n";
  flush out_ch

let _ =
  try
    while true do
      print_string (input_line in_ch)
    done
  with End_of_file ->
    Unix.close sock

The Unix. prefixes are not necessary if one puts open Unix at the top of the file, but I preferred to leave them in for clarity.

The program can be compiled to byte code with ocamlc unix.cma -o get get.ml.

I agree with @ChriS' suggestion to read Leroy and Rémy's Unix system programming in OCaml (I've included a link to the online version); it's a great book.

like image 44
tbrk Avatar answered Sep 21 '22 12:09

tbrk