-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
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.