I have Nginx reverse proxying my service that works by OData protocol. I'm trying to enable compression for theese requests by putting
#...
gzip on;
gzip_types application/json;
#...
server {
#...
location /odata/ {
proxy_pass http://localhost:7700/odata/;
}
#...
}
in nginx.conf.
Sometimes my service returns
Content-Type: application/json; charset=utf-8; odata.metadata=minimal
and Nginx compresses it.
But sometimes my service returns
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
and Nginx doesn't compress such responses.
What should I do to enable Nginx compressing such responses?
Solved this problem by writing middleware in my application, that changes Content-Type header and transforms it to application/json; charset=utf-8; odata.metadata=minimal; odata.streaming=true;
After that Nginx could recognize it as json content type and compresses it.
Let me add my solution for ASP.NET Core.
Note though that these responses are chunked so Nginx parameter gzip_min_length will not work and small responses will become gzipped as well increasing the size and reducing performance.
/// <summary>
/// Middleware to reorder Content-Type parts for Nginx compression.
/// </summary>
public class FixODataMiddlewareForNginx
{
readonly RequestDelegate _next;
public FixODataMiddlewareForNginx(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
context.Response.OnStarting(() =>
{
var contentType = context.Response.GetTypedHeaders().ContentType;
if (contentType != null &&
contentType.Parameters.Count > 0 &&
!contentType.Charset.HasValue)
{
contentType.Parameters.Insert(0, new NameValueHeaderValue("charset", "utf-8"));
context.Response.Headers["Content-Type"] = contentType.ToString();
}
return Task.CompletedTask;
});
await _next.Invoke(context);
}
}