Fix the body framing decision in an HTTP client

Review the AI's codeEasy12 min

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". -1 means "read until the server closes the connection". -2 means "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-Length counts only when its value is one or more ASCII digits. If it appears more than once, the last valid one wins.
  • Transfer-Encoding: chunked makes the body chunked. Connection: close makes the body end when the connection closes.
  • Decide in this order:
    1. Chunked: return -2. This wins even when there is also a Content-Length.
    2. A valid Content-Length: return the length minus buffered, but never less than 0. Any surplus bytes are the start of the next response, not part of this body.
    3. Connection: close: return -1.
    4. None of these: return 0.

Examples

bytes_still_to_read(headers: list[str], buffered: int) -> int
Example 1
Inputbytes_still_to_read(["Content-Length: 120", "Content-Type: application/json"], 40)
Output80
Example 2
Inputbytes_still_to_read(["Transfer-Encoding: chunked"], 0)
Output-2
Example 3
Inputbytes_still_to_read(["Connection: close", "Server: nginx"], 100)
Output-1