2 // System.Net.HttpWebResponse
5 // Lawrence Pit (loz@cable.a2000.nl)
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 // (c) 2002 Lawrence Pit
9 // (c) 2003 Ximian, Inc. (http://www.ximian.com)
14 using System.Net.Sockets;
15 using System.Runtime.Serialization;
21 public class HttpWebResponse : WebResponse, ISerializable, IDisposable
24 WebHeaderCollection webHeaders;
25 CookieCollection cookieCollection;
28 HttpStatusCode statusCode;
29 string statusDescription;
31 long contentLength = -1;
34 bool disposed = false;
35 WebConnectionStream stream;
39 internal HttpWebResponse (Uri uri, string method, WebConnectionData data, bool cookiesSet)
43 webHeaders = data.Headers;
44 version = data.Version;
45 statusCode = (HttpStatusCode) data.StatusCode;
46 statusDescription = data.StatusDescription;
50 } else if (webHeaders != null) {
51 webHeaders.RemoveInternal ("Set-Cookie");
52 webHeaders.RemoveInternal ("Set-Cookie2");
56 [MonoTODO("Check this out and update if needed")] //Gon
57 protected HttpWebResponse (SerializationInfo serializationInfo, StreamingContext streamingContext)
59 uri = (Uri) serializationInfo.GetValue ("uri", typeof (Uri));
60 webHeaders = (WebHeaderCollection) serializationInfo.GetValue ("webHeaders",
61 typeof (WebHeaderCollection));
62 cookieCollection = (CookieCollection) serializationInfo.GetValue ("cookieCollection",
63 typeof (CookieCollection));
64 method = serializationInfo.GetString ("method");
65 version = (Version) serializationInfo.GetValue ("version", typeof (Version));
66 statusCode = (HttpStatusCode) serializationInfo.GetValue ("statusCode", typeof (HttpStatusCode));
67 statusDescription = serializationInfo.GetString ("statusDescription");
68 chunked = serializationInfo.GetBoolean ("chunked");
73 public string CharacterSet {
74 // Content-Type = "Content-Type" ":" media-type
75 // media-type = type "/" subtype *( ";" parameter )
76 // parameter = attribute "=" value
77 // 3.7.1. default is ISO-8859-1
80 string contentType = ContentType;
81 if (contentType == null)
83 string val = contentType.ToLower ();
84 int pos = val.IndexOf ("charset=");
88 int pos2 = val.IndexOf (';', pos);
90 ? contentType.Substring (pos)
91 : contentType.Substring (pos, pos2 - pos);
95 public string ContentEncoding {
98 return webHeaders ["Content-Encoding"];
102 public override long ContentLength {
105 if (contentLength != -1)
106 return contentLength;
109 contentLength = (long) UInt64.Parse (webHeaders ["Content-Length"]);
110 } catch (Exception) {
114 return contentLength;
118 public override string ContentType {
121 if (contentType == null)
122 contentType = webHeaders ["Content-Type"];
128 public CookieCollection Cookies {
132 if (cookieCollection == null)
133 cookieCollection = new CookieCollection ();
134 return cookieCollection;
138 cookieCollection = value;
142 public override WebHeaderCollection Headers {
149 public DateTime LastModified {
153 string dtStr = webHeaders ["Last-Modified"];
154 return MonoHttpDate.Parse (dtStr);
155 } catch (Exception) {
161 public string Method {
168 public Version ProtocolVersion {
175 public override Uri ResponseUri {
182 public string Server {
185 return webHeaders ["Server"];
189 public HttpStatusCode StatusCode {
196 public string StatusDescription {
199 return statusDescription;
205 public override int GetHashCode ()
208 return base.GetHashCode ();
211 public string GetResponseHeader (string headerName)
214 string value = webHeaders [headerName];
215 return (value != null) ? value : "";
218 public override Stream GetResponseStream ()
221 if (0 == String.Compare (method, "HEAD", true)) // see par 4.3 & 9.4
227 void ISerializable.GetObjectData (SerializationInfo serializationInfo,
228 StreamingContext streamingContext)
231 serializationInfo.AddValue ("uri", uri);
232 serializationInfo.AddValue ("webHeaders", webHeaders);
233 serializationInfo.AddValue ("cookieCollection", cookieCollection);
234 serializationInfo.AddValue ("method", method);
235 serializationInfo.AddValue ("version", version);
236 serializationInfo.AddValue ("statusCode", statusCode);
237 serializationInfo.AddValue ("statusDescription", statusDescription);
238 serializationInfo.AddValue ("chunked", chunked);
244 public override void Close ()
246 ((IDisposable) this).Dispose ();
249 void IDisposable.Dispose ()
252 GC.SuppressFinalize (this);
255 protected virtual void Dispose (bool disposing)
259 this.disposed = true;
262 // release managed resources
265 cookieCollection = null;
268 statusDescription = null;
271 // release unmanaged resources
278 private void CheckDisposed ()
281 throw new ObjectDisposedException (GetType ().FullName);
286 if (webHeaders == null)
289 string val = webHeaders ["Set-Cookie"];
290 if (val != null && val.Trim () != "")
293 val = webHeaders ["Set-Cookie2"];
294 if (val != null && val.Trim () != "")
298 static string [] SplitValue (string input)
300 string [] result = new string [2];
301 int eq = input.IndexOf ('=');
303 result [0] = "invalid";
305 result [0] = input.Substring (0, eq).Trim ().ToUpper ();
306 result [1] = input.Substring (eq + 1);
312 [MonoTODO ("Parse dates")]
313 void SetCookie (string cookie_str)
315 string[] parts = null;
316 Collections.Queue options = null;
317 Cookie cookie = null;
319 options = new Collections.Queue (cookie_str.Split (';'));
320 parts = SplitValue ((string) options.Dequeue()); // NAME=VALUE must be first
322 cookie = new Cookie (parts[0], parts[1]);
324 while (options.Count > 0) {
325 parts = SplitValue ((string) options.Dequeue());
328 if (cookie.Comment == null)
329 cookie.Comment = parts[1];
332 if (cookie.CommentUri == null)
333 cookie.CommentUri = new Uri(parts[1]);
336 cookie.Discard = true;
339 if (cookie.Domain == "")
340 cookie.Domain = parts[1];
342 case "MAX-AGE": // RFC Style Set-Cookie2
343 if (cookie.Expires == DateTime.MinValue)
344 cookie.Expires = cookie.TimeStamp.AddSeconds (Int32.Parse (parts[1]));
346 case "EXPIRES": // Netscape Style Set-Cookie
347 if (cookie.Expires == DateTime.MinValue) {
348 //FIXME: Does DateTime parse something like: "Sun, 17-Jan-2038 19:14:07 GMT"?
349 //cookie.Expires = DateTime.ParseExact (parts[1]);
350 cookie.Expires = DateTime.Now.AddDays (1);
354 cookie.Path = parts[1];
357 if (cookie.Port == null)
358 cookie.Port = parts[1];
361 cookie.Secure = true;
364 cookie.Version = Int32.Parse (parts[1]);
369 if (cookieCollection == null)
370 cookieCollection = new CookieCollection();
372 if (cookie.Domain == "")
373 cookie.Domain = uri.Host;
375 cookieCollection.Add (cookie);
378 void SetCookie2 (string cookies_str)
380 string [] cookies = cookies_str.Split (',');
382 foreach (string cookie_str in cookies)
383 SetCookie (cookie_str);