Fix the body framing decision in an HTTP client
Your task
Your lightweight HTTP client read the response head, then took one more recv as the whole body. Bodies came back cut short or with the next response glued on. The fix decides from the headers how the body is framed, and how many more bytes to read.
An assistant wrote bytes_still_to_read(headers, buffered). It is in the editor. It has a bug. Find it and fix it.
Input and output:
headers: the response header lines, each"Name: value".buffered: how many body bytes already arrived together with the head.- Return a number: 0 or more means "read exactly this many more bytes".
-1means "read until the server closes the connection".-2means "the body is chunked, so de-chunk it instead of counting".
Rules the tests check:
- Skip a line with no
:. Otherwise split it at the first:, then trim the name and the value and compare both without regard to case. A value may itself contain:. Content-Lengthcounts only when its value is one or more ASCII digits. If it appears more than once, the last valid one wins.Transfer-Encoding: chunkedmakes the body chunked.Connection: closemakes the body end when the connection closes.- Decide in this order:
- Chunked: return
-2. This wins even when there is also aContent-Length. - A valid
Content-Length: return the length minusbuffered, but never less than 0. Any surplus bytes are the start of the next response, not part of this body. Connection: close: return-1.- None of these: return 0.
- Chunked: return
Examples
bytes_still_to_read(headers: list[str], buffered: int) -> intExample 1
Input
bytes_still_to_read(["Content-Length: 120", "Content-Type: application/json"], 40)Output
80Example 2
Input
bytes_still_to_read(["Transfer-Encoding: chunked"], 0)Output
-2Example 3
Input
bytes_still_to_read(["Connection: close", "Server: nginx"], 100)Output
-1