Skip to content

fileserver: precompressed sidecar's Content-Encoding and Content-Length end up on error responses #8204

Open

Description

@NitinKumar004

Issue Details

With precompressed enabled, if file_server has picked a sidecar (e.g. hello.txt.gz) and then returns an error, the error response still carries the sidecar's Content-Encoding and Content-Length. The body is empty, or is whatever handle_errors writes, so clients fail to read it.

Tested on master at 401582c.

The common case is any non-GET/HEAD request (scanners, misdirected webhooks, forms) with Accept-Encoding: gzip, which browsers and HTTP clients send by default:

{
      admin localhost:2999
      http_port 9080
      auto_https off
}
:9080 {
      root * ./site
      file_server {
              precompressed gzip
      }
}
:9081 {
      root * ./site
      file_server {
              precompressed gzip
      }
      handle_errors {
              respond "error {err.status_code}"
      }
}

Files: printf 'hello world\n' > site/hello.txt && gzip -k site/hello.txt (hello.txt.gz is 42 bytes).

$ curl -sS -i -X POST -H 'Accept-Encoding: gzip' http://localhost:9080/hello.txt
curl: (18) transfer closed with 42 bytes remaining to read
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD
Content-Encoding: gzip
Content-Length: 42
Server: Caddy
Vary: Accept-Encoding

$ curl -sS --compressed -X POST http://localhost:9081/hello.txt
curl: (61) Error while processing content unencoding: incorrect header check

Without Accept-Encoding the 405 is fine (Content-Length: 9, body error 405).

In FileServer.ServeHTTP the sidecar loop sets the two headers as soon as it opens the sidecar, and three error returns come after that. The error path doesn't clear headers, so all three are affected:

  1. the GET/HEAD check (405), shown above;
  2. reading the sidecar's etag file with etag_file_extensions, when the read fails with anything other than not-exist (500);
  3. the status override when it doesn't parse as a number, e.g. status {query.code} with ?code=abc (500 with Content-Encoding: gzip, Content-Length: 42, empty body).

Same kind of problem as #8147, but in fileserver.

I'd like to fix it by keeping the chosen encoding and size in local variables and setting the headers after the last error return, right before http.ServeContent. I have a patch and a test covering all three paths that fails on master and passes with the fix, and I can open a PR if that approach sounds right.

AI assistance was used for this report; I ran the repro myself and checked the output.

Assistance Disclosure

No response

If AI was used, describe the extent to which it was used.

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      Sponsor
      SponsoredKunjungi sekarang
      Promo