00001 using System;
00002 using System.IO;
00003 using System.Text;
00004 using System.Net.Sockets;
00005 using System.Collections;
00006 using System.Runtime.Serialization;
00007 using System.Runtime.Serialization.Formatters.Binary;
00008 using NZlib.Streams;
00009
00010 namespace Common {
00011
00012
00013 public class HTTPResponse : HTTPObject {
00014
00015 public String ContentType {
00016 get {
00017 return headers.headerCollection["Content-Type"];
00018 }
00019 }
00020
00021 public String ContentLength {
00022 get { return headers.headerCollection["Content-Length"]; }
00023 set {
00024 try {
00025 string oldLength = "Content-Length: " + headers.headerCollection["Content-length"];
00026 string newLength = "Content-Length: " + value;
00027 headers.rawString.Replace(oldLength, newLength);
00028 } catch (Exception ex) {
00029 Console.WriteLine("*** Error occured trying to set new Content Length value for response: {0} ***", ex.Message);
00030 }
00031 this.headers.parseRaw();
00032 }
00033 }
00034 public string Headers {
00035 get { return headers.rawString; }
00036 }
00037
00038 public int StatusCode {
00039 get { return Int32.Parse(((HTTPResponseHeader)headers).statusCode); }
00040 }
00041
00042 public HTTPBody Body {
00043 get { return body; }
00044 }
00045
00046 public HTTPResponse(HTTPResponseHeader headers) {
00047 this.headers = headers;
00048 }
00049
00050 public HTTPResponse(ref Stream nwstream) {
00051 StringBuilder sb = new StringBuilder();
00052 string s1 = StreamUtil.ReadLine(ref nwstream);
00053 while (s1 != "") {
00054 sb.Append(s1 + "\r\n");
00055 s1 = StreamUtil.ReadLine(ref nwstream);
00056 }
00057 sb.Append("\r\n");
00058
00059 this.headers = new HTTPResponseHeader(sb.ToString());
00060
00061 if (this.headers.headerCollection["Content-Length"] != null) {
00062 int bodySize = Int32.Parse(this.headers.headerCollection["Content-Length"]);
00063 byte[] bodyBuffer = StreamUtil.ReadBody(ref nwstream, bodySize);
00064 this.body = new HTTPBody(bodyBuffer);
00065 }
00066 else if ((this.headers.headerCollection["Connection"] == "Close") || ((HTTPResponseHeader)this.headers).statusCode == "200") {
00067
00068 try {
00069 byte[] bodyBuffer = StreamUtil.ReadBody(ref nwstream);
00070 this.body = new HTTPBody(bodyBuffer);
00071 } catch (Exception ex) {
00072
00073 Console.WriteLine(ex);
00074 }
00075 }
00076 }
00077
00078 public HTTPResponse() {}
00079
00080 public HTTPResponse(byte[] src) : base(src) {
00081 if (headerBytes != null) {
00082 headers = new HTTPResponseHeader(headerBytes);
00083 }
00084 if (bodyBytes != null) {
00085 body = new HTTPBody(bodyBytes);
00086 }
00087 }
00088 }
00089
00090
00091 public class HTTPResponseHeader : HTTPHeader {
00092
00093 public string statusCode;
00094
00095 public HTTPResponseHeader(string source) : base(source) {}
00096 public HTTPResponseHeader(byte[] src) : base(Encoding.ASCII.GetString(src)) {}
00097
00098
00099 protected override void parseHTTP() {
00100 int i1 = rawStringPos;
00101 int i2 = rawString.IndexOf("\r\n");
00102 int i3;
00103 string s = rawString.Substring(i1,i2-i1);
00104
00105
00106 i3 = s.IndexOf(' ');
00107
00108 i1 = i3 + 1;
00109
00110 i3 = s.IndexOf(' ', i1);
00111 this.parseStatusCode(s.Substring(i1, i3-i1));
00112 rawStringPos = i2 + "\r\n".Length;
00113 }
00114
00115 protected void parseStatusCode(string src) {
00116 statusCode = src;
00117 }
00118 }
00119
00120 public class HTTPResponseQueueObject : HTTPResponse {
00121 public ushort destinationDeviceID;
00122
00123
00124
00125 public HTTPResponseQueueObject() : base() { }
00126 public HTTPResponseQueueObject(ref Stream nwstream) : base(ref nwstream) {}
00127 public HTTPResponseQueueObject(HTTPResponseHeader headers) : base(headers) {}
00128
00129 }
00130
00134 public class EncodedHTTPResponse : EncodedData {
00135 byte[] compressedData;
00136 bool isDeltaEncoded;
00141 public EncodedHTTPResponse(HTTPResponse response) : this(response, null, null) {}
00142
00149 public EncodedHTTPResponse(HTTPResponse resp, byte[] originalCHk, CacheManager cacheManager) {
00150 MemoryStream uncompressedDataStream = new MemoryStream();
00151 if (originalCHk != null && cacheManager != null && resp.ContentType.StartsWith("text")) {
00152 byte[] oldBodyBytes = cacheManager.GetByChk(originalCHk).data;
00153 if (Math.Abs(oldBodyBytes.Length - resp.Body.data.Length) <= (16 * 1024)) {
00154 isDeltaEncoded = true;
00155 MemoryStream oldBodyData = new MemoryStream(oldBodyBytes);
00156 MemoryStream newBodyData = new MemoryStream(resp.Body.data);
00157 ArrayList changeHunks = CacheManager.Diff(oldBodyData, newBodyData);
00158
00159 IFormatter formatter = new BinaryFormatter();
00160
00161 resp.AppendBody(null);
00162 byte[] serilaisedHeaders = resp.Serialise();
00163
00164
00165 uncompressedDataStream.Write(BitConverter.GetBytes(serilaisedHeaders.Length), 0, BitConverter.GetBytes(serilaisedHeaders.Length).Length);
00166 uncompressedDataStream.Write(serilaisedHeaders, 0, serilaisedHeaders.Length);
00167 uncompressedDataStream.Write(originalCHk, 0, originalCHk.Length);
00168 formatter.Serialize(uncompressedDataStream, changeHunks);
00169 } else {
00170 isDeltaEncoded = false;
00171 byte[] serialisedResponse = resp.Serialise();
00172 uncompressedDataStream.Write(serialisedResponse, 0, serialisedResponse.Length);
00173 }
00174 } else {
00175 isDeltaEncoded = false;
00176 byte[] serialisedResponse = resp.Serialise();
00177 uncompressedDataStream.Write(serialisedResponse, 0, serialisedResponse.Length);
00178 }
00179
00180 compressedData = Zip(uncompressedDataStream);
00181 uncompressedDataStream.Close();
00182
00183 }
00184
00191 public EncodedHTTPResponse(byte[] src, int start, int length) {
00192 Deserialise(src, start, length);
00193 }
00194
00195 public byte[] Serialise() {
00196 MemoryStream buffer = new MemoryStream();
00197 buffer.Write(BitConverter.GetBytes(isDeltaEncoded), 0, BitConverter.GetBytes(isDeltaEncoded).Length);
00198 buffer.Write(compressedData, 0, compressedData.Length);
00199 byte[] result = new byte[buffer.Length];
00200 buffer.Seek(0, SeekOrigin.Begin);
00201 buffer.Read(result, 0, result.Length);
00202 buffer.Close();
00203 return result;
00204 }
00205
00206 public void Deserialise(byte[] src, int start, int length) {
00207 int currentPos = start;
00208 isDeltaEncoded = BitConverter.ToBoolean(src, currentPos);
00209 currentPos += 1;
00210 compressedData = new byte[(length - currentPos) + start];
00211 Array.Copy(src, currentPos, compressedData, 0, compressedData.Length);
00212 }
00213
00214
00220 public HTTPResponse Decode(CacheManager cacheManager) {
00221 MemoryStream compressedDataStream = new MemoryStream(compressedData);
00222 HTTPResponse result;
00223 if (isDeltaEncoded) {
00224 byte[] uncompressedData = Unzip(ref compressedDataStream);
00225 int currentPos = 0;
00226
00227 int headerLength = BitConverter.ToInt32(uncompressedData, currentPos);
00228 currentPos += 4;
00229 byte[] headerBytes = new byte[headerLength];
00230 Array.Copy(uncompressedData, currentPos, headerBytes, 0, headerLength);
00231 currentPos += headerLength;
00232
00233 result = new HTTPResponse(headerBytes);
00234
00235 byte[] originalChk = new byte[20];
00236 Array.Copy(uncompressedData, currentPos, originalChk, 0, originalChk.Length);
00237 currentPos += 20;
00238
00239 MemoryStream partialUncompressedStream = new MemoryStream(uncompressedData, currentPos, uncompressedData.Length - currentPos);
00240 IFormatter formatter = new BinaryFormatter();
00241 ArrayList hunkList = (ArrayList) formatter.Deserialize(partialUncompressedStream);
00242
00243
00244 HTTPBody oldDocBody = cacheManager.GetByChk(originalChk);
00245 byte[] newDocBytes = CacheManager.Patch(oldDocBody.data, hunkList);
00246 result.AppendBody(new HTTPBody(newDocBytes));
00247 } else {
00248 result = new HTTPResponse(Unzip(ref compressedDataStream));
00249 }
00250 compressedDataStream.Close();
00251 return result;
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 }
00274
00275 public class EncodedData {
00279 protected byte[] Unzip(ref MemoryStream compressedStream) {
00280 MemoryStream deflatedOutput = new MemoryStream();
00281 byte[] buffer = new byte[512];
00282 int bytesRead;
00283 InflaterInputStream inflateStream = new InflaterInputStream(compressedStream);
00284 bytesRead = inflateStream.Read(buffer, 0, buffer.Length);
00285 while (bytesRead > 0) {
00286 deflatedOutput.Write(buffer, 0, bytesRead);
00287 bytesRead = inflateStream.Read(buffer, 0, buffer.Length);
00288 }
00289 inflateStream.Flush();
00290 inflateStream.Close();
00291 deflatedOutput.Flush();
00292 byte[] result = new byte[deflatedOutput.Length];
00293 deflatedOutput.Seek(0, SeekOrigin.Begin);
00294 deflatedOutput.Read(result, 0, result.Length);
00295 deflatedOutput.Close();
00296 return result;
00297 }
00298
00299 protected byte[] Zip(MemoryStream uncompressedDataStream) {
00300 MemoryStream compressedDataStream = new MemoryStream();
00301 DeflaterOutputStream deflaterStream = new DeflaterOutputStream(compressedDataStream);
00302 uncompressedDataStream.WriteTo(deflaterStream);
00303 deflaterStream.Flush();
00304 deflaterStream.Finish();
00305 byte[] result = new byte[compressedDataStream.Length];
00306 compressedDataStream.Seek(0, SeekOrigin.Begin);
00307 compressedDataStream.Read(result, 0, result.Length);
00308 deflaterStream.Close();
00309 compressedDataStream.Close();
00310 return result;
00311 }
00312
00313 public static byte[] StaticUnzip(ref MemoryStream compressedStream) {
00314 EncodedData instance = new EncodedData();
00315 return instance.Unzip(ref compressedStream);
00316 }
00317
00318 public static byte[] StaticZip(MemoryStream uncompressedDataStream) {
00319 EncodedData instance = new EncodedData();
00320 return instance.Zip(uncompressedDataStream);
00321 }
00322 }
00323 }
00324