Alla fine, ho usato la risposta di Wiktor Zychla, ma ho trovato un paio di bug (citato anche nei commenti del suo articolo). Per completezza, posterò la mia versione fissa del modulo HttpCompression qui, ma il resto del codice (e le linee guida di implementazione) di cui hai bisogno sono in Wiktor's article.
UPDATE:
realtà ho dovuto smettere di usare questo codice in quanto ha un bug non riesco a risolvere (anche con la mia versione migliorata di seguito). Per molte persone dietro i server proxy viene visualizzato un errore che dice "il numero magico nell'intestazione gzip non è corretto" e non riesco a capire come risolvere questo problema. Penso che sia perché i server proxy decomprimono GZIP e questo codice non consente di ricevere le risposte sia zippate che non compresse nella sua forma attuale.
using System;
using System.IO.Compression;
using System.Web;
using System.Web.Security;
/// <summary>
/// Implement two way HTTP compression for the SOAP API
/// Code taken from: http://netpl.blogspot.co.uk/2009/07/aspnet-webservices-two-way- response-and.html
/// Fix: Set Content-encoding: gzip header when an Exception occurs on the server.
/// Fix: Do not attempt to decrypt GZIP request stream when request was not GZIPed.
/// </summary>
public class HttpCompressionModule : IHttpModule
{
private bool isDisposed = false;
~HttpCompressionModule()
{
Dispose(false);
}
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(Context_BeginRequest);
context.PreSendRequestHeaders += new EventHandler(context_PreSendRequestHeaders);
}
void context_PreSendRequestHeaders(object sender, EventArgs e)
{
// Fix headers having been lost if an exception occurred.
HttpApplication app = sender as HttpApplication;
HttpContext ctx = app.Context;
if (app.Response.Filter is GZipStream) SetEncoding("gzip");
else if (app.Response.Filter is DeflateStream) SetEncoding("deflate");
// Fix double header
if (ctx.Response.Headers["Content-encoding"] == "gzip,gzip")
ctx.Response.Headers.Set("Content-encoding", "gzip");
}
public void Context_BeginRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
HttpContext ctx = app.Context;
// Currently only enable for the Uploader API webservice
if (!ctx.Request.Url.PathAndQuery.ToLower().Contains("uploaderapi.asmx"))
{
return;
}
// Add request filter if request was GZIP encoded
string requestEncoding = ctx.Request.Headers["Content-encoding"];
if (requestEncoding != null && requestEncoding == "gzip")
{
app.Request.Filter =
new System.IO.Compression.GZipStream(app.Request.Filter, CompressionMode.Decompress);
}
// Add response compression filter if the client accepts compressed responses
if (IsEncodingAccepted("gzip"))
{
app.Response.Filter = new GZipStream(app.Response.Filter, CompressionMode.Compress);
SetEncoding("gzip");
}
else if (IsEncodingAccepted("deflate"))
{
app.Response.Filter = new DeflateStream(app.Response.Filter, CompressionMode.Compress);
SetEncoding("deflate");
}
}
private bool IsEncodingAccepted(string encoding)
{
return HttpContext.Current.Request.Headers["Accept-encoding"] != null &&
HttpContext.Current.Request.Headers["Accept-encoding"].Contains(encoding);
}
private void SetEncoding(string encoding)
{
HttpContext ctx = HttpContext.Current;
string responseEncodings = ctx.Response.Headers.Get("Content-encoding");
if (responseEncodings == null || !responseEncodings.Contains(encoding))
HttpContext.Current.Response.AppendHeader("Content-encoding", encoding);
}
public void Dispose()
{
Dispose(true);
}
private void Dispose(bool dispose)
{
isDisposed = dispose;
}
}
Si prega di fare riferimento a questo SO messaggio (http://stackoverflow.com/questions/4416177/how-to-compress-http-requests-from-wcf-net-at-the-transport-level) – Rajesh