问题
For an ASP.NET 4.0 / IIS7 web app, I would like to support compressed HTTP requests. Basically, I would like to support clients that would add Content-Encoding: gzip
in the request headers, and compress the body accordingly.
Does anyone known how I achieve such a behavior?
Ps: concerning, I have multiple endpoints REST and SOAP, and it feels a better solution to support compression at the HTTP level rather than custom encoders for each endpoint.
回答1:
For those who might be interested, the implementation is rather straightforward with an IHttpModule
that simply filters incoming requests.
public class GZipDecompressModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += BeginRequest;
}
void BeginRequest(object sender, EventArgs e)
{
var app = (HttpApplication)sender;
if ("gzip" == app.Request.Headers["Content-Encoding"])
{
app.Request.Filter = new GZipStream(
app.Request.Filter, CompressionMode.Decompress);
}
}
public void Dispose()
{
}
}
Update: It appears that this approach trigger a problem in WCF, as WCF relies on the original Content-Length
and not the value obtained after decompressing.
回答2:
Try Wiktor's answer to my similar question here:
How do I enable GZIP compression for POST (upload) requests to a SOAP WebService on IIS 7?
...but please note his implementation on his blog contained a couple of bugs / compatibility issues, so please try my patched version of the HttpCompressionModule class posted on the same page.
回答3:
Although hacky, you can get around WCF using the original Content-Length
even after the request has been decompressed by setting the private _contentLength
field in the HttpRequest
class using reflection. Using Joannes Vermorel's code:
void BeginRequest(object sender, EventArgs e)
{
var app = (HttpApplication)sender;
if ("gzip" == app.Request.Headers["Content-Encoding"])
{
app.Request.Filter = new GZipStream(
app.Request.Filter, CompressionMode.Decompress);
// set private _contentLength field with new content length after the request has been decompressed
var contentLengthProperty = typeof(HttpRequest).GetField("_contentLength", BindingFlags.NonPublic | BindingFlags.Instance);
contentLengthProperty.SetValue(app.Request, (Int32)app.Request.InputStream.Length);
}
}
来源:https://stackoverflow.com/questions/4410968/how-to-support-compressed-http-requests-in-asp-net-4-0-iis7