4 using Hammock.Extensions;
7 using Hammock.Silverlight.Compat;
9 using System.Collections.Specialized;
17 public class RestResponseBase : IDisposable
19 private string _content;
20 public virtual string Content
24 if(_content == null && ContentStream != null)
26 ContentStream = ReplaceContentStreamWithMemoryStream();
27 using (var reader = new StreamReader(ContentStream))
29 _content = reader.ReadToEnd();
31 if (ContentStream.CanSeek)
33 ContentStream.Position = 0;
40 private byte[] _contentBytes;
41 public virtual byte[] ContentBytes
45 if(_contentBytes == null && ContentStream != null)
47 ContentStream = ReplaceContentStreamWithMemoryStream();
48 _contentBytes = ReadFully(ContentStream);
49 if(ContentStream.CanSeek)
51 ContentStream.Position = 0;
58 public virtual object ErrorContentEntity { get; set; }
59 public virtual Stream ContentStream { get; set; }
60 public virtual WebResponse InnerResponse { get; set; }
61 public virtual Exception InnerException { get; set; }
62 public virtual DateTime? RequestDate { get; set; }
63 public virtual DateTime? ResponseDate { get; set; }
64 public virtual string RequestMethod { get; set; }
65 public virtual bool RequestKeptAlive { get; set; }
66 public virtual HttpStatusCode StatusCode { get; set; }
67 public virtual string StatusDescription { get; set; }
68 public virtual string ContentType { get; set; }
69 public virtual long ContentLength { get; set; }
70 public virtual Uri RequestUri { get; set; }
71 public virtual Uri ResponseUri { get; set; }
72 public virtual bool IsMock { get; set; }
73 public virtual bool TimedOut { get; set; }
74 public virtual int TimesTried { get; set; }
75 public virtual object Tag { get; set; }
76 public virtual NameValueCollection Headers { get; set; }
77 public virtual NameValueCollection Cookies { get; set; }
78 public virtual bool SkippedDueToRateLimitingRule { get; set; }
79 public virtual bool IsFromCache
83 return StatusCode == 0 &&
84 StatusDescription.IsNullOrBlank() &&
89 public RestResponseBase()
94 private void Initialize()
96 Headers = new NameValueCollection(0);
97 Cookies = new NameValueCollection(0);
100 // http://www.yoda.arachsys.com/csharp/readbinary.html
101 public static byte[] ReadFully(Stream stream)
103 const int initialLength = 32768;
104 var buffer = new byte[initialLength];
108 while ((chunk = stream.Read(buffer, read, buffer.Length - read)) > 0)
111 if (read != buffer.Length)
115 var nextByte = stream.ReadByte();
120 var newBuffer = new byte[buffer.Length * 2];
121 Array.Copy(buffer, newBuffer, buffer.Length);
122 newBuffer[read] = (byte)nextByte;
126 var ret = new byte[read];
127 Array.Copy(buffer, ret, read);
131 private Stream ReplaceContentStreamWithMemoryStream()
133 if(ContentStream is DurableMemoryStream)
135 return ContentStream;
138 var buffer = new byte[4096];
139 var stream = new MemoryStream();
143 if (ContentStream == null)
147 count = ContentStream.Read(buffer, 0, buffer.Length);
148 stream.Write(buffer, 0, count);
149 } while (count != 0);
151 if (ContentStream != null)
153 ContentStream.Close();
154 ContentStream.Dispose();
162 return new DurableMemoryStream(stream);
165 private class DurableMemoryStream : MemoryStream
167 private readonly Stream _stream;
169 public DurableMemoryStream(Stream stream)
174 public override IAsyncResult BeginRead(byte[] buffer, int offset, int count,
175 AsyncCallback callback, object state)
177 return _stream.BeginRead(buffer, offset, count, callback, state);
180 public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count,
181 AsyncCallback callback, object state)
183 return _stream.BeginWrite(buffer, offset, count, callback, state);
186 public override bool CanRead
188 get { return _stream.CanRead; }
191 public override bool CanSeek
193 get { return _stream.CanSeek; }
196 public override bool CanWrite
198 get { return _stream.CanWrite; }
201 public override void Close()
206 public override int EndRead(IAsyncResult asyncResult)
208 return _stream.EndRead(asyncResult);
211 public override void EndWrite(IAsyncResult asyncResult)
213 _stream.EndWrite(asyncResult);
216 public override void Flush()
221 public override long Length
225 return _stream.Length;
229 public override long Position
233 return _stream.Position;
237 _stream.Position = value;
241 public override int Read(byte[] buffer, int offset, int count)
243 return _stream.Read(buffer, offset, count);
246 public override int ReadByte()
248 return _stream.ReadByte();
251 public override long Seek(long offset, SeekOrigin origin)
253 return _stream.Seek(offset, origin);
256 public override void SetLength(long value)
258 _stream.SetLength(value);
261 public override void Write(byte[] buffer, int offset, int count)
263 _stream.Write(buffer, offset, count);
266 public override void WriteByte(byte value)
268 _stream.WriteByte(value);
271 protected override void Dispose(bool disposing)
277 base.Dispose(disposing);
281 public void SetContent(string content)
286 public void Dispose()
288 if(ContentStream != null)
290 ContentStream.Dispose();
298 public class RestResponse : RestResponseBase
300 public virtual object ContentEntity { get; set; }
306 public class RestResponse<T> : RestResponseBase
308 public virtual T ContentEntity { get; set; }