Update mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng/RelaxngPattern.cs
[mono.git] / mcs / class / System / System.Net / HttpWebResponse.cs
1 //
2 // System.Net.HttpWebResponse
3 //
4 // Authors:
5 //      Lawrence Pit (loz@cable.a2000.nl)
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //      Daniel Nauck    (dna(at)mono-project(dot)de)
8 //
9 // (c) 2002 Lawrence Pit
10 // (c) 2003 Ximian, Inc. (http://www.ximian.com)
11 // (c) 2008 Daniel Nauck
12 //
13
14 //
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:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
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.
33 //
34
35 using System;
36 using System.Collections;
37 using System.Globalization;
38 using System.IO;
39 using System.IO.Compression;
40 using System.Net.Sockets;
41 using System.Runtime.Serialization;
42 using System.Text;
43
44 namespace System.Net 
45 {
46 #if MOONLIGHT
47         internal class HttpWebResponse : WebResponse, ISerializable, IDisposable {
48 #else
49         [Serializable]
50         public class HttpWebResponse : WebResponse, ISerializable, IDisposable {
51 #endif
52                 Uri uri;
53                 WebHeaderCollection webHeaders;
54                 CookieCollection cookieCollection;
55                 string method;
56                 Version version;
57                 HttpStatusCode statusCode;
58                 string statusDescription;
59                 long contentLength;
60                 string contentType;
61                 CookieContainer cookie_container;
62
63                 bool disposed;
64                 Stream stream;
65                 
66                 // Constructors
67                 
68                 internal HttpWebResponse (Uri uri, string method, WebConnectionData data, CookieContainer container)
69                 {
70                         this.uri = uri;
71                         this.method = method;
72                         webHeaders = data.Headers;
73                         version = data.Version;
74                         statusCode = (HttpStatusCode) data.StatusCode;
75                         statusDescription = data.StatusDescription;
76                         stream = data.stream;
77                         contentLength = -1;
78
79                         try {
80                                 string cl = webHeaders ["Content-Length"];
81                                 if (String.IsNullOrEmpty (cl) || !Int64.TryParse (cl, out contentLength))
82                                         contentLength = -1;
83                         } catch (Exception) {
84                                 contentLength = -1;
85                         }
86
87                         if (container != null) {
88                                 this.cookie_container = container;      
89                                 FillCookies ();
90                         }
91
92                         string content_encoding = webHeaders ["Content-Encoding"];
93                         if (content_encoding == "gzip" && (data.request.AutomaticDecompression & DecompressionMethods.GZip) != 0)
94                                 stream = new GZipStream (stream, CompressionMode.Decompress);
95                         else if (content_encoding == "deflate" && (data.request.AutomaticDecompression & DecompressionMethods.Deflate) != 0)
96                                 stream = new DeflateStream (stream, CompressionMode.Decompress);
97                 }
98
99                 [Obsolete ("Serialization is obsoleted for this type", false)]
100                 protected HttpWebResponse (SerializationInfo serializationInfo, StreamingContext streamingContext)
101                 {
102                         SerializationInfo info = serializationInfo;
103
104                         uri = (Uri) info.GetValue ("uri", typeof (Uri));
105                         contentLength = info.GetInt64 ("contentLength");
106                         contentType = info.GetString ("contentType");
107                         method = info.GetString ("method");
108                         statusDescription = info.GetString ("statusDescription");
109                         cookieCollection = (CookieCollection) info.GetValue ("cookieCollection", typeof (CookieCollection));
110                         version = (Version) info.GetValue ("version", typeof (Version));
111                         statusCode = (HttpStatusCode) info.GetValue ("statusCode", typeof (HttpStatusCode));
112                 }
113                 
114                 // Properties
115                 
116                 public string CharacterSet {
117                         // Content-Type   = "Content-Type" ":" media-type
118                         // media-type     = type "/" subtype *( ";" parameter )
119                         // parameter      = attribute "=" value
120                         // 3.7.1. default is ISO-8859-1
121                         get { 
122                                 string contentType = ContentType;
123                                 if (contentType == null)
124                                         return "ISO-8859-1";
125                                 string val = contentType.ToLower ();                                    
126                                 int pos = val.IndexOf ("charset=", StringComparison.Ordinal);
127                                 if (pos == -1)
128                                         return "ISO-8859-1";
129                                 pos += 8;
130                                 int pos2 = val.IndexOf (';', pos);
131                                 return (pos2 == -1)
132                                      ? contentType.Substring (pos) 
133                                      : contentType.Substring (pos, pos2 - pos);
134                         }
135                 }
136                 
137                 public string ContentEncoding {
138                         get {
139                                 CheckDisposed ();
140                                 string h = webHeaders ["Content-Encoding"];
141                                 return h != null ? h : "";
142                         }
143                 }
144                 
145                 public override long ContentLength {            
146                         get {
147                                 return contentLength;
148                         }
149                 }
150                 
151                 public override string ContentType {            
152                         get {
153                                 CheckDisposed ();
154
155                                 if (contentType == null)
156                                         contentType = webHeaders ["Content-Type"];
157
158                                 return contentType;
159                         }
160                 }
161                 
162                 public CookieCollection Cookies {
163                         get {
164                                 CheckDisposed ();
165                                 if (cookieCollection == null)
166                                         cookieCollection = new CookieCollection ();
167                                 return cookieCollection;
168                         }
169                         set {
170                                 CheckDisposed ();
171                                 cookieCollection = value;
172                         }
173                 }
174                 
175                 public override WebHeaderCollection Headers {           
176                         get {
177                                 return webHeaders; 
178                         }
179                 }
180
181                 static Exception GetMustImplement ()
182                 {
183                         return new NotImplementedException ();
184                 }
185                 
186                 [MonoTODO]
187                 public override bool IsMutuallyAuthenticated
188                 {
189                         get {
190                                 throw GetMustImplement ();
191                         }
192                 }
193                 
194                 public DateTime LastModified {
195                         get {
196                                 CheckDisposed ();
197                                 try {
198                                         string dtStr = webHeaders ["Last-Modified"];
199                                         return MonoHttpDate.Parse (dtStr);
200                                 } catch (Exception) {
201                                         return DateTime.Now;    
202                                 }
203                         }
204                 }
205                 
206                 public string Method {
207                         get {
208                                 CheckDisposed ();
209                                 return method; 
210                         }
211                 }
212                 
213                 public Version ProtocolVersion {
214                         get {
215                                 CheckDisposed ();
216                                 return version; 
217                         }
218                 }
219                 
220                 public override Uri ResponseUri {               
221                         get {
222                                 CheckDisposed ();
223                                 return uri; 
224                         }
225                 }               
226                 
227                 public string Server {
228                         get {
229                                 CheckDisposed ();
230                                 return webHeaders ["Server"]; 
231                         }
232                 }
233                 
234                 public HttpStatusCode StatusCode {
235                         get {
236                                 return statusCode; 
237                         }
238                 }
239                 
240                 public string StatusDescription {
241                         get {
242                                 CheckDisposed ();
243                                 return statusDescription; 
244                         }
245                 }
246
247                 // Methods
248                 
249                 public string GetResponseHeader (string headerName)
250                 {
251                         CheckDisposed ();
252                         string value = webHeaders [headerName];
253                         return (value != null) ? value : "";
254                 }
255
256                 internal void ReadAll ()
257                 {
258                         WebConnectionStream wce = stream as WebConnectionStream;
259                         if (wce == null)
260                                 return;
261                                 
262                         try {
263                                 wce.ReadAll ();
264                         } catch {}
265                 }
266
267                 public override Stream GetResponseStream ()
268                 {
269                         CheckDisposed ();
270                         if (stream == null)
271                                 return Stream.Null;  
272                         if (0 == String.Compare (method, "HEAD", true)) // see par 4.3 & 9.4
273                                 return Stream.Null;  
274
275                         return stream;
276                 }
277                 
278                 void ISerializable.GetObjectData (SerializationInfo serializationInfo,
279                                                   StreamingContext streamingContext)
280                 {
281                         GetObjectData (serializationInfo, streamingContext);
282                 }
283
284                 protected override void GetObjectData (SerializationInfo serializationInfo,
285                         StreamingContext streamingContext)
286                 {
287                         SerializationInfo info = serializationInfo;
288
289                         info.AddValue ("uri", uri);
290                         info.AddValue ("contentLength", contentLength);
291                         info.AddValue ("contentType", contentType);
292                         info.AddValue ("method", method);
293                         info.AddValue ("statusDescription", statusDescription);
294                         info.AddValue ("cookieCollection", cookieCollection);
295                         info.AddValue ("version", version);
296                         info.AddValue ("statusCode", statusCode);
297                 }
298
299                 // Cleaning up stuff
300
301                 public override void Close ()
302                 {
303                         if (stream != null) {
304                                 Stream st = stream;
305                                 stream = null;
306                                 if (st != null)
307                                         st.Close ();
308                         }
309                 }
310                 
311                 void IDisposable.Dispose ()
312                 {
313                         Dispose (true);
314                         GC.SuppressFinalize (this);  
315                 }
316
317                 void Dispose (bool disposing) 
318                 {
319                         this.disposed = true;
320                         if (disposing)
321                                 Close ();
322                 }
323                 
324                 private void CheckDisposed () 
325                 {
326                         if (disposed)
327                                 throw new ObjectDisposedException (GetType ().FullName);
328                 }
329
330                 void FillCookies ()
331                 {
332                         if (webHeaders == null)
333                                 return;
334
335                         string value = webHeaders.Get ("Set-Cookie");
336                         if (value != null) {
337                                 SetCookie (value);
338                         }
339
340                         value = webHeaders.Get ("Set-Cookie2");
341                         if (value != null) {
342                                 SetCookie (value);
343                         }
344                 }
345
346                 void SetCookie (string header)
347                 {
348                         if (cookieCollection == null)
349                                 cookieCollection = new CookieCollection ();
350
351                         var parser = new CookieParser (header);
352                         foreach (var cookie in parser.Parse ()) {
353                                 if (cookie.Domain == "")
354                                         cookie.Domain = uri.Host;
355
356                                 cookieCollection.Add (cookie);
357                                 if (cookie_container != null)
358                                         cookie_container.Add (uri, cookie);
359                         }
360                 }
361         }       
362 }
363