Skip to content

Add decompressRequest filter for handling compressed request body#4023

Draft
Abdelghafour01 wants to merge 1 commit into
zalando:masterfrom
Abdelghafour01:implement-decompress-request
Draft

Add decompressRequest filter for handling compressed request body#4023
Abdelghafour01 wants to merge 1 commit into
zalando:masterfrom
Abdelghafour01:implement-decompress-request

Conversation

@Abdelghafour01
Copy link
Copy Markdown

PR Description

Add decompressRequest filter

Adds a new filter decompressRequest() that decompresses the request body on the request path, mirroring the existing decompress() filter that operates on response bodies.

Motivation

Skipper currently supports decompressing response bodies via the decompress() filter, but there is no equivalent for request bodies. Backends that don't natively understand compressed request payloads (e.g. clients sending Content-Encoding: gzip on POST/PUT) can't be transparently fronted by Skipper today. This filter closes that gap.

Changes

  • New filter decompressrequest.go implementing decompressRequest().
    • Reads the request's Content-Encoding header and streams the body through the appropriate decoder.
    • Supported encodings: gzip, deflate, br, zstd (reuses newDecodedBody, getEncodings, encodingsSupported from the existing decompress filter — no duplication of decoder logic or pools).
    • On success: removes Content-Encoding and Content-Length headers and sets ContentLength = -1 so the request is sent to the backend as a streamed, decompressed body.
    • On unsupported encoding: leaves the request unmodified and sets filter::decompress::not-possible in the state bag.
    • On init failure: closes the body, replaces it with http.NoBody, sets both filter::decompress::not-possible and filter::decompress::error in the state bag, and logs the error. Same state-bag keys as decompress() for consistency.
  • Registered the new spec in builtin.go and added the DecompressRequestName constant in filters.go.
  • Tests in decompressrequest_test.go covering:
    • successful gzip decompression and header/ContentLength cleanup
    • request without Content-Encoding is passed through unchanged
    • unsupported encoding sets DecompressionNotPossible and preserves headers
    • invalid gzip payload sets both DecompressionNotPossible and DecompressionError
    • filter name
  • Documentation entry added under filters.md.

Note

  • The state-bag keys (DecompressionNotPossible, DecompressionError) are intentionally shared with decompress(); if you'd prefer request-specific keys to disambiguate, happy to split them.

…sing existing decoders (gzip, deflate, br, zstd)

Signed-off-by: Abdelghafour Mourchid <Abdelghafour01@users.noreply.github.com>
@Abdelghafour01 Abdelghafour01 force-pushed the implement-decompress-request branch from 505d9c1 to 18549ac Compare May 22, 2026 11:41
}
if got := ctx.Request().Header.Get("Content-Encoding"); got != "unsupported" {
t.Errorf("expected Content-Encoding to be preserved when unsupported, got: %q", got)
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please also check the body contains "x"?

}
}

func TestDecompressRequestInvalidPayload(t *testing.T) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we detect this we should respond by a 400, right?
If so I would say we should also test it.

@szuecs
Copy link
Copy Markdown
Member

szuecs commented May 23, 2026

@Abdelghafour01 thanks for the pr, looks great and there are only a bit of ideas what we can further improve by testing.
I didn't read any rfc regarding this but I would expect that there will be an rfc that tells what to do in case of header says gzip but body is plain. I am not sure if Go already detecting this case but if not please check and reference the rfc if you can find it.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants