1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
let () =
Logs.set_level ~all:true @@ Some Logs.Debug;
Logs.set_reporter (Logs_fmt.reporter ())
let handler _conn request body =
match Http.Request.resource request with
| "/" -> Cohttp_eio.Server.respond_string ~status:`OK ~body:"root" ()
| "/stream" ->
let body = Eio_mock.Flow.make "streaming body" in
let () =
Eio_mock.Flow.on_read body
[ `Return "Hello"; `Yield_then (`Return "World") ]
in
Cohttp_eio.Server.respond ~status:`OK ~body ()
| "/post" -> Cohttp_eio.Server.respond ~status:`OK ~body ()
| _ -> Cohttp_eio.Server.respond_string ~status:`Not_found ~body:"" ()
let () =
Eio_main.run @@ fun env ->
Eio.Switch.run @@ fun sw ->
let () =
let socket =
Eio.Net.listen env#net ~sw ~backlog:128 ~reuse_addr:true ~reuse_port:true
(`Tcp (Eio.Net.Ipaddr.V4.loopback, 4242))
and server = Cohttp_eio.Server.make ~callback:handler () in
Eio.Fiber.fork_daemon ~sw @@ fun () ->
let () = Cohttp_eio.Server.run socket server ~on_error:raise in
`Stop_daemon
in
let test_case name f =
let f () =
let socket =
Eio.Net.connect ~sw env#net (`Tcp (Eio.Net.Ipaddr.V4.loopback, 4242))
in
f socket
in
Alcotest.test_case name `Quick f
in
let root socket =
let () =
Eio.Flow.write socket
[ Cstruct.of_string "GET / HTTP/1.1\r\nconnection: close\r\n\r\n" ]
in
Alcotest.(check ~here:[%here] string)
"response"
"HTTP/1.1 200 OK\r\nconnection: close\r\ncontent-length: 4\r\n\r\nroot"
Eio.Buf_read.(of_flow ~max_size:max_int socket |> take_all)
and missing socket =
let () =
Eio.Flow.write socket
[
Cstruct.of_string "GET /missing HTTP/1.1\r\nconnection: close\r\n\r\n";
]
in
Alcotest.(check ~here:[%here] string)
"response"
"HTTP/1.1 404 Not Found\r\nconnection: close\r\ncontent-length: 0\r\n\r\n"
Eio.Buf_read.(of_flow ~max_size:max_int socket |> take_all)
and streaming_response socket =
let () =
Eio.Flow.write socket
[
Cstruct.of_string "GET /stream HTTP/1.1\r\nconnection: close\r\n\r\n";
]
in
Alcotest.(check ~here:[%here] string)
"response"
"HTTP/1.1 200 OK\r\n\
connection: close\r\n\
transfer-encoding: chunked\r\n\
\r\n\
5\r\n\
Hello\r\n\
5\r\n\
World\r\n\
0\r\n\
\r\n"
Eio.Buf_read.(of_flow ~max_size:max_int socket |> take_all)
and request_body socket =
let () =
Eio.Flow.write socket
[
Cstruct.of_string
"POST /post HTTP/1.1\r\n\
connection: close\r\n\
content-length:12\r\n\
\r\n\
hello world!";
]
in
Alcotest.(check ~here:[%here] string)
"response"
"HTTP/1.1 200 OK\r\n\
connection: close\r\n\
transfer-encoding: chunked\r\n\
\r\n\
c\r\n\
hello world!\r\n\
0\r\n\
\r\n"
Eio.Buf_read.(of_flow ~max_size:max_int socket |> take_all)
in
Alcotest.run "cohttp-eio"
[
( "cohttp-eio server",
[
test_case "root" root;
test_case "missing" missing;
test_case "streaming response" streaming_response;
test_case "request body" request_body;
] );
]
|