104 lines
2.8 KiB
OCaml
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
|
|
]
|