Skip to content

Commit

Permalink
Add eio backend using parsing and serialization from Http and Cohttp.
Browse files Browse the repository at this point in the history
  • Loading branch information
mefyl committed Jun 14, 2023
1 parent ee1ba0b commit a5fb7dc
Show file tree
Hide file tree
Showing 25 changed files with 573 additions and 1,552 deletions.
1 change: 1 addition & 0 deletions cohttp-eio.opam
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ bug-reports: "https://github.com/mirage/ocaml-cohttp/issues"
depends: [
"dune" {>= "3.0"}
"base-domains"
"cohttp" {= version}
"eio" {>= "0.7"}
"eio_main" {with-test}
"mdx" {with-test}
Expand Down
13 changes: 11 additions & 2 deletions cohttp-eio/examples/client1.ml
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
open Cohttp_eio

let () = Logs.set_reporter (Logs_fmt.reporter ())
and () = Logs.Src.set_level Cohttp_eio.src (Some Debug)

let () =
Eio_main.run @@ fun env ->
let res = Client.get env ~host:"www.example.org" "/" in
print_string @@ Client.read_fixed res
Eio.Switch.run @@ fun sw ->
match Client.get ~sw env#net (Uri.of_string "http://example.com") with
| Result.Ok (resp, body) when Http.Status.compare resp.status `OK = 0 ->
Fmt.string Format.std_formatter
@@ Eio.Buf_read.(take_all @@ of_flow ~max_size:max_int body)
| Result.Ok (resp, _) ->
Fmt.epr "Unexpected HTTP status: %a" Http.Status.pp resp.status
| Result.Error e -> Fmt.epr "HTTP error: %s" e
16 changes: 7 additions & 9 deletions cohttp-eio/examples/client_timeout.ml
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
open Eio
open Cohttp_eio

let () =
Eio_main.run @@ fun env ->
Switch.run @@ fun sw ->
(* Increment/decrement this value to see success/failure. *)
let timeout_s = 0.01 in
Eio.Time.with_timeout env#clock timeout_s (fun () ->
let host, port = ("www.example.org", 80) in
let he = Unix.gethostbyname host in
let addr = `Tcp (Eio_unix.Ipaddr.of_unix he.h_addr_list.(0), port) in
let conn = Net.connect ~sw env#net addr in
let res = Client.get ~conn ~port env ~host "/" in
Client.read_fixed res |> Result.ok)
Eio.Switch.run @@ fun sw ->
match Client.get env#net ~sw (Uri.of_string "http://www.example.org") with
| Result.Error e -> Result.Error (`Fatal e)
| Result.Ok (_, body) ->
Eio.Buf_read.(of_flow ~max_size:max_int body |> take_all) |> Result.ok)
|> function
| Ok s -> print_string s
| Error `Timeout -> print_string "Connection timed out"
| Error (`Fatal e) -> Fmt.epr "fatal error: %s@." e
| Error `Timeout -> Fmt.epr "Connection timed out@."
31 changes: 20 additions & 11 deletions cohttp-eio/examples/docker_client.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,25 @@ module Client = Cohttp_eio.Client
module Response = Http.Response
module Status = Http.Status

let () = Logs.set_reporter (Logs_fmt.reporter ())
and () = Logs.Src.set_level Cohttp_eio.src (Some Debug)

let () =
Eio_main.run @@ fun env ->
Switch.run @@ fun sw ->
let addr = `Unix "/var/run/docker.sock" in
let conn = Net.connect ~sw env#net addr in
let res = Client.get ~conn ~host:"docker" env "/version" in
let code = fst res |> Response.status |> Status.to_int in
Printf.printf "Response code: %d\n" code;
Printf.printf "Headers: %s\n"
(fst res |> Response.headers |> Http.Header.to_string);
let body = Client.read_fixed res in
Printf.printf "Body of length: %d\n" (String.length body);
print_endline ("Received body\n" ^ body)
Eio.Switch.run @@ fun sw ->
match
Client.get env#net ~sw
@@ Uri.make ~scheme:"httpunix" ~host:"/var/run/docker.sock" ~path:"/version"
()
with
| Result.Error error ->
Printf.eprintf "fatal error: %sn" error;
exit 1
| Result.Ok (response, body) ->
let code = response |> Response.status |> Status.to_int in
Printf.printf "Response code: %d\n" code;
Printf.printf "Headers: %s\n"
(response |> Response.headers |> Http.Header.to_string);
let body = Eio.Buf_read.(of_flow ~max_size:max_int body |> take_all) in
Printf.printf "Body of length: %d\n" (String.length body);
print_endline ("Received body\n" ^ body)
2 changes: 1 addition & 1 deletion cohttp-eio/examples/dune
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
(executables
(names server1 client1 docker_client client_timeout)
(libraries cohttp-eio eio_main eio.unix unix))
(libraries cohttp-eio eio_main eio.unix fmt unix logs.fmt))

(alias
(name runtest)
Expand Down
25 changes: 16 additions & 9 deletions cohttp-eio/examples/server1.ml
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,26 @@ let text =
was coming to, but it was too dark to see anything; then she looked at the \
sides of the well, and noticed that they were filled with cupboards......"

open Cohttp_eio
let () = Logs.set_reporter (Logs_fmt.reporter ())
and () = Logs.Src.set_level Cohttp_eio.src (Some Debug)

let app : Server.request -> Server.response =
fun ((req, _, _) : Server.request) ->
match Http.Request.resource req with
| "/" -> Server.text_response text
| "/html" -> Server.html_response text
| _ -> Server.not_found_response
let handler ~sw:_ _peer request _body =
match Http.Request.resource request with
| "/" -> (Http.Response.make (), Cohttp_eio.Body.of_string text)
| "/html" ->
( Http.Response.make
~headers:(Http.Header.of_list [ ("content-type", "text/html") ])
(),
(* Use a plain flow to test chunked encoding *)
Eio.Flow.string_source text )
| _ -> (Http.Response.make ~status:`Not_found (), Cohttp_eio.Body.of_string "")

let () =
let port = ref 8080 in
Arg.parse
[ ("-p", Arg.Set_int port, " Listening port number(8080 by default)") ]
ignore "An HTTP/1.1 server";

Eio_main.run @@ fun env -> Server.run ~port:!port env app
Eio_main.run @@ fun env ->
Eio.Switch.run @@ fun sw ->
let server = Cohttp_eio.Server.make env#net ~sw ~port:!port handler in
Cohttp_eio.Server.run server
Loading

0 comments on commit a5fb7dc

Please sign in to comment.