Skip to content

Commit 0b4c282

Browse files
authored
Merge pull request #87 from c-cube/simon/fix-chunk-2024-06-18
fix chunking reading
2 parents 199bcff + f720a01 commit 0b4c282

File tree

6 files changed

+59
-4
lines changed

6 files changed

+59
-4
lines changed

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ build:
99
test:
1010
@dune runtest --no-buffer --force $(OPTS)
1111

12+
test-autopromote:
13+
@dune runtest --no-buffer --force $(OPTS) --auto-promote
14+
1215
clean:
1316
@dune clean
1417

src/core/IO.ml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,14 @@ module Input = struct
348348
method private refill (slice : Slice.t) : unit =
349349
if !chunk_size = 0 && not !eof then (
350350
chunk_size := read_next_chunk_len ();
351-
if !chunk_size = 0 then eof := true (* stream is finished *)
351+
if !chunk_size = 0 then (
352+
(* stream is finished, consume trailing \r\n *)
353+
eof := true;
354+
let line = read_line_using ~buf:line_buf ic in
355+
if String.trim line <> "" then
356+
raise
357+
(fail (spf "expected \\r\\n to follow last chunk, got %S" line))
358+
)
352359
);
353360
slice.off <- 0;
354361
slice.len <- 0;

tests/echo1.expect

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ test_out.txt
5050
</html>
5151
hello
5252
world
53-
ykjNycnnKs8vyknhAgAAAP//AwA=
53+
ykjNycnnKs8vyknhAgAAAP//
5454

5555
<html>
5656
<head>

tests/echo1.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ sleep 0.1
1515
curl -N "http://localhost:${PORT}/vfs/a.txt" --max-time 5
1616

1717
sleep 0.1
18-
curl -N "http://localhost:${PORT}/vfs/a.txt" -H 'accept-encoding: deflate' --max-time 5 | base64
18+
# NOTE: the sed is there because of a timing/deflate non determinism. Both strings
19+
# decompress to the same "hello\nworld\n" but which one is picked depends on
20+
# the machine/library/… ?? but both are valid.
21+
curl -N "http://localhost:${PORT}/vfs/a.txt" -H 'accept-encoding: deflate' --max-time 5 | base64 | sed 's+ykjNycnnKs8vyknhAgAAAP//AwA=+ykjNycnnKs8vyknhAgAAAP//+'
1922

2023
sleep 0.1
2124
curl -N "http://localhost:${PORT}/vfs/sub/yolo.html" --max-time 5

tests/unit/dune

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

22
(tests
3-
(names t_util t_buf t_server)
3+
(names t_util t_buf t_server t_io)
44
(package tiny_httpd)
55
(libraries tiny_httpd.core qcheck-core qcheck-core.runner test_util))

tests/unit/t_io.ml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
open Test_util
2+
open Tiny_httpd_core.IO
3+
4+
let spf = Printf.sprintf
5+
6+
(* one chunk *)
7+
let () =
8+
let io = Input.of_string "5\r\nhello\r\n0\r\n\r\nARGH" in
9+
let str =
10+
io
11+
|> Input.read_chunked ~bytes:(Bytes.create 4) ~fail:failwith
12+
|> Input.read_all_using ~buf:(Buf.create ())
13+
in
14+
assert_eq ~to_string:(spf "%S") "hello" str
15+
16+
(* two chunks *)
17+
let () =
18+
let io = Input.of_string "5\r\nhello\r\n6\r\n world\r\n0\r\n\r\nARGH" in
19+
let str =
20+
io
21+
|> Input.read_chunked ~bytes:(Bytes.create 4) ~fail:failwith
22+
|> Input.read_all_using ~buf:(Buf.create ())
23+
in
24+
assert_eq ~to_string:(spf "%S") "hello world" str;
25+
26+
let str_rest = io |> Input.read_all_using ~buf:(Buf.create ()) in
27+
assert_eq ~to_string:(spf "%S") "ARGH" str_rest;
28+
()
29+
30+
(* two chunks *)
31+
let () =
32+
let io = Input.of_string "10\r\n{\"poCheck\":true}\r\n0\r\n\r\n" in
33+
let str =
34+
io
35+
|> Input.read_chunked ~bytes:(Bytes.create 4) ~fail:failwith
36+
|> Input.read_all_using ~buf:(Buf.create ())
37+
in
38+
assert_eq ~to_string:(spf "%S") {|{"poCheck":true}|} str;
39+
40+
let str_rest = io |> Input.read_all_using ~buf:(Buf.create ()) in
41+
assert_eq ~to_string:(spf "%S") "" str_rest;
42+
()

0 commit comments

Comments
 (0)