2 // System.Net.HttpWebResponse
5 // Lawrence Pit (loz@cable.a2000.nl)
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // Daniel Nauck (dna(at)mono-project(dot)de)
9 // (c) 2002 Lawrence Pit
10 // (c) 2003 Ximian, Inc. (http://www.ximian.com)
11 // (c) 2008 Daniel Nauck
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 using System.Collections;
37 using System.Globalization;
39 using System.IO.Compression;
40 using System.Net.Sockets;
41 using System.Runtime.Serialization;
47 public class HttpWebResponse : WebResponse, ISerializable, IDisposable {
49 WebHeaderCollection webHeaders;
50 CookieCollection cookieCollection;
53 HttpStatusCode statusCode;
54 string statusDescription;
57 CookieContainer cookie_container;
64 internal HttpWebResponse (Uri uri, string method, WebConnectionData data, CookieContainer container)
68 webHeaders = data.Headers;
69 version = data.Version;
70 statusCode = (HttpStatusCode) data.StatusCode;
71 statusDescription = data.StatusDescription;
76 string cl = webHeaders ["Content-Length"];
77 if (String.IsNullOrEmpty (cl) || !Int64.TryParse (cl, out contentLength))
83 if (container != null) {
84 this.cookie_container = container;
88 string content_encoding = webHeaders ["Content-Encoding"];
89 if (content_encoding == "gzip" && (data.request.AutomaticDecompression & DecompressionMethods.GZip) != 0)
90 stream = new GZipStream (stream, CompressionMode.Decompress);
91 else if (content_encoding == "deflate" && (data.request.AutomaticDecompression & DecompressionMethods.Deflate) != 0)
92 stream = new DeflateStream (stream, CompressionMode.Decompress);
95 [Obsolete ("Serialization is obsoleted for this type", false)]
96 protected HttpWebResponse (SerializationInfo serializationInfo, StreamingContext streamingContext)
98 SerializationInfo info = serializationInfo;
100 uri = (Uri) info.GetValue ("uri", typeof (Uri));
101 contentLength = info.GetInt64 ("contentLength");
102 contentType = info.GetString ("contentType");
103 method = info.GetString ("method");
104 statusDescription = info.GetString ("statusDescription");
105 cookieCollection = (CookieCollection) info.GetValue ("cookieCollection", typeof (CookieCollection));
106 version = (Version) info.GetValue ("version", typeof (Version));
107 statusCode = (HttpStatusCode) info.GetValue ("statusCode", typeof (HttpStatusCode));
112 public string CharacterSet {
113 // Content-Type = "Content-Type" ":" media-type
114 // media-type = type "/" subtype *( ";" parameter )
115 // parameter = attribute "=" value
116 // 3.7.1. default is ISO-8859-1
118 string contentType = ContentType;
119 if (contentType == null)
121 string val = contentType.ToLower ();
122 int pos = val.IndexOf ("charset=", StringComparison.Ordinal);
126 int pos2 = val.IndexOf (';', pos);
128 ? contentType.Substring (pos)
129 : contentType.Substring (pos, pos2 - pos);
133 public string ContentEncoding {
136 string h = webHeaders ["Content-Encoding"];
137 return h != null ? h : "";
141 public override long ContentLength {
143 return contentLength;
147 public override string ContentType {
151 if (contentType == null)
152 contentType = webHeaders ["Content-Type"];
161 public CookieCollection Cookies {
164 if (cookieCollection == null)
165 cookieCollection = new CookieCollection ();
166 return cookieCollection;
170 cookieCollection = value;
174 public override WebHeaderCollection Headers {
180 static Exception GetMustImplement ()
182 return new NotImplementedException ();
186 public override bool IsMutuallyAuthenticated
189 throw GetMustImplement ();
193 public DateTime LastModified {
197 string dtStr = webHeaders ["Last-Modified"];
198 return MonoHttpDate.Parse (dtStr);
199 } catch (Exception) {
208 public string Method {
215 public Version ProtocolVersion {
222 public override Uri ResponseUri {
229 public string Server {
232 return webHeaders ["Server"];
239 public HttpStatusCode StatusCode {
248 public string StatusDescription {
251 return statusDescription;
257 public string GetResponseHeader (string headerName)
260 string value = webHeaders [headerName];
261 return (value != null) ? value : "";
264 internal void ReadAll ()
266 WebConnectionStream wce = stream as WebConnectionStream;
275 public override Stream GetResponseStream ()
280 if (string.Equals (method, "HEAD", StringComparison.OrdinalIgnoreCase)) // see par 4.3 & 9.4
286 void ISerializable.GetObjectData (SerializationInfo serializationInfo,
287 StreamingContext streamingContext)
289 GetObjectData (serializationInfo, streamingContext);
292 protected override void GetObjectData (SerializationInfo serializationInfo,
293 StreamingContext streamingContext)
295 SerializationInfo info = serializationInfo;
297 info.AddValue ("uri", uri);
298 info.AddValue ("contentLength", contentLength);
299 info.AddValue ("contentType", contentType);
300 info.AddValue ("method", method);
301 info.AddValue ("statusDescription", statusDescription);
302 info.AddValue ("cookieCollection", cookieCollection);
303 info.AddValue ("version", version);
304 info.AddValue ("statusCode", statusCode);
309 public override void Close ()
311 if (stream != null) {
319 void IDisposable.Dispose ()
325 protected override void Dispose (bool disposing)
327 this.disposed = true;
331 void Dispose (bool disposing)
333 this.disposed = true;
339 private void CheckDisposed ()
342 throw new ObjectDisposedException (GetType ().FullName);
347 if (webHeaders == null)
351 // Don't terminate response reading on bad cookie value
355 value = webHeaders.Get ("Set-Cookie");
356 if (value != null && SetCookie (value))
362 value = webHeaders.Get ("Set-Cookie2");
369 bool SetCookie (string header)
371 if (cookieCollection == null)
372 cookieCollection = new CookieCollection ();
374 bool at_least_one_set = false;
375 var parser = new CookieParser (header);
376 foreach (var cookie in parser.Parse ()) {
377 if (cookie.Domain == "") {
378 cookie.Domain = uri.Host;
379 cookie.HasDomain = false;
382 if (cookie.HasDomain &&
383 !CookieContainer.CheckSameOrigin (uri, cookie.Domain))
386 cookieCollection.Add (cookie);
387 if (cookie_container != null) {
388 cookie_container.Add (uri, cookie);
389 at_least_one_set = true;
393 return at_least_one_set;