File: test.ml

package info (click to toggle)
ocaml-cohttp 6.2.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,624 kB
  • sloc: ml: 13,107; makefile: 20; sh: 18; javascript: 18
file content (112 lines) | stat: -rw-r--r-- 3,359 bytes parent folder | download
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;
        ] );
    ]