mirror of
https://github.com/c-cube/tiny_httpd.git
synced 2025-12-06 11:15:35 -05:00
Merge pull request #87 from c-cube/simon/fix-chunk-2024-06-18
fix chunking reading
This commit is contained in:
commit
0b4c28264c
6 changed files with 59 additions and 4 deletions
3
Makefile
3
Makefile
|
|
@ -9,6 +9,9 @@ build:
|
||||||
test:
|
test:
|
||||||
@dune runtest --no-buffer --force $(OPTS)
|
@dune runtest --no-buffer --force $(OPTS)
|
||||||
|
|
||||||
|
test-autopromote:
|
||||||
|
@dune runtest --no-buffer --force $(OPTS) --auto-promote
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@dune clean
|
@dune clean
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -348,7 +348,14 @@ module Input = struct
|
||||||
method private refill (slice : Slice.t) : unit =
|
method private refill (slice : Slice.t) : unit =
|
||||||
if !chunk_size = 0 && not !eof then (
|
if !chunk_size = 0 && not !eof then (
|
||||||
chunk_size := read_next_chunk_len ();
|
chunk_size := read_next_chunk_len ();
|
||||||
if !chunk_size = 0 then eof := true (* stream is finished *)
|
if !chunk_size = 0 then (
|
||||||
|
(* stream is finished, consume trailing \r\n *)
|
||||||
|
eof := true;
|
||||||
|
let line = read_line_using ~buf:line_buf ic in
|
||||||
|
if String.trim line <> "" then
|
||||||
|
raise
|
||||||
|
(fail (spf "expected \\r\\n to follow last chunk, got %S" line))
|
||||||
|
)
|
||||||
);
|
);
|
||||||
slice.off <- 0;
|
slice.off <- 0;
|
||||||
slice.len <- 0;
|
slice.len <- 0;
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ test_out.txt
|
||||||
</html>
|
</html>
|
||||||
hello
|
hello
|
||||||
world
|
world
|
||||||
ykjNycnnKs8vyknhAgAAAP//AwA=
|
ykjNycnnKs8vyknhAgAAAP//
|
||||||
|
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,10 @@ sleep 0.1
|
||||||
curl -N "http://localhost:${PORT}/vfs/a.txt" --max-time 5
|
curl -N "http://localhost:${PORT}/vfs/a.txt" --max-time 5
|
||||||
|
|
||||||
sleep 0.1
|
sleep 0.1
|
||||||
curl -N "http://localhost:${PORT}/vfs/a.txt" -H 'accept-encoding: deflate' --max-time 5 | base64
|
# NOTE: the sed is there because of a timing/deflate non determinism. Both strings
|
||||||
|
# decompress to the same "hello\nworld\n" but which one is picked depends on
|
||||||
|
# the machine/library/… ?? but both are valid.
|
||||||
|
curl -N "http://localhost:${PORT}/vfs/a.txt" -H 'accept-encoding: deflate' --max-time 5 | base64 | sed 's+ykjNycnnKs8vyknhAgAAAP//AwA=+ykjNycnnKs8vyknhAgAAAP//+'
|
||||||
|
|
||||||
sleep 0.1
|
sleep 0.1
|
||||||
curl -N "http://localhost:${PORT}/vfs/sub/yolo.html" --max-time 5
|
curl -N "http://localhost:${PORT}/vfs/sub/yolo.html" --max-time 5
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
(tests
|
(tests
|
||||||
(names t_util t_buf t_server)
|
(names t_util t_buf t_server t_io)
|
||||||
(package tiny_httpd)
|
(package tiny_httpd)
|
||||||
(libraries tiny_httpd.core qcheck-core qcheck-core.runner test_util))
|
(libraries tiny_httpd.core qcheck-core qcheck-core.runner test_util))
|
||||||
|
|
|
||||||
42
tests/unit/t_io.ml
Normal file
42
tests/unit/t_io.ml
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
open Test_util
|
||||||
|
open Tiny_httpd_core.IO
|
||||||
|
|
||||||
|
let spf = Printf.sprintf
|
||||||
|
|
||||||
|
(* one chunk *)
|
||||||
|
let () =
|
||||||
|
let io = Input.of_string "5\r\nhello\r\n0\r\n\r\nARGH" in
|
||||||
|
let str =
|
||||||
|
io
|
||||||
|
|> Input.read_chunked ~bytes:(Bytes.create 4) ~fail:failwith
|
||||||
|
|> Input.read_all_using ~buf:(Buf.create ())
|
||||||
|
in
|
||||||
|
assert_eq ~to_string:(spf "%S") "hello" str
|
||||||
|
|
||||||
|
(* two chunks *)
|
||||||
|
let () =
|
||||||
|
let io = Input.of_string "5\r\nhello\r\n6\r\n world\r\n0\r\n\r\nARGH" in
|
||||||
|
let str =
|
||||||
|
io
|
||||||
|
|> Input.read_chunked ~bytes:(Bytes.create 4) ~fail:failwith
|
||||||
|
|> Input.read_all_using ~buf:(Buf.create ())
|
||||||
|
in
|
||||||
|
assert_eq ~to_string:(spf "%S") "hello world" str;
|
||||||
|
|
||||||
|
let str_rest = io |> Input.read_all_using ~buf:(Buf.create ()) in
|
||||||
|
assert_eq ~to_string:(spf "%S") "ARGH" str_rest;
|
||||||
|
()
|
||||||
|
|
||||||
|
(* two chunks *)
|
||||||
|
let () =
|
||||||
|
let io = Input.of_string "10\r\n{\"poCheck\":true}\r\n0\r\n\r\n" in
|
||||||
|
let str =
|
||||||
|
io
|
||||||
|
|> Input.read_chunked ~bytes:(Bytes.create 4) ~fail:failwith
|
||||||
|
|> Input.read_all_using ~buf:(Buf.create ())
|
||||||
|
in
|
||||||
|
assert_eq ~to_string:(spf "%S") {|{"poCheck":true}|} str;
|
||||||
|
|
||||||
|
let str_rest = io |> Input.read_all_using ~buf:(Buf.create ()) in
|
||||||
|
assert_eq ~to_string:(spf "%S") "" str_rest;
|
||||||
|
()
|
||||||
Loading…
Add table
Reference in a new issue