This patch adds Cookie handling and more correct header handling
(doesn't assume that the next character after a \r is a \n being the
most important).

could someone please look over this and 1) tell me what I did wrong or
2) apply it?
Thanks

--Shahms
? .HttpWebResponse.cs.swp
Index: HttpWebRequest.cs
===================================================================
RCS file: /mono/mcs/class/System/System.Net/HttpWebRequest.cs,v
retrieving revision 1.5
diff -u -r1.5 HttpWebRequest.cs
--- HttpWebRequest.cs   28 May 2002 18:36:53 -0000      1.5
+++ HttpWebRequest.cs   3 Sep 2002 01:17:56 -0000
@@ -56,9 +56,9 @@
                        this.requestUri = uri;
                        this.actualUri = uri;
                        this.webHeaders = new WebHeaderCollection (true);
-                       // this.webHeaders.SetInternal ("Host", uri.Authority);
-                       // this.webHeaders.SetInternal ("Date", 
DateTime.Now.ToUniversalTime ().ToString ("r", null));
-                       // this.webHeaders.SetInternal ("Expect", "100-continue");
+                       this.webHeaders.SetInternal ("Host", uri.Authority);
+                       this.webHeaders.SetInternal ("Date", 
+DateTime.Now.ToUniversalTime ().ToString ("r", null));
+                       this.webHeaders.SetInternal ("Expect", "100-continue");
                        this.method = "GET";
                        this.version = HttpVersion.Version11;
                        this.proxy = GlobalProxySelection.Select;
@@ -451,7 +451,7 @@
                
                internal Stream GetRequestStreamInternal ()
                {
-                       this.requestStream = null;   // TODO: new HttpWebStream (this);
+                       this.requestStream = new HttpWebStream (this);
                        return this.requestStream;
                }
                
@@ -512,7 +512,7 @@
                        if (requestEndEvent != null) {
                                requestEndEvent.WaitOne ();
                        }
-                       Stream responseStream = null; // TODO: new HttpWebStream 
(this);
+                       Stream responseStream = new HttpWebStream (this);
                        this.webResponse = new HttpWebResponse (this.actualUri, 
method, responseStream);
                        return (WebResponse) this.webResponse;
                }
@@ -557,16 +557,41 @@
                // Private Classes
                
                // to catch the Close called on the NetworkStream
-               /*
-               internal class HttpWebStream : Stream
+               internal class HttpWebStream : NetworkStream
                {
                        HttpWebRequest webRequest;
                        
-                       internal HttpWebStream (HttpWebRequest webRequest)
-                               : base (webRequest.RequestUri)
+                       internal HttpWebStream (HttpWebRequest webRequest) 
+                               : base (HttpWebStream.CreateSocket (webRequest), true)
                        {
+                               StreamWriter webWriter = null;
+                               string headerValue = null;
+
+
+                               webWriter = new StreamWriter (this);
+       
+                               webWriter.Write (webRequest.Method + " " + 
+webRequest.actualUri.AbsolutePath + " HTTP/1.1\r\n");
+
+                               foreach (string header in webRequest.webHeaders) {
+                                       headerValue = header + ": " + 
+webRequest.webHeaders[header] + "\r\n";
+                                       webWriter.Write (headerValue);
+                               }
+                               webWriter.Write ("\r\n");
+                               webWriter.Flush();
+
                                this.webRequest = webRequest;
                        }
+               
+                       private static Socket CreateSocket (HttpWebRequest webRequest)
+                       {
+                               IPAddress hostAddr = Dns.Resolve 
+(webRequest.actualUri.Host).AddressList[0];
+                               IPEndPoint endPoint = new IPEndPoint (hostAddr, 
+webRequest.actualUri.Port);
+                               Socket socket = new Socket(AddressFamily.InterNetwork, 
+SocketType.Stream,
+                                       ProtocolType.Tcp);
+
+                               socket.Connect (endPoint);
+                               return socket;
+                       }
                                                
                        public override void Close() 
                        {
@@ -574,6 +599,5 @@
                                webRequest.Close ();
                        }
                }               
-               */
        }
-}
\ No newline at end of file
+}
Index: HttpWebResponse.cs
===================================================================
RCS file: /mono/mcs/class/System/System.Net/HttpWebResponse.cs,v
retrieving revision 1.4
diff -u -r1.4 HttpWebResponse.cs
--- HttpWebResponse.cs  28 May 2002 18:36:53 -0000      1.4
+++ HttpWebResponse.cs  3 Sep 2002 01:17:56 -0000
@@ -29,13 +29,54 @@
                
                internal HttpWebResponse (Uri uri, string method, Stream 
responseStream) 
                { 
+                       Text.StringBuilder value = null;
+                       string last = null;
+                       string line = null;
+                       string[] protocol, header;
+
                        this.uri = uri;
                        this.method = method;
                        this.responseStream = responseStream;
+                       this.webHeaders = new WebHeaderCollection();
+
+                       line = ReadHttpLine(responseStream);
+                       protocol = line.Split (' ');
+                       
+                       switch (protocol[0]) {
+                               case "HTTP/1.0":
+                                       this.version = HttpVersion.Version10;
+                                       break;
+                               case "HTTP/1.1":
+                                       this.version = HttpVersion.Version11;
+                                       break;
+                               default:
+                                       throw new WebException ("Unrecognized HTTP 
+Version");
+                       }
                        
-                       // TODO: parse headers from responseStream
+                       this.statusCode = Int32.Parse (protocol[1]);
+
+                       while ((line = ReadHttpLine(responseStream)).Length != 0) {
+                               if (!Char.IsWhiteSpace (line[0])) { // new header
+                                       header = line.Split (new char[] {':'}, 2);
+                                       if (header.Length != 2)
+                                               throw new WebException ("Bad HTTP 
+Header");
+                                       if (last != null) { // not the first header
+                                               if (last.Equals ("Set-Cookie"))
+                                                       SetCookie (value.ToString());
+                                               else if (last.Equals ("Set-Cookie2"))
+                                                       SetCookie2 (value.ToString());
+                                               else //don't save Set-Cookie headers
+                                                       this.webHeaders[last] = 
+value.ToString();
+                                       }
+                                       last = header[0];
+                                       value = new Text.StringBuilder 
+(header[1].Trim());
+                               }
+                               else
+                                       value.Append (header[0].Trim());
+                       }
                        
-                       this.statusCode = HttpStatusCode.OK;
+                       this.webHeaders[last] = value.ToString(); // otherwise we miss 
+the last header
+                       // TODO: parse cookies from headers
                }
                
                protected HttpWebResponse (SerializationInfo serializationInfo, 
StreamingContext streamingContext)
@@ -100,11 +141,6 @@
                        get { 
                                CheckDisposed ();
                                
-                               // LAMESPEC: a simple test reveal this always 
-                               // returns an empty collection. It is not filled 
-                               // with the values from the Set-Cookie or 
-                               // Set-Cookie2 response headers, which is a bit
-                               // of a shame..
                                if (cookieCollection == null)
                                        cookieCollection = new CookieCollection ();
                                return cookieCollection;
@@ -267,5 +303,98 @@
                        if (disposed)
                                throw new ObjectDisposedException (GetType 
().FullName);
                }
+
+               private static string ReadHttpLine (Stream stream)
+               {
+                       Text.StringBuilder line = new Text.StringBuilder();
+                       byte last = (byte)'\n';
+                       bool read_last = false;
+                       byte[] buf = new byte[1]; // one at a time to not snarf too 
+much
+                       
+                       while (stream.Read (buf, 0, buf.Length) != 0) {
+                               if (buf[0] == '\r') {
+                                       if ((last = (byte)stream.ReadByte ()) == '\n') 
+// headers; not at EOS
+                                               break;
+                                       read_last = true;
+                               }
+
+                               line.Append (Convert.ToChar(buf[0]));
+                               if (read_last) {
+                                       line.Append (Convert.ToChar (last));
+                                       read_last = false;
+                               }
+                       }
+                       
+                       return line.ToString();
+               }
+
+               private void SetCookie (string cookie_str)
+               {
+                       string[] parts = null;
+                       Collections.Queue options = null;
+                       Cookie cookie = null;
+
+                       options = new Collections.Queue (cookie_str.Split (';'));
+                       parts = ((string)options.Dequeue()).Split ('='); // NAME=VALUE 
+must be first
+
+                       cookie = new Cookie (parts[0], parts[1]);
+
+                       while (options.Count > 0) {
+                               parts = ((string)options.Dequeue()).Split ('=');
+                               switch (parts[0].ToUpper()) { // cookie options are 
+case-insensitive
+                                       case "COMMENT":
+                                               if (cookie.Comment == String.Empty)
+                                                       cookie.Comment = parts[1];
+                                       break;
+                                       case "COMMENTURL":
+                                               if (cookie.CommentUri == null)
+                                                       cookie.CommentUri = new 
+Uri(parts[1]);
+                                       break;
+                                       case "DISCARD":
+                                               cookie.Discard = true;
+                                       break;
+                                       case "DOMAIN":
+                                               if (cookie.Domain == String.Empty)
+                                                       cookie.Domain = parts[1];
+                                       break;
+                                       case "MAX-AGE": // RFC Style Set-Cookie2
+                                               if (cookie.Expires == 
+DateTime.MinValue)
+                                                       cookie.Expires = 
+cookie.TimeStamp.AddSeconds (Int32.Parse (parts[1]));
+                                       break;
+                                       case "EXPIRES": // Netscape Style Set-Cookie
+                                               if (cookie.Expires == 
+DateTime.MinValue)
+                                                       cookie.Expires = 
+DateTime.Parse (parts[1]);
+                                       break;
+                                       case "PATH":
+                                               if (cookie.Path == String.Empty)
+                                                       cookie.Path = parts[1];
+                                       break;
+                                       case "PORT":
+                                               if (cookie.Port == String.Empty)
+                                                       cookie.Port = parts[1];
+                                       break;
+                                       case "SECURE":
+                                               cookie.Secure = true;
+                                       break;
+                                       case "VERSION":
+                                               cookie.Version = Int32.Parse 
+(parts[1]);
+                                       break;
+                               } // switch
+                       } // while
+
+                       if (cookieCollection == null)
+                               cookieCollection = new CookieCollection();
+
+                       cookieCollection.Add (cookie);
+               }
+
+               private void SetCookie2 (string cookies_str)
+               {
+                       string[] cookies = cookies_str.Split (',');
+       
+                       foreach (string cookie_str in cookies)
+                               SetCookie (cookie_str);
+
+               }
        }       
-}
\ No newline at end of file
+}



Reply via email to