mtrudel/bandit

Content-Length header gets overridden

Closed this issue · 3 comments

Is there a good reason for why content-length header gets overridden/removed?

headers = Bandit.Headers.add_content_length(headers, IO.iodata_length(body), status)

headers = Enum.reject(headers, &(elem(&1, 0) == "content-length"))

I'm mocking AWS streaming response where there first request is a HEAD request to get the content-length. There should be no body for HEAD request but the content-length should be whatever it was set to. There could be a conditional to check the method, but I'm not sure Bandit should modify the content-length at all if it has already been set?

Oh I get it now. The body is not returned for HEAD request as expected. I assume the body is necessary to set to calculate the right length depending on the compression?

Ok, I figured out the issue I had. Bandit does need the body to calculate length, can't just set it, makes sense. Also my HTTP client was accepting gzip, Bandit responded accordingly when I was simulating streaming from S3. Setting http_options: [compress: false]] makes this work like AWS. All good, got confused how this was supposed to function 😄

I actually have a few things on the backlog to refine this behaviour (mostly stemming from this issue).

  • If a content-length header is set when a user called send_chunked/2, just send a non transfer-encoded response body out as bare bytes as the user calls chunk/2 (this is already what we do for HTTP/2, which doesn't do transfer-encoding)
  • I have to verify that we're doing the right thing with sending a content-length header for HEAD/304 (where we MAY send it) and 204 (where we MUST NOT send it)