2010-05-12 3 views
26

Dans this answer, j'ai décrit comment j'ai eu recours à wrappnig un GZipStream autour du flux de réponse dans un HttpWebResponse, afin de le décompresser..NET: Est-il possible de demander à HttpWebRequest de décompresser automatiquement les réponses gzip?

Le code correspondant ressemble à ceci:

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 ... 
    } 
} 

Y at-il un moyen d'obtenir HttpWebResponse pour fournir un flux de-compression, automatiquement? En d'autres termes, un moyen pour moi d'éliminer ce qui suit du code ci-dessus:

 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); 

Merci.

Répondre

55

Utilisez la propriété HttpWebRequest.AutomaticDecompression comme suit:

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

Il est pas nécessaire d'ajouter manuellement le Accept-Encoding HTTP entête; il sera automatiquement ajouté lorsque cette propriété est utilisée.

(Aussi, je sais que cela est juste un exemple de code, mais l'objet HttpWebResponse doit être placé dans un bloc using il est donc disposé à correctement lorsque vous avez fini de l'utiliser.)

+0

Cha-ching! Merci. Comment ça m'a manqué? – Cheeso

+0

merci, j'ai corrigé ma question, aussi, d'employer une clause using. – Cheeso

+5

"Il n'est pas nécessaire d'ajouter manuellement l'en-tête HTTP Accept-Encoding" - En outre, si vous le faites, les valeurs "gzip" et "deflate" seront dupliquées dans l'en-tête ce qui peut entraîner le rejet de la requête. – Chad

0

Mon expérience est qu'elle le fait déjà automatiquement. Je devais le désactiver en explicitement le réglage de la AutomaticDecompression propriété de l'objet Demande de DecompressionMethods.None

+1

Hmm, c'est étrange. Je dois refaire mes tests. Je pensais avoir vu des données compressées arriver. J'ai peut-être tort. merci. – Cheeso

+1

Juste testé - dans mon code, il n'était pas automatiquement activé. Je vais devoir lire le doc pour le découvrir, mais. . . quand je l'ai activé explicitement, cela m'a évité de devoir faire le flux de décompression. merci pour la réponse. – Cheeso

+0

J'ai eu du mal à trouver un site qui compresserait mes données comme demandé - http://www.google.com ne le ferait pas. - Sur une réflexion j'ai mis dans l'URL pour cette question exacte de StackOverflow, et cela a fonctionné - quand je le laisse réglé à DecompressionMethods.None (la valeur par défaut apparente dans .NET 4.5.1), je reçois des gzipped bytes dos. Agréable. – BrainSlugs83

-1

Je ne pense pas que AutomaticDecompression ajoute à l'en-tête AcceptDecoding = gzip, dégonfle. Ci-dessous est un exemple de ma demande et réponse lorsque j'ai ajouté juste AutomaticDecompression (sans ajouter explicitement AcceptEncoding en-tête). Comme vous pouvez le voir, il n'y a aucun AcceptEncoding dans l'en-tête du tout

//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 
+0

Il semble que ce soit le cas - voir ici: http://referencesource.microsoft.com/#System/net/System/Net/HttpWebRequest.cs,4985 – AndersMad

+0

@AndersMad Oui, je l'ai fait, je peux voir votre lien montrant que AcceptEncoding est ajouté mais je ne vois pas cela quand je regarde mon en-tête comme indiqué ci-dessus – pixel

Questions connexes