00001 using System;
00002 using System.Threading;
00003 using System.Collections;
00004 using System.Collections.Specialized;
00005 using System.Text;
00006 using System.IO;
00007 using System.Net;
00008 using System.Net.Sockets;
00009 using System.Security.Cryptography;
00010
00011 namespace Common
00012 {
00016 public abstract class HTTPObject
00017 {
00018 protected HTTPHeader headers;
00019 protected HTTPBody body;
00020
00021 public HTTPObject() {}
00022
00023 public byte[] Serialise() {
00024
00025
00026
00027
00028
00029
00030 byte[] result;
00031 byte[] headerBuffer = null;
00032 byte[] intSizeByteBuffer;
00033 int resultLength = 0;
00034 int headerLength = 0;
00035 int bodyLength = 0;
00036 if (headers != null) {
00037 headerBuffer = Encoding.ASCII.GetBytes(headers.rawString);
00038 headerLength = headerBuffer.Length;
00039 resultLength += headerLength;
00040 } else {
00041 headerLength = -1;
00042 }
00043 if (body != null) {
00044 bodyLength = body.data.Length;
00045 resultLength += bodyLength;
00046 } else {
00047 bodyLength = -1;
00048 }
00049 result = new byte[resultLength + 8];
00050 intSizeByteBuffer = BitConverter.GetBytes(headerLength);
00051 Array.Copy(intSizeByteBuffer, 0, result, 0, intSizeByteBuffer.Length);
00052 intSizeByteBuffer = BitConverter.GetBytes(bodyLength);
00053 Array.Copy(intSizeByteBuffer, 0, result, 4, intSizeByteBuffer.Length);
00054 if (headers != null) { Array.Copy(headerBuffer, 0, result, 8, headerBuffer.Length); }
00055 if (body != null) { Array.Copy(body.data, 0, result, 8 + headerBuffer.Length, body.data.Length); }
00056 return result;
00057 }
00058
00059 public byte[] ToHTTPByteArray() {
00060
00061
00062
00063
00064
00065
00066 byte[] result;
00067 byte[] headerBuffer = null;
00068 int resultLength = 0;
00069 if (headers != null) {
00070 headerBuffer = Encoding.ASCII.GetBytes(headers.rawString);
00071 resultLength += headerBuffer.Length;
00072 }
00073 if (body != null) {
00074 resultLength += body.data.Length;
00075 }
00076 result = new byte[resultLength];
00077 if (headers != null) { Array.Copy(headerBuffer, 0, result, 0, headerBuffer.Length); }
00078 if (body != null) { Array.Copy(body.data, 0, result, headerBuffer.Length, body.data.Length); }
00079 return result;
00080 }
00081
00082
00087 public HTTPObject(byte[] src) {
00088 int headerLength = BitConverter.ToInt32(src, 0);
00089 int bodyLength = BitConverter.ToInt32(src, 4);
00090 if (headerLength != -1 ) {
00091 headerBytes = new byte[headerLength];
00092 Array.Copy(src, 8, headerBytes, 0, headerLength);
00093 } else {
00094 headerBytes = null;
00095 }
00096 if (bodyLength != -1) {
00097 bodyBytes = new byte[bodyLength];
00098 Array.Copy(src, 8 + headerLength, bodyBytes, 0, bodyLength);
00099 } else {
00100 bodyBytes = null;
00101 }
00102 }
00103
00104
00105
00106 protected byte[] headerBytes;
00107 protected byte[] bodyBytes;
00108
00109 public void AppendBody(HTTPBody newBody) {
00110 body = newBody;
00111 }
00112
00113 public byte[] GetCHK() {
00114 return body.GetCHK();
00115 }
00116 }
00117
00118
00119 public class HTTPBody {
00120 public byte[] data;
00121
00122 public HTTPBody(byte[] data) {
00123 this.data = data;
00124 }
00125
00126 public byte[] GetCHK() {
00127 SHA1Managed sha1 = new SHA1Managed();
00128 return sha1.ComputeHash(data);
00129 }
00130 }
00131
00132
00133 public abstract class HTTPHeader {
00134 public string rawString;
00135 protected int rawStringPos = -1;
00136
00137 public WebHeaderCollection headerCollection;
00138
00139
00140
00141 public HTTPHeader(string source) {
00142 rawString = source;
00143 parseRaw();
00144 }
00145
00146
00147
00148
00149 public void parseRaw() {
00150 rawStringPos = 0;
00151 this.parseHTTP();
00152 this.populateRawHeaders();
00153 }
00154
00158 protected abstract void parseHTTP();
00159
00160
00161
00162
00163
00164
00165
00166 public void populateRawHeaders() {
00167 string CRLF = "\r\n";
00168 headerCollection = new WebHeaderCollection();
00169
00170 int i1 = rawStringPos;
00171 int i2 = rawString.IndexOf(CRLF, i1);
00172 string s = rawString.Substring(i1, i2-i1);
00173 while (s != "") {
00174 headerCollection.Add(s);
00175 i1 = i2 + CRLF.Length;
00176 i2 = rawString.IndexOf(CRLF, i1);
00177 s = rawString.Substring(i1, i2-i1);
00178 }
00179 rawStringPos = i1;
00180 }
00181 }
00182
00183
00184
00185 public class HTTPObjectQueue: Queue {
00186
00187
00188
00189 public void EnqueueBlocking(HTTPObject obj) {
00190 lock(this) {
00191 Enqueue(obj);
00192 Monitor.Pulse(this);
00193 }
00194 }
00195
00196 public HTTPObject DequeueBlocking() {
00197 HTTPObject result;
00198 lock(this) {
00199 while (Count == 0) { Monitor.Wait(this); }
00200 result = (HTTPObject)Dequeue();
00201 Monitor.Pulse(this);
00202 }
00203 return result;
00204 }
00205
00206
00207 }
00208
00209 public class StreamUtil {
00210 public static string ReadLine(ref Stream ns) {
00211 const byte CR = 13;
00212 const byte LF = 10;
00213 byte[] bBuffer = new byte[8 * 1024];
00214 int elementCount = 0;
00215 bool endOfStream = false;
00216 bool endOfLine = false;
00217
00218 string sBuffer;
00219 int readByteResult;
00220 byte currentByte;
00221
00222 while (!endOfStream && !endOfLine) {
00223 readByteResult = ns.ReadByte();
00224 if (readByteResult == -1) {
00225 endOfStream = true;
00226 } else {
00227 currentByte = (byte)readByteResult;
00228 if (currentByte == CR) {
00229 readByteResult = ns.ReadByte();
00230 if (readByteResult == -1) {
00231 endOfStream = true;
00232 } else {
00233 currentByte = (byte)readByteResult;
00234 if (currentByte == LF) {
00235 endOfLine = true;
00236 } else {
00237 append(ref bBuffer, ref elementCount, CR);
00238 append(ref bBuffer, ref elementCount, currentByte);
00239 }
00240 }
00241 } else if (currentByte == LF) {
00242 endOfLine = true;
00243 } else {
00244 append(ref bBuffer, ref elementCount, currentByte);
00245 }
00246 }
00247 }
00248 if (endOfStream) {
00249
00250 sBuffer = null;
00251 } else {
00252
00253 sBuffer = Encoding.ASCII.GetString(bBuffer, 0, elementCount);
00254 }
00255 return sBuffer;
00256 }
00257
00258 private static byte[] ReadBody(ref Stream ns, bool haveTarget, int targetBytes) {
00259
00260 byte[] readBuffer = new byte[8*1024];
00261 byte[] bBuffer = new byte[8*1024];
00262 bool endOfStream = false;
00263 int readByteResult;
00264 byte currentByte;
00265
00266 int totalBytesRead = 0;
00267
00268
00269 while (!endOfStream && (haveTarget ? totalBytesRead < targetBytes : true)) {
00270 readByteResult = ns.ReadByte();
00271 if (readByteResult != -1) {
00272 currentByte = (byte)readByteResult;
00273 append(ref bBuffer, ref totalBytesRead, currentByte);
00274
00275 } else {
00276 endOfStream = true;
00277 }
00278 }
00279
00280
00281 byte[] result = new byte[totalBytesRead];
00282 Array.Copy(bBuffer, result, totalBytesRead);
00283 return result;
00284 }
00285
00286 public static byte[] ReadBody(ref Stream ns, int targetBytes) {
00287 return ReadBody(ref ns, true, targetBytes);
00288 }
00289 public static byte[] ReadBody(ref Stream ns) {
00290 return ReadBody(ref ns, false, 0);
00291 }
00292
00293 private static void append(ref byte[] buffer, ref int elementCount, byte data) {
00294 if (elementCount + 1 > buffer.Length) {
00295 byte[] newBuffer = new byte[buffer.Length * 2];
00296 Array.Copy(buffer, 0, newBuffer, 0, buffer.Length);
00297 buffer = newBuffer;
00298 }
00299 buffer[elementCount] = data;
00300 elementCount++;
00301 }
00302
00303 }
00304 }