Skip to content

Gzip middleware re-compresses proxied responses #2788

@cbarry0720

Description

@cbarry0720

When using the Proxy middleware to forward requests to a backend service that already performs Gzip compression, the Gzip middleware in Echo attempts to compress the response body a second time. This can lead to corrupted responses or unnecessary processing.

The core of the issue is that the Gzip middleware does not check if the response has already been compressed by an upstream service before attempting to apply its own compression.Describe the solution you'd likeThe Gzip middleware should inspect the Content-Encoding header of the response coming from the proxy target. If the header is already set to gzip, the middleware should simply pass the response through without attempting to compress it again.This would make the Gzip middleware idempotent and allow it to work seamlessly in a reverse proxy setup where the origin server might also be compressing content.

The alternative is to disable Gzip compression on the backend service, but this is not always possible or desirable, especially if the service is also accessed directly. Another alternative is to fork the middleware and add this check, but it would be more beneficial for all users if it were part of the official middleware.

Here's a conceptual example of the middleware setup:

e := echo.New()

// This Gzip middleware will try to re-compress the already compressed response
e.Use(middleware.Gzip(middleware.GzipConfig{
    Level: 5,
}))

// Proxy to a backend that already gzips
e.Use(middleware.Proxy(middleware.NewRoundRobinBalancer([]*middleware.ProxyTarget{
    {
        URL: // -> a service that returns gzipped responses
    },
})))

A check within the gzipResponseWriter of the Gzip middleware before compression, something like this, would resolve the issue:

if res.Header().Get(echo.HeaderContentEncoding) == "gzip" {
    return next(c)
}

This would ensure that Echo's Gzip middleware doesn't interfere with responses that are already compressed.

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