Skip to content

Commit

Permalink
Fix bug related to requests in the same buffer (inhabitedtype#91)
Browse files Browse the repository at this point in the history
When the remainder of one request body is the start of the buffer where
the subsequent request is stored, the first request needs to be taken
out of the request queue, otherwise the server could hang forever.
  • Loading branch information
anmonteiro authored Apr 9, 2021
1 parent 41ac60c commit dfcd7f1
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
9 changes: 7 additions & 2 deletions lib/server_connection.ml
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,15 @@ and _final_read_operation_for t reqd =
* non-empty `request_queue` has had the request handler called on its
* head element. *)
match Reader.next t.reader with
| `Error _ | `Read as operation ->
| `Error _ as op ->
(* Keep reading when in a "partial" state (`Read).
* Don't advance the request queue if in an error state. *)
operation
op
| `Read as op ->
(* we just don't advance the request queue in the case of a parser
error. *)
advance_request_queue t;
op
| _ ->
advance_request_queue t;
_next_read_operation t
Expand Down
17 changes: 17 additions & 0 deletions lib_test/test_server_connection.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1809,6 +1809,22 @@ let test_response_finished_before_body_read () =
write_response t response ~body:"done";
;;

let test_pipelined_requests_answer_before_reading_body () =
let response = Response.create `OK ~headers:(Headers.encoding_fixed 0) in
let request_handler reqd =
let response =
Response.create ~headers:(Headers.of_list ["content-length", "0"]) `OK
in
Reqd.respond_with_string reqd response ""
in
let t = create request_handler in
read_request t (Request.create `GET "/" ~headers:(Headers.encoding_fixed 5));
write_response t response;
(* Finish the request and send another *)
read_string t "helloGET / HTTP/1.1\r\nhost: localhost\r\ncontent-length: 5\r\n\r\n";
write_response t response;
;;

let tests =
[ "initial reader state" , `Quick, test_initial_reader_state
; "shutdown reader closed", `Quick, test_reader_is_closed_after_eof
Expand Down Expand Up @@ -1869,4 +1885,5 @@ let tests =
; "multiple requests with connection close", `Quick, test_multiple_requests_in_single_read_with_close
; "parse failure after checkpoint", `Quick, test_parse_failure_after_checkpoint
; "response finished before body read", `Quick, test_response_finished_before_body_read
; "pipelined", `Quick, test_pipelined_requests_answer_before_reading_body
]

0 comments on commit dfcd7f1

Please sign in to comment.