| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510 |
- //
- // System.Net.HttpWebResponse
- //
- // Authors:
- // Lawrence Pit ([email protected])
- // Gonzalo Paniagua Javier ([email protected])
- //
- // (c) 2002 Lawrence Pit
- // (c) 2003 Ximian, Inc. (http://www.ximian.com)
- //
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- using System;
- using System.Collections;
- using System.Globalization;
- using System.IO;
- using System.Net.Sockets;
- using System.Runtime.Serialization;
- using System.Text;
- namespace System.Net
- {
- [Serializable]
- public class HttpWebResponse : WebResponse, ISerializable, IDisposable
- {
- Uri uri;
- WebHeaderCollection webHeaders;
- CookieCollection cookieCollection;
- string method;
- Version version;
- HttpStatusCode statusCode;
- string statusDescription;
- long contentLength = -1;
- string contentType;
- CookieContainer cookieContainer;
- bool disposed = false;
- Stream stream;
-
- // Constructors
-
- internal HttpWebResponse (Uri uri, string method, WebConnectionData data, CookieContainer container)
- {
- this.uri = uri;
- this.method = method;
- webHeaders = data.Headers;
- version = data.Version;
- statusCode = (HttpStatusCode) data.StatusCode;
- statusDescription = data.StatusDescription;
- stream = data.stream;
- if (container != null) {
- this.cookieContainer = container;
- FillCookies ();
- } else if (webHeaders != null) {
- webHeaders.RemoveInternal ("Set-Cookie");
- webHeaders.RemoveInternal ("Set-Cookie2");
- }
- }
- protected HttpWebResponse (SerializationInfo serializationInfo, StreamingContext streamingContext)
- {
- SerializationInfo info = serializationInfo;
- uri = (Uri) info.GetValue ("uri", typeof (Uri));
- contentLength = info.GetInt64 ("contentLength");
- contentType = info.GetString ("contentType");
- method = info.GetString ("method");
- statusDescription = info.GetString ("statusDescription");
- cookieCollection = (CookieCollection) info.GetValue ("cookieCollection", typeof (CookieCollection));
- version = (Version) info.GetValue ("version", typeof (Version));
- statusCode = (HttpStatusCode) info.GetValue ("statusCode", typeof (HttpStatusCode));
- }
-
- // Properties
-
- public string CharacterSet {
- // Content-Type = "Content-Type" ":" media-type
- // media-type = type "/" subtype *( ";" parameter )
- // parameter = attribute "=" value
- // 3.7.1. default is ISO-8859-1
- get {
- CheckDisposed ();
- string contentType = ContentType;
- if (contentType == null)
- return "ISO-8859-1";
- string val = contentType.ToLower ();
- int pos = val.IndexOf ("charset=");
- if (pos == -1)
- return "ISO-8859-1";
- pos += 8;
- int pos2 = val.IndexOf (';', pos);
- return (pos2 == -1)
- ? contentType.Substring (pos)
- : contentType.Substring (pos, pos2 - pos);
- }
- }
-
- public string ContentEncoding {
- get {
- CheckDisposed ();
- return webHeaders ["Content-Encoding"];
- }
- }
-
- public override long ContentLength {
- get {
- CheckDisposed ();
- if (contentLength != -1)
- return contentLength;
- try {
- contentLength = (long) UInt64.Parse (webHeaders ["Content-Length"]);
- } catch (Exception) {
- return -1;
- }
- return contentLength;
- }
- }
-
- public override string ContentType {
- get {
- CheckDisposed ();
- if (contentType == null)
- contentType = webHeaders ["Content-Type"];
- return contentType;
- }
- }
-
- public CookieCollection Cookies {
- get {
- CheckDisposed ();
-
- if (cookieCollection == null)
- cookieCollection = new CookieCollection ();
- return cookieCollection;
- }
- set {
- CheckDisposed ();
- cookieCollection = value;
- }
- }
-
- public override WebHeaderCollection Headers {
- get {
- CheckDisposed ();
- return webHeaders;
- }
- }
-
- public DateTime LastModified {
- get {
- CheckDisposed ();
- try {
- string dtStr = webHeaders ["Last-Modified"];
- return MonoHttpDate.Parse (dtStr);
- } catch (Exception) {
- return DateTime.Now;
- }
- }
- }
-
- public string Method {
- get {
- CheckDisposed ();
- return method;
- }
- }
-
- public Version ProtocolVersion {
- get {
- CheckDisposed ();
- return version;
- }
- }
-
- public override Uri ResponseUri {
- get {
- CheckDisposed ();
- return uri;
- }
- }
-
- public string Server {
- get {
- CheckDisposed ();
- return webHeaders ["Server"];
- }
- }
-
- public HttpStatusCode StatusCode {
- get {
- CheckDisposed ();
- return statusCode;
- }
- }
-
- public string StatusDescription {
- get {
- CheckDisposed ();
- return statusDescription;
- }
- }
- // Methods
- #if !NET_2_0
- public override int GetHashCode ()
- {
- CheckDisposed ();
- return base.GetHashCode ();
- }
- #endif
-
- public string GetResponseHeader (string headerName)
- {
- CheckDisposed ();
- string value = webHeaders [headerName];
- return (value != null) ? value : "";
- }
- internal void ReadAll ()
- {
- WebConnectionStream wce = stream as WebConnectionStream;
- if (wce == null)
- return;
-
- try {
- wce.ReadAll ();
- } catch {}
- }
- public override Stream GetResponseStream ()
- {
- CheckDisposed ();
- if (stream == null)
- return Stream.Null;
- if (0 == String.Compare (method, "HEAD", true)) // see par 4.3 & 9.4
- return Stream.Null;
- return stream;
- }
-
- void ISerializable.GetObjectData (SerializationInfo serializationInfo,
- StreamingContext streamingContext)
- {
- SerializationInfo info = serializationInfo;
- info.AddValue ("uri", uri);
- info.AddValue ("contentLength", contentLength);
- info.AddValue ("contentType", contentType);
- info.AddValue ("method", method);
- info.AddValue ("statusDescription", statusDescription);
- info.AddValue ("cookieCollection", cookieCollection);
- info.AddValue ("version", version);
- info.AddValue ("statusCode", statusCode);
- }
- // Cleaning up stuff
- public override void Close ()
- {
- ((IDisposable) this).Dispose ();
- }
-
- void IDisposable.Dispose ()
- {
- Dispose (true);
- GC.SuppressFinalize (this);
- }
- #if !NET_2_0
- protected virtual
- #endif
- void Dispose (bool disposing)
- {
- if (this.disposed)
- return;
- this.disposed = true;
-
- if (disposing) {
- // release managed resources
- uri = null;
- webHeaders = null;
- cookieCollection = null;
- method = null;
- version = null;
- statusDescription = null;
- }
-
- // release unmanaged resources
- Stream st = stream;
- stream = null;
- if (st != null)
- st.Close ();
- }
-
- private void CheckDisposed ()
- {
- if (disposed)
- throw new ObjectDisposedException (GetType ().FullName);
- }
- void FillCookies ()
- {
- if (webHeaders == null)
- return;
- string [] values = webHeaders.GetValues ("Set-Cookie");
- if (values != null) {
- foreach (string va in values)
- SetCookie (va);
- }
- values = webHeaders.GetValues ("Set-Cookie2");
- if (values != null) {
- foreach (string va in values)
- SetCookie2 (va);
- }
- }
- void SetCookie (string header)
- {
- string name, val;
- Cookie cookie = null;
- CookieParser parser = new CookieParser (header);
- while (parser.GetNextNameValue (out name, out val)) {
- if (name == null || name == "")
- continue;
- if (cookie == null) {
- cookie = new Cookie (name, val);
- continue;
- }
- name = name.ToUpper ();
- switch (name) {
- case "COMMENT":
- if (cookie.Comment == null)
- cookie.Comment = val;
- break;
- case "COMMENTURL":
- if (cookie.CommentUri == null)
- cookie.CommentUri = new Uri (val);
- break;
- case "DISCARD":
- cookie.Discard = true;
- break;
- case "DOMAIN":
- if (cookie.Domain == "")
- cookie.Domain = val;
- break;
- case "MAX-AGE": // RFC Style Set-Cookie2
- if (cookie.Expires == DateTime.MinValue)
- cookie.Expires = cookie.TimeStamp.AddSeconds (Int32.Parse (val));
- break;
- case "EXPIRES": // Netscape Style Set-Cookie
- if (cookie.Expires != DateTime.MinValue)
- break;
- try {
- cookie.Expires = DateTime.ParseExact (val, "r", CultureInfo.InvariantCulture);
- } catch {
- try {
- cookie.Expires = DateTime.ParseExact (val,
- "ddd, dd'-'MMM'-'yyyy HH':'mm':'ss 'GMT'",
- CultureInfo.InvariantCulture);
- } catch {
- cookie.Expires = DateTime.Now.AddDays (1);
- }
- }
- break;
- case "PATH":
- cookie.Path = val;
- break;
- case "PORT":
- if (cookie.Port == null)
- cookie.Port = val;
- break;
- case "SECURE":
- cookie.Secure = true;
- break;
- case "VERSION":
- cookie.Version = Int32.Parse (val);
- break;
- }
- }
- if (cookieCollection == null)
- cookieCollection = new CookieCollection ();
- if (cookie.Domain == "")
- cookie.Domain = uri.Host;
- cookieCollection.Add (cookie);
- if (cookieContainer != null)
- cookieContainer.Add (uri, cookie);
- }
- void SetCookie2 (string cookies_str)
- {
- string [] cookies = cookies_str.Split (',');
-
- foreach (string cookie_str in cookies)
- SetCookie (cookie_str);
- }
- }
- class CookieParser {
- string header;
- int pos;
- int length;
- public CookieParser (string header) : this (header, 0)
- {
- }
- public CookieParser (string header, int position)
- {
- this.header = header;
- this.pos = position;
- this.length = header.Length;
- }
- public bool GetNextNameValue (out string name, out string val)
- {
- name = null;
- val = null;
- if (pos >= length)
- return false;
- name = GetCookieName ();
- if (pos < header.Length && header [pos] == '=') {
- pos++;
- val = GetCookieValue ();
- if (pos < length && header [pos] == ';')
- pos++;
- }
- return true;
- }
- string GetCookieName ()
- {
- int k = pos;
- while (k < length && Char.IsWhiteSpace (header [k]))
- k++;
- int begin = k;
- while (k < length && header [k] != ';' && header [k] != '=')
- k++;
- pos = k;
- return header.Substring (begin, k - begin).Trim ();
- }
- string GetCookieValue ()
- {
- if (pos >= length)
- return null;
- int k = pos;
- while (k < length && Char.IsWhiteSpace (header [k]))
- k++;
- int begin;
- if (header [k] == '"'){
- int j;
- begin = ++k;
- while (k < length && header [k] != '"')
- k++;
- for (j = k; j < length && header [j] != ';'; j++)
- ;
- pos = j;
- } else {
- begin = k;
- while (k < length && header [k] != ';')
- k++;
- pos = k;
- }
-
- return header.Substring (begin, k - begin).Trim ();
- }
- }
- }
|