Main Page | Class Hierarchy | Class List | File List | Class Members

HTTPRequest.cs

00001 using System;
00002 using System.IO;
00003 using System.Net.Sockets;
00004 using System.Text;
00005 using NZlib.Compression;
00006 using NZlib.Streams;
00007 using NZlib.Zip;
00008 using NZlib.Checksums;
00009 
00010 namespace Common {
00011         /*************************************************************************/
00012         public class HTTPRequest : HTTPObject {
00013                 /*** Properties ***/
00014 
00015                 public string Hostname {
00016                         get { return ((HTTPRequestHeader)headers).requestUri.Host;}
00017                 }
00018 
00019                 public int Port {
00020                         get { return ((HTTPRequestHeader)headers).requestUri.Port; }
00021                 }
00022 
00023                 public Uri URI {
00024                         get { return ((HTTPRequestHeader)headers).requestUri; }
00025                 }
00026                 
00027                 public bool HasPragmaNoCacheSet {
00028                         get { if (headers.headerCollection["Pragma"] != null) {
00029                                           return (headers.headerCollection["Pragma"].IndexOf("no-cache") != -1);
00030                                   } else {
00031                                           return false;
00032                                   }
00033                         }
00034                 }
00035                 /*** Constructors ***/
00036 
00037                 public HTTPRequest(Stream src) {
00038                         StringBuilder sb = new StringBuilder();
00039 
00040                         StreamReader sr = new StreamReader(src, Encoding.ASCII, false, 256);
00041                         string s = sr.ReadLine();
00042 
00043 //                      string s = StreamUtil.ReadLine(ref src);
00044                         while (s != "" && s != null) {
00045                                 sb.Append(s + "\r\n");
00046                                 s = sr.ReadLine();
00047 //                              s = StreamUtil.ReadLine(ref src);
00048                         }
00049                         sb.Append("\r\n");
00050 
00051                         headers = new HTTPRequestHeader(sb.ToString());
00052                         //Console.WriteLine(">>> CLIENT REQUEST: " + this.URI);
00053                         // if we have data to receive, we can receive "Content-length" number of bits!
00054                         if (this.headers.headerCollection["Content-Length"] != null) {
00055                                 int bodySize = Int32.Parse(this.headers.headerCollection["Content-Length"]);
00056                                 byte[] bodyBuffer = StreamUtil.ReadBody(ref src, bodySize);
00057                                 this.body = new HTTPBody(bodyBuffer);
00058                         } // otherwise, we could be in a case where connection is terminating determines size
00059                         else if ((this.headers.headerCollection["Connection"] == "Close") || ((HTTPRequestHeader)this.headers).method == "POST") {
00060                                 // TODO: find more conditions for having a body
00061                                         byte[] bodyBuffer = StreamUtil.ReadBody(ref src);
00062                                         this.body = new HTTPBody(bodyBuffer);
00063                                 // throw any exceptions up the ladder.
00064                         } 
00065 //                      Console.WriteLine("HTTP Request constructor finished");
00066                 }
00067 
00068                 public HTTPRequest(byte[] src) : base(src) {
00069                         // calling base(src) should have set up bodyBytes and headerBytes
00070                         if (headerBytes != null) {
00071                                 headers = new HTTPRequestHeader(headerBytes);
00072                         }
00073                         if (bodyBytes != null) {
00074                                 body = new HTTPBody(bodyBytes);
00075                         }
00076                 }
00077 
00082                 public HTTPRequest(HTTPRequest req) {
00083                         this.headers = new HTTPRequestHeader(req.headers.rawString);
00084                         this.headerBytes = req.headerBytes;
00085                         this.body = req.body;
00086                         this.bodyBytes = req.bodyBytes;
00087                 }
00088 
00094                 public HTTPRequest(HTTPRequest baseRequest, Uri newUri) : this(baseRequest) {
00095                         try {
00096                                 int i1 = 0;
00097                                 int i2 = headers.rawString.IndexOf("\r\n");
00098                                 int i3;
00099                                 string s = headers.rawString.Substring(i1, i2-i1);
00100                                 // extract method
00101                                 i3 = s.IndexOf(' ');
00102                                 //                      parseHTTPMethod(s.Substring(i1, i3-i1));
00103                                 i1=i3+1;
00104                                 // extract URI
00105                                 i3 = s.IndexOf(' ', i1);
00106                                 string newRawHeaders = s.Remove(i1, i3-i1);
00107                                 newRawHeaders = newRawHeaders.Insert(i1, newUri.ToString());
00108                                 string s1 = headers.rawString.Replace(s, newRawHeaders);
00109                                 s1 = s1.Replace(headers.headerCollection["Host"], newUri.Host + ":" + newUri.Port);
00110                                 headers.rawString = s1;
00111                                 headers.parseRaw();
00112                         } catch (Exception ex) {
00113                                 string errorMessage = String.Format("*** Error creating HTTP Request for {0} ***\n{1}", newUri, ex.Message);
00114                                 Console.WriteLine(errorMessage);
00115                                 throw new Exception(errorMessage, ex);
00116                         }
00117                 }
00118         }
00119 
00120         /*************************************************************************/
00121         public class HTTPRequestHeader : HTTPHeader {
00122                 // deals differently with HTTP/1.0 GET foo.html header
00123                 public Uri requestUri;
00124                 public string method; // TODO: Convert to ENUM
00125 
00126                 /*** Constructors ***/
00127                 public HTTPRequestHeader(string source) : base(source) {}
00128 
00129                 public HTTPRequestHeader(byte[] src) : this(Encoding.ASCII.GetString(src)) {
00130 
00131                 }
00132                 /*** Methods ***/
00133                 protected override void parseHTTP() {
00134                         string CRLF = "\r\n";
00135                         int i1 = rawStringPos;
00136                         int i2 = rawString.IndexOf(CRLF);
00137                         int i3;
00138                         string s = rawString.Substring(i1, i2-i1);
00139                         // do parsing work
00140                         // extract method
00141                         i3 = s.IndexOf(' ');
00142                         parseHTTPMethod(s.Substring(i1, i3-i1));
00143                         i1=i3+1;
00144                         // extract URI
00145                         i3 = s.IndexOf(' ', i1);
00146                         parseRequestUri(s.Substring(i1, i3-i1));
00147                         i1 = i3 + 1;
00148                         // extract version info
00149 //                      parseVersionInfo(s.Substring(i1, s.Length-i1)); // get to the end of the string
00150                         rawStringPos = i2 + CRLF.Length; // step over the newline char
00151                 }
00152                 public void parseHTTPMethod(string s) {
00153                         method = s;
00154                 }
00155 
00156                 protected void parseRequestUri(string s) {
00157                         requestUri = new Uri(s);
00158                 }
00159         }
00160         /*************************************************************************/
00161         // used to go in a queue
00162         public class HTTPRequestQueueObject : HTTPRequest {
00166                 public ushort sourceDeviceID;
00167                 // callback ID
00168                 public int callbackReceipt;             
00169                 // chk of origianl document. if != null, use it to create a delta
00170                 public byte[] originalChk; 
00171                 // parent constructors
00172                 public HTTPRequestQueueObject(System.Net.Sockets.NetworkStream s) : base(s) {}
00173                 public HTTPRequestQueueObject(HTTPRequest req) : base(req) {}
00174         }
00175         /*************************************************************************/
00179         public class EncodedHTTPRequest {
00180                 byte[] compressedData;
00185                 public EncodedHTTPRequest(HTTPRequest req) {
00186                         byte[] srcData = req.Serialise();
00187                         MemoryStream deflatedMem = new MemoryStream();
00188                         DeflaterOutputStream defOutStr = new DeflaterOutputStream(deflatedMem);
00189                         defOutStr.Write(srcData, 0, srcData.Length);
00190                         defOutStr.Flush();
00191                         defOutStr.Finish();
00192                         compressedData = new byte[deflatedMem.Position];
00193                         Array.Copy(deflatedMem.GetBuffer(), compressedData, compressedData.Length);
00194                         defOutStr.Close();
00195                 }
00202                 public EncodedHTTPRequest(byte[] src, int start, int length) {
00203                         compressedData = new byte[length];
00204                         Array.Copy(src, start, compressedData, 0, length);
00205                 }
00206 
00207                 public byte[] ToByteArray() {
00208                         return compressedData;
00209                 }
00210 
00215                 public HTTPRequest Decode() {
00216                         MemoryStream baseInflationStream = new MemoryStream(compressedData);
00217                         MemoryStream deflatedOutput = new MemoryStream();
00218                         byte[] buffer = new byte[512];
00219                         int bytesRead;
00220                         InflaterInputStream inflateStream = new InflaterInputStream(baseInflationStream);
00221                         bytesRead = inflateStream.Read(buffer, 0, buffer.Length);
00222                         while (bytesRead > 0) {
00223                                 deflatedOutput.Write(buffer, 0, bytesRead);
00224                                 bytesRead = inflateStream.Read(buffer, 0, buffer.Length);
00225                         }
00226                         inflateStream.Flush();
00227                         inflateStream.Close();
00228                         deflatedOutput.Flush();
00229                         HTTPRequest result = new HTTPRequest(deflatedOutput.GetBuffer());
00230                         deflatedOutput.Close();
00231                         return result;
00232                 }
00233         }
00234         
00235 }

Generated on Mon May 8 22:07:27 2006 by  doxygen 1.3.9.1