.NET:是否可以让 HttpWebRequest 自动解压缩 gzip 响应?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2815721/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 14:17:08  来源:igfitidea点击:

.NET: Is it possible to get HttpWebRequest to automatically decompress gzip'd responses?

.nethttpwebrequestgzip

提问by Cheeso

In this answer, I described how I resorted to wrappnig a GZipStream around the response stream in a HttpWebResponse, in order to decompress it.

这个答案中,我描述了我如何在 HttpWebResponse 中的响应流周围使用 GZipStream 来对其进行解压缩。

The relevant code looks like this:

相关代码如下所示:

HttpWebRequest hwr = (HttpWebRequest) WebRequest.Create(url);
hwr.CookieContainer =
    PersistentCookies.GetCookieContainerForUrl(url);
hwr.Accept = "text/xml, */*";
hwr.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate");
hwr.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-us");
hwr.UserAgent = "My special app";
hwr.KeepAlive = true;

using (var resp = (HttpWebResponse) hwr.GetResponse()) 
{
    using(Stream s = resp.GetResponseStream())
    {
        Stream s2 = s;
        if (resp.ContentEncoding.ToLower().Contains("gzip"))
            s2 = new GZipStream(s2, CompressionMode.Decompress);
        else if (resp.ContentEncoding.ToLower().Contains("deflate"))
            s2 = new DeflateStream(s2, CompressionMode.Decompress);

         ... use s2 ...
    }
}

Is there a way to get HttpWebResponse to provide a de-compressing stream, automatically? In other words, a way for me to eliminate the following from the above code:

有没有办法让 HttpWebResponse 自动提供解压缩流?换句话说,我可以从上面的代码中消除以下内容:

      Stream s2 = s;
      if (resp.ContentEncoding.ToLower().Contains("gzip"))
          s2 = new GZipStream(s2, CompressionMode.Decompress);
      else if (resp.ContentEncoding.ToLower().Contains("deflate"))
          s2 = new DeflateStream(s2, CompressionMode.Decompress);

Thanks.

谢谢。

回答by Bradley Grainger

Use the HttpWebRequest.AutomaticDecompressionproperty as follows:

使用HttpWebRequest.AutomaticDecompression属性如下:

HttpWebRequest hwr = (HttpWebRequest) WebRequest.Create(url);
hwr.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;

It's not necessary to manually add the Accept-EncodingHTTP header; it will automatically be added when that property is used.

不需要手动添加Accept-EncodingHTTP 头;使用该属性时,它将自动添加。

(Also, I know this is just example code, but the HttpWebResponseobject should be placed in a usingblock so it's disposed correctly when you've finished using it.)

(另外,我知道这只是示例代码,但该HttpWebResponse对象应该放在一个using块中,以便在您完成使用后正确处理它。)

回答by snoopy-do

My expreience is that it already does it automatically. I had to explicitly disable it by setting the AutomaticDecompressionproperty of the Request object to DecompressionMethods.None

我的经验是它已经自动完成了。我必须通过将Request 对象的AutomaticDecompression属性设置为 DecompressionMethods.None来明确禁用它

回答by pixel

I dont think AutomaticDecompression adds to Header AcceptDecoding=gzip,deflate. Below is example of my request and response when I added just AutomaticDecompression (without adding explicityly AcceptEncoding header). As you can see, there is no AcceptEncoding in Header at all

我认为 AutomaticDecompression 不会添加到 Header AcceptDecoding=gzip,deflate 中。以下是我仅添加 AutomaticDecompression(未显式添加 AcceptEncoding 标头)时的请求和响应示例。如您所见,Header 中根本没有 AcceptEncoding

//REQUEST 
//===============================================================
-       req {System.Net.HttpWebRequest} System.Net.HttpWebRequest
+       base    {System.Net.HttpWebRequest} System.Net.WebRequest {System.Net.HttpWebRequest}
        _AuthInfo   null    System.Net.ICredentials
        _ContentLength  -1  long
+       _HttpRequestHeaders {User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS .NET CF Web Services Client Protocol 3.5.7283.0)
Authorization: Basic RElOT0I6MTExMQ==

}   System.Net.WebHeaderCollection
        _MaximumAllowedRedirections 50  int
        _MediaType  null    string
+       _OriginUri  {http://192.168.0.106:8084/MyTestApp/Soap/IMyApp}   System.Uri
        _OriginVerb "GET"   string
+       _Proxy  {System.Net.GlobalProxySelection.SystemWebProxy}    System.Net.IWebProxy {System.Net.GlobalProxySelection.SystemWebProxy}
        _ProxyAuthenticationState   null    System.Net.AuthenticationState
        _ReadWriteTimeout   300000  int
        _ServerAuthenticationState  null    System.Net.AuthenticationState
        _Timeout    100000  int
+       _Timer  {System.Threading.Timer}    System.Threading.Timer
+       _Uri    {http://192.168.0.106:8084/MyTestApp/Soap/IMyApp}   System.Uri
        Aborted false   bool
        Accept  Could not evaluate expression   string
+       Address {http://192.168.0.106:8084/MyTestApp/Soap/IMyApp}   System.Uri
        AllowAutoRedirect   false   bool
        AllowWriteStreamBuffering   true    bool
        AutomaticDecompression  GZip | Deflate  System.Net.DecompressionMethods
        ChallengedUri   Could not evaluate expression   System.Uri
+       ClientCertificates  {System.Security.Cryptography.X509Certificates.X509CertificateCollection}   System.Security.Cryptography.X509Certificates.X509CertificateCollection
        ConnectHostAndPort  "192.168.0.106:8084"    string
        Connection  Could not evaluate expression   string
        ConnectionGroupName Could not evaluate expression   string
        ContentLength   -1  long
        ContentType Could not evaluate expression   string
        ContinueDelegate    Could not evaluate expression   System.Net.HttpContinueDelegate
        Credentials Could not evaluate expression   System.Net.ICredentials
+       CurrentAuthenticationState  {System.Net.AuthenticationState}    System.Net.AuthenticationState
        Expect  Could not evaluate expression   string
        hasEntityData   false   bool
        HaveResponse    false   bool
+       Headers {User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS .NET CF Web Services Client Protocol 3.5.7283.0)
Authorization: Basic RElOT0I6MTExMQ==

}   System.Net.WebHeaderCollection
+       IfModifiedSince {9/7/15 5:47:12 AM} System.DateTime
        KeepAlive   true    bool
        m_Aborted   false   bool
        m_allowAutoRedirection  false   bool
        m_allowWriteStreamBuffering true    bool
        m_AutomaticDecompression    GZip | Deflate  System.Net.DecompressionMethods
        m_boundConnection   null    System.Net.Connection
+       m_clientCertificates    {System.Security.Cryptography.X509Certificates.X509CertificateCollection}   System.Security.Cryptography.X509Certificates.X509CertificateCollection
        m_connection    null    System.Net.Connection
        m_ConnectionClosedStopSendingEntityData false   bool
        m_connectionGroupName   null    string
        m_connectionUsers   0   int
        m_connMgrConnection -1  int
        m_continueDelegate  null    System.Net.HttpContinueDelegate
+       m_continueFunction  {System.Threading.TimerCallback}    System.Threading.TimerCallback
+       m_continueTimer null    System.Threading.Timer
        m_doneSendingEvent  null    System.Threading.ManualResetEvent
        m_errorResponse null    System.Net.WebException
        m_expectContinue    false   bool
        m_finishedWriting   false   bool
        m_httpWriteMode None    System.Net.HttpWriteMode
        m_IsCurrentAuthenticationStateProxy false   bool
        m_isSubmitting  false   bool
        m_KeepAlive true    bool
        m_numberRedirections    0   int
        m_Pipelined true    bool
        m_PreAuthenticate   false   bool
+       m_readWriteTimer    {System.Threading.Timer}    System.Threading.Timer
        m_requestGeneration 0   int
+       m_requestSentEvent  {System.Threading.ManualResetEvent} System.Threading.ManualResetEvent
+       m_requestStream null    System.Net.HttpWriteStream
        m_requestStreamRetrieved    false   bool
        m_RequestSubmitted  false   bool
        m_response  null    System.Net.HttpWebResponse
        m_responseComplete  false   bool
+       m_responseEvent {System.Threading.ManualResetEvent} System.Threading.ManualResetEvent
        m_responseRetrieved false   bool
        m_sentHeaders   false   bool
+       m_setProxy  {System.Net.GlobalProxySelection.SystemWebProxy}    System.Net.IWebProxy {System.Net.GlobalProxySelection.SystemWebProxy}
+       m_srvPoint  null    System.Net.ServicePoint
        m_startedReceiving  false   bool
        m_timedOut  0   int
+       m_version   {1.1}   System.Version
        MaximumAutomaticRedirections    50  int
        MediaType   Could not evaluate expression   string
        Method  "GET"   string
        NtlmKeepAlive   false   bool
        Pipelined   true    bool
        PreAuthenticate false   bool
+       ProtocolVersion {1.1}   System.Version
+       Proxy   {System.Net.GlobalProxySelection.SystemWebProxy}    System.Net.IWebProxy {System.Net.GlobalProxySelection.SystemWebProxy}
        ProxyAuthenticatedConnectionSharing false   bool
+       ProxyAuthenticationState    {System.Net.AuthenticationState}    System.Net.AuthenticationState
        ReadWriteTimeout    300000  int
        Referer Could not evaluate expression   string
+       RequestUri  {http://192.168.0.106:8084/MyTestApp/Soap/IMyApp}   System.Uri
+       ResponseStatusCode  'req.ResponseStatusCode' threw an exception of type 'System.NullReferenceException' System.Net.HttpStatusCode {System.NullReferenceException}
        SendChunked false   bool
+       ServerAuthenticationState   {System.Net.AuthenticationState}    System.Net.AuthenticationState
        ServicePoint    Could not evaluate expression   System.Net.ServicePoint
        SyncObject  {object}    object
        Timeout 100000  int
        TransferEncoding    Could not evaluate expression   string
        UserAgent   "Mozilla/4.0 (compatible; MSIE 6.0; MS .NET CF Web Services Client Protocol 3.5.7283.0)"    string
+       UsesProxySemantics  'req.UsesProxySemantics' threw an exception of type 'System.NullReferenceException' bool {System.NullReferenceException}
+       Static members  


//RESPONSE 
=====================================================
-       res {System.Net.HttpWebResponse}    System.Net.HttpWebResponse
+       base    {System.Net.HttpWebResponse}    System.Net.WebResponse {System.Net.HttpWebResponse}
        CharacterSet    ""  string
        ContentEncoding ""  string
        ContentLength   -1  long
        ContentType "text/xml"  string
-       Headers {Date: Mon, 07 Sep 2015 11:49:36 GMT
Server: Apache/2.2.29 (Win32)
Vary: Accept-Encoding,User-Agent
Content-Encoding: 
Content-Length: 1481
Keep-Alive: timeout=60, max=100
Connection: Keep-Alive
Content-Type: text/xml

}   System.Net.WebHeaderCollection
+       base    {Date: Mon, 07 Sep 2015 11:49:36 GMT
Server: Apache/2.2.29 (Win32)
Vary: Accept-Encoding,User-Agent
Content-Encoding: 
Content-Length: 1481
Keep-Alive: timeout=60, max=100
Connection: Keep-Alive
Content-Type: text/xml

}   System.Collections.Specialized.NameValueCollection {System.Net.WebHeaderCollection}
        m_IsHttpWebHeaderObject true    bool
+       Static members      
+       LastModified    {9/7/15 5:49:45 AM} System.DateTime
        m_contentLength -1  long
        m_decompressionMethod   GZip | Deflate  System.Net.DecompressionMethods
-       m_httpResponseHeaders   {Date: Mon, 07 Sep 2015 11:49:36 GMT
Server: Apache/2.2.29 (Win32)
Vary: Accept-Encoding,User-Agent
Content-Encoding: 
Content-Length: 1481
Keep-Alive: timeout=60, max=100
Connection: Keep-Alive
Content-Type: text/xml

}   System.Net.WebHeaderCollection
-       base    {Date: Mon, 07 Sep 2015 11:49:36 GMT
Server: Apache/2.2.29 (Win32)
Vary: Accept-Encoding,User-Agent
Content-Encoding: 
Content-Length: 1481
Keep-Alive: timeout=60, max=100
Connection: Keep-Alive
Content-Type: text/xml

}   System.Collections.Specialized.NameValueCollection {System.Net.WebHeaderCollection}
+       base    {Date: Mon, 07 Sep 2015 11:49:36 GMT
Server: Apache/2.2.29 (Win32)
Vary: Accept-Encoding,User-Agent
Content-Encoding: 
Content-Length: 1481
Keep-Alive: timeout=60, max=100
Connection: Keep-Alive
Content-Type: text/xml

}   System.Collections.Specialized.NameObjectCollectionBase {System.Net.WebHeaderCollection}
        _allKeys    null    string[]
+       AllKeys {string[8]} string[]
        m_IsHttpWebHeaderObject true    bool
+       Static members      
        m_mediaType null    string
        m_method    "POST"  string
-       m_responseStream    {System.Net.GZipWrapperStream}  System.IO.Stream {System.Net.GZipWrapperStream}
+       [System.Net.GZipWrapperStream]  {System.Net.GZipWrapperStream}  System.Net.GZipWrapperStream
        base    {System.Net.GZipWrapperStream}  System.MarshalByRefObject {System.Net.GZipWrapperStream}
        _closeRecursionCounter  0   int
        CanRead true    bool
        CanSeek false   bool
        CanTimeout  false   bool
        CanWrite    false   bool
+       Length  'res.m_responseStream.Length' threw an exception of type 'System.NotSupportedException' long {System.NotSupportedException}
+       Position    'res.m_responseStream.Position' threw an exception of type 'System.NotSupportedException'   long {System.NotSupportedException}
+       ReadTimeout 'res.m_responseStream.ReadTimeout' threw an exception of type 'System.InvalidOperationException'    int {System.InvalidOperationException}
+       WriteTimeout    'res.m_responseStream.WriteTimeout' threw an exception of type 'System.InvalidOperationException'   int {System.InvalidOperationException}
+       Static members      
        m_statusCode    200 int
        m_statusDescription "OK"    string
+       m_url   {http://192.168.0.106:8084/MyTestApp/Soap/IMyApp}   System.Uri
+       m_version   {1.1}   System.Version
        Method  "POST"  string
-       ProtocolVersion {1.1}   System.Version
        _Build  -1  int
        _Major  1   int
        _Minor  1   int
        _Revision   -1  int
        Build   -1  int
        Major   1   int
        Minor   1   int
        Revision    -1  int
-       ResponseUri {http://192.168.0.106:8084/MyTestApp/Soap/IMyApp}   System.Uri
        AbsolutePath    "/MyTestApp/Soap/IMyApp"    string
        AbsoluteUri "http://192.168.0.106:8084/MyTestApp/Soap/IMyApp"   string
        Authority   "192.168.0.106:8084"    string
        DnsSafeHost "192.168.0.106" string
        Fragment    ""  string
        HasAuthority    true    bool
        Host    "192.168.0.106" string
        HostNameType    IPv4    System.UriHostNameType
        HostType    IPv4HostType    System.Uri.Flags
        IsAbsoluteUri   true    bool
        IsDefaultPort   false   bool
        IsDosPath   false   bool
        IsFile  false   bool
        IsImplicitFile  false   bool
        IsLoopback  false   bool
        IsNotAbsoluteUri    false   bool
        IsUnc   false   bool
        IsUncOrDosPath  false   bool
        IsUncPath   false   bool
        LocalPath   "/MyTestApp/Soap/IMyApp"    string
        m_Flags IPv4HostType | AuthorityFound | NotDefaultPort | MinimalUriInfoSet | AllUriInfoSet  System.Uri.Flags
+       m_Info  {System.Uri.UriInfo}    System.Uri.UriInfo
        m_OrigFileString    null    string
        m_String    "http://192.168.0.106:8084/MyTestApp/Soap/IMyApp"   string
+       m_Syntax    {System.UriParser.BuiltInUriParser} System.UriParser {System.UriParser.BuiltInUriParser}
        OriginalString  "http://192.168.0.106:8084/MyTestApp/Soap/IMyApp"   string
        PathAndQuery    "/MyTestApp/Soap/IMyApp"    string
        Port    8084    int
        PrivateAbsolutePath "/MyTestApp/Soap/IMyApp"    string
        Query   ""  string
        Scheme  "http"  string
        SecuredPathIndex    0   ushort
+       Segments    {string[4]} string[]
+       Syntax  {System.UriParser.BuiltInUriParser} System.UriParser {System.UriParser.BuiltInUriParser}
        UserDrivenParsing   false   bool
        UserEscaped false   bool
        UserInfo    ""  string
+       Static members      
        Server  "Apache/2.2.29 (Win32)" string
        StatusCode  OK  System.Net.HttpStatusCode
        StatusDescription   "OK"    string