You almost had it – just need to create a custom resolver in order to map a hostname into a Unix domain socket. There is no standard way to do this in HTTP (something has to be present in the Host
field in HTTP/1.1), so we just make up a name like docker
.
open Lwt.Infix
let t =
let resolver =
let h = Hashtbl.create 1 in
Hashtbl.add h "docker" (`Unix_domain_socket "/var/run/docker.sock");
Resolver_lwt_unix.static h in
let ctx = Cohttp_lwt_unix.Client.custom_ctx ~resolver () in
Cohttp_lwt_unix.Client.get ~ctx (Uri.of_string "http://docker/version") >>= fun (resp, body) ->
let open Cohttp in
let code = resp |> Response.status |> Code.code_of_status in
Printf.printf "Response code: %d\n" code;
Printf.printf "Headers: %s\n" (resp |> Response.headers |> Header.to_string);
body |> Cohttp_lwt.Body.to_string >|= fun body ->
Printf.printf "Body of length: %d\n" (String.length body);
print_endline ("Received body\n" ^ body)
let _ = Lwt_main.run t
Run this with CONDUIT_DEBUG=1
in the environment and I get:
Resolver static: http://docker/version ((name http) (port 80) (tls false)) -> (Unix_domain_socket /var/run/docker.sock)
Response code: 200
Headers: api-version: 1.37
content-length: 574
content-type: application/json
date: Fri, 23 Mar 2018 17:27:32 GMT
docker-experimental: true
ostype: linux
server: Docker/18.03.0-ce-rc4 (linux)
Body of length: 574
Received body
{"Platform":{"Name":""},"Components":[{"Name":"Engine","Version":"18.03.0-ce-rc4","Details":{"ApiVersion":"1.37","Arch":"amd64","BuildTime":"2018-03-15T07:42:29.000000000+00:00","Experimental":"true","GitCommit":"fbedb97","GoVersion":"go1.9.4","KernelVersion":"4.9.87-linuxkit-aufs","MinAPIVersion":"1.12","Os":"linux"}}],"Version":"18.03.0-ce-rc4","ApiVersion":"1.37","MinAPIVersion":"1.12","GitCommit":"fbedb97","GoVersion":"go1.9.4","Os":"linux","Arch":"amd64","KernelVersion":"4.9.87-linuxkit-aufs","Experimental":true,"BuildTime":"2018-03-15T07:42:29.000000000+00:00"}