Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lib/bandit/compression.ex
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ defmodule Bandit.Compression do

headers = maybe_add_vary_header(adapter, status, headers)

if status not in [204, 304] && not is_nil(adapter.content_encoding) &&
# 206 responses are excluded since compressing them would change the bytes relative to the
# content-range the response advertises against the identity representation, corrupting
# range reassembly at the client
if status not in [204, 206, 304] && not is_nil(adapter.content_encoding) &&
is_nil(response_content_encoding_header) &&
!response_has_strong_etag(headers) && !response_indicates_no_transform(headers) &&
!empty_body? do
Expand Down
21 changes: 21 additions & 0 deletions test/bandit/http1/protocol_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -1992,6 +1992,21 @@ defmodule HTTP1ProtocolTest do
assert response.body == String.duplicate("a", 10_000)
end

test "does no encoding for 206 responses", context do
response =
Req.get!(context.req,
url: "/send_206_response",
headers: [{"accept-encoding", "deflate"}]
)

# Assert that we did not try to compress the body, since doing so would
# invalidate the range the response advertises via content-range
assert response.status == 206
assert response.headers["content-length"] == ["10000"]
assert response.headers["content-encoding"] == nil
assert response.body == String.duplicate("a", 10_000)
end

test "does no encoding if a malformed etag starting with W but not W/ is present", context do
response =
Req.get!(context.req,
Expand Down Expand Up @@ -2216,6 +2231,12 @@ defmodule HTTP1ProtocolTest do
|> send_resp(200, String.duplicate("a", 10_000))
end

def send_206_response(conn) do
conn
|> put_resp_header("content-range", "bytes 0-9999/20000")
|> send_resp(206, String.duplicate("a", 10_000))
end

def send_weak_etag(conn) do
conn
|> put_resp_header("etag", "W/\"1234\"")
Expand Down
Loading