8

ASP.NET 4.0 / IIS7 Web アプリの場合、圧縮された HTTP要求をサポートしたいと考えています。Content-Encoding: gzip基本的には、リクエスト ヘッダーを追加し、それに応じて本文を圧縮するクライアントをサポートしたいと考えています。

私がそのような行動を達成する方法を知っている人はいますか?

Ps: 私は複数のエンドポイント REST と SOAP を持っており、エンドポイントごとにカスタム エンコーダーを使用するよりも、HTTP レベルで圧縮をサポートする方が優れたソリューションだと感じています。

4

3 に答える 3

5

IHttpModule興味のある方のために説明すると、受信リクエストを単純にフィルタリングする を使用した実装はかなり簡単です。

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()
    {
    }
}

更新:Content-Length WCF は解凍後に取得された値ではなく元の値に依存しているため、このアプローチは WCF で問題を引き起こすようです。

于 2010-12-11T09:44:52.983 に答える
0

ハックですが、リフレクションを使用してクラスにプライベートフィールドをContent-Length設定することで、リクエストが解凍された後でも、オリジナルを使用して WCF を回避できます。Joannes Vermorel のコードを使用する:_contentLengthHttpRequest

    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);
        }
    }
于 2019-06-16T20:04:16.457 に答える