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;
30 long contentLength = -1;
33 bool disposed = false;
34 WebConnectionStream stream;
38 internal HttpWebResponse (Uri uri, string method, WebConnectionData data, bool cookiesSet)
42 webHeaders = data.Headers;
43 version = data.Version;
44 statusCode = (HttpStatusCode) data.StatusCode;
45 statusDescription = data.StatusDescription;
49 } else if (webHeaders != null) {
50 webHeaders.RemoveInternal ("Set-Cookie");
51 webHeaders.RemoveInternal ("Set-Cookie2");
55 protected HttpWebResponse (SerializationInfo serializationInfo, StreamingContext streamingContext)
57 SerializationInfo info = serializationInfo;
59 uri = (Uri) info.GetValue ("uri", typeof (Uri));
60 contentLength = info.GetInt64 ("contentLength");
61 contentType = info.GetString ("contentType");
62 method = info.GetString ("method");
63 statusDescription = info.GetString ("statusDescription");
64 cookieCollection = (CookieCollection) info.GetValue ("cookieCollection", typeof (CookieCollection));
65 version = (Version) info.GetValue ("version", typeof (Version));
66 statusCode = (HttpStatusCode) info.GetValue ("statusCode", typeof (HttpStatusCode));
71 public string CharacterSet {
72 // Content-Type = "Content-Type" ":" media-type
73 // media-type = type "/" subtype *( ";" parameter )
74 // parameter = attribute "=" value
75 // 3.7.1. default is ISO-8859-1
78 string contentType = ContentType;
79 if (contentType == null)
81 string val = contentType.ToLower ();
82 int pos = val.IndexOf ("charset=");
86 int pos2 = val.IndexOf (';', pos);
88 ? contentType.Substring (pos)
89 : contentType.Substring (pos, pos2 - pos);
93 public string ContentEncoding {
96 return webHeaders ["Content-Encoding"];
100 public override long ContentLength {
103 if (contentLength != -1)
104 return contentLength;
107 contentLength = (long) UInt64.Parse (webHeaders ["Content-Length"]);
108 } catch (Exception) {
112 return contentLength;
116 public override string ContentType {
119 if (contentType == null)
120 contentType = webHeaders ["Content-Type"];
126 public CookieCollection Cookies {
130 if (cookieCollection == null)
131 cookieCollection = new CookieCollection ();
132 return cookieCollection;
136 cookieCollection = value;
140 public override WebHeaderCollection Headers {
147 public DateTime LastModified {
151 string dtStr = webHeaders ["Last-Modified"];
152 return MonoHttpDate.Parse (dtStr);
153 } catch (Exception) {
159 public string Method {
166 public Version ProtocolVersion {
173 public override Uri ResponseUri {
180 public string Server {
183 return webHeaders ["Server"];
187 public HttpStatusCode StatusCode {
194 public string StatusDescription {
197 return statusDescription;
203 public override int GetHashCode ()
206 return base.GetHashCode ();
209 public string GetResponseHeader (string headerName)
212 string value = webHeaders [headerName];
213 return (value != null) ? value : "";
216 public override Stream GetResponseStream ()
219 if (0 == String.Compare (method, "HEAD", true)) // see par 4.3 & 9.4
225 void ISerializable.GetObjectData (SerializationInfo serializationInfo,
226 StreamingContext streamingContext)
228 SerializationInfo info = serializationInfo;
230 info.AddValue ("uri", uri);
231 info.AddValue ("contentLength", contentLength);
232 info.AddValue ("contentType", contentType);
233 info.AddValue ("method", method);
234 info.AddValue ("statusDescription", statusDescription);
235 info.AddValue ("cookieCollection", cookieCollection);
236 info.AddValue ("version", version);
237 info.AddValue ("statusCode", statusCode);
243 public override void Close ()
245 ((IDisposable) this).Dispose ();
248 void IDisposable.Dispose ()
251 GC.SuppressFinalize (this);
254 protected virtual void Dispose (bool disposing)
258 this.disposed = true;
261 // release managed resources
264 cookieCollection = null;
267 statusDescription = null;
270 // release unmanaged resources
277 private void CheckDisposed ()
280 throw new ObjectDisposedException (GetType ().FullName);
285 if (webHeaders == null)
288 string val = webHeaders ["Set-Cookie"];
289 if (val != null && val.Trim () != "")
292 val = webHeaders ["Set-Cookie2"];
293 if (val != null && val.Trim () != "")
297 static string [] SplitValue (string input)
299 string [] result = new string [2];
300 int eq = input.IndexOf ('=');
302 result [0] = "invalid";
304 result [0] = input.Substring (0, eq).Trim ().ToUpper ();
305 result [1] = input.Substring (eq + 1);
311 [MonoTODO ("Parse dates")]
312 void SetCookie (string cookie_str)
314 string[] parts = null;
315 Collections.Queue options = null;
316 Cookie cookie = null;
318 options = new Collections.Queue (cookie_str.Split (';'));
319 parts = SplitValue ((string) options.Dequeue()); // NAME=VALUE must be first
321 cookie = new Cookie (parts[0], parts[1]);
323 while (options.Count > 0) {
324 parts = SplitValue ((string) options.Dequeue());
327 if (cookie.Comment == null)
328 cookie.Comment = parts[1];
331 if (cookie.CommentUri == null)
332 cookie.CommentUri = new Uri(parts[1]);
335 cookie.Discard = true;
338 if (cookie.Domain == "")
339 cookie.Domain = parts[1];
341 case "MAX-AGE": // RFC Style Set-Cookie2
342 if (cookie.Expires == DateTime.MinValue)
343 cookie.Expires = cookie.TimeStamp.AddSeconds (Int32.Parse (parts[1]));
345 case "EXPIRES": // Netscape Style Set-Cookie
346 if (cookie.Expires == DateTime.MinValue) {
347 //FIXME: Does DateTime parse something like: "Sun, 17-Jan-2038 19:14:07 GMT"?
348 //cookie.Expires = DateTime.ParseExact (parts[1]);
349 cookie.Expires = DateTime.Now.AddDays (1);
353 cookie.Path = parts[1];
356 if (cookie.Port == null)
357 cookie.Port = parts[1];
360 cookie.Secure = true;
363 cookie.Version = Int32.Parse (parts[1]);
368 if (cookieCollection == null)
369 cookieCollection = new CookieCollection();
371 if (cookie.Domain == "")
372 cookie.Domain = uri.Host;
374 cookieCollection.Add (cookie);
377 void SetCookie2 (string cookies_str)
379 string [] cookies = cookies_str.Split (',');
381 foreach (string cookie_str in cookies)
382 SetCookie (cookie_str);