mte/unikernel/duniverse/httpun/lib_test/test_request.ml
2025-11-11 02:07:51 +01:00

104 lines
2.8 KiB
OCaml

open Httpun
open Request
open Helpers
let body_length = Alcotest.of_pp Request.Body_length.pp_hum
let check =
let alco =
Alcotest.result
(Alcotest.of_pp pp_hum)
Alcotest.string
in
fun message ~expect input ->
let actual =
Angstrom.parse_string ~consume:All Httpun_private.Parse.request input
in
Alcotest.check alco message expect actual
;;
let test_parse_valid () =
check
"valid GET without headers"
~expect:(Ok (Request.create `GET "/"))
"GET / HTTP/1.1\r\n\r\n";
check
"valid non-standard method without headers"
~expect:(Ok (Request.create (`Other "some-other-verb") "/"))
"some-other-verb / HTTP/1.1\r\n\r\n";
check
"valid GET with headers"
~expect:(Ok (Request.create ~headers:(Headers.of_list [ "Link", "/path/to/some/website"]) `GET "/"))
"GET / HTTP/1.1\r\nLink: /path/to/some/website\r\n\r\n";
;;
let test_parse_invalid_errors () =
check
"doesn't end"
~expect:(Error ": not enough input")
"GET / HTTP/1.1\r\n";
check
"invalid version"
~expect:(Error "eol: string")
"GET / HTTP/1.22\r\n\r\n";
check
"malformed header"
~expect:(Error "header: char ':'")
"GET / HTTP/1.1\r\nLink : /path/to/some/website\r\n\r\n";
;;
let test_body_length () =
let check message request ~expect =
let actual = Request.body_length request in
Alcotest.check body_length message expect actual
in
let req method_ headers = Request.create method_ ~headers "/" in
check
"no headers"
~expect:(`Fixed 0L)
(req `GET Headers.empty);
check
"single fixed"
~expect:(`Fixed 10L)
(req `GET Headers.(encoding_fixed 10));
check
"negative fixed"
~expect:(`Error `Bad_request)
(req `GET Headers.(encoding_fixed (-10)));
check
"multiple fixed"
~expect:(`Error `Bad_request)
(req `GET Headers.(encoding_fixed 10 @ encoding_fixed 20));
check
"chunked"
~expect:`Chunked
(req `GET Headers.encoding_chunked);
check
"chunked multiple times"
~expect:`Chunked
(req `GET Headers.(encoding_chunked @ encoding_chunked));
let encoding_gzip = Headers.of_list ["transfer-encoding", "gzip"] in
check
"non-chunked transfer-encoding"
~expect:(`Error `Bad_request)
(req `GET encoding_gzip);
check
"chunked after non-chunked"
~expect:`Chunked
(req `GET Headers.(encoding_gzip @ encoding_chunked));
check
"chunked before non-chunked"
~expect:(`Error `Bad_request)
(req `GET Headers.(encoding_chunked @ encoding_gzip));
check
"chunked case-insensitive"
~expect:`Chunked
(req `GET Headers.(of_list ["transfer-encoding", "CHUNKED"]));
;;
let tests =
[ "parse valid" , `Quick, test_parse_valid
; "parse invalid errors", `Quick, test_parse_invalid_errors
; "body length", `Quick, test_body_length
]