HttpResult.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Net;
  5. using System.Text;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. using MediaBrowser.Model.Services;
  9. using ServiceStack.Host;
  10. namespace ServiceStack
  11. {
  12. public class HttpResult
  13. : IHttpResult, IAsyncStreamWriter
  14. {
  15. public HttpResult()
  16. : this((object)null, null)
  17. {
  18. }
  19. public HttpResult(object response)
  20. : this(response, null)
  21. {
  22. }
  23. public HttpResult(object response, string contentType)
  24. : this(response, contentType, HttpStatusCode.OK)
  25. {
  26. }
  27. public HttpResult(HttpStatusCode statusCode, string statusDescription)
  28. : this()
  29. {
  30. StatusCode = statusCode;
  31. StatusDescription = statusDescription;
  32. }
  33. public HttpResult(object response, HttpStatusCode statusCode)
  34. : this(response, null, statusCode)
  35. { }
  36. public HttpResult(object response, string contentType, HttpStatusCode statusCode)
  37. {
  38. this.Headers = new Dictionary<string, string>();
  39. this.Cookies = new List<Cookie>();
  40. this.Response = response;
  41. this.ContentType = contentType;
  42. this.StatusCode = statusCode;
  43. }
  44. public HttpResult(Stream responseStream, string contentType)
  45. : this(null, contentType, HttpStatusCode.OK)
  46. {
  47. this.ResponseStream = responseStream;
  48. }
  49. public HttpResult(string responseText, string contentType)
  50. : this(null, contentType, HttpStatusCode.OK)
  51. {
  52. this.ResponseText = responseText;
  53. }
  54. public HttpResult(byte[] responseBytes, string contentType)
  55. : this(null, contentType, HttpStatusCode.OK)
  56. {
  57. this.ResponseStream = new MemoryStream(responseBytes);
  58. }
  59. public string ResponseText { get; private set; }
  60. public Stream ResponseStream { get; private set; }
  61. public string ContentType { get; set; }
  62. public IDictionary<string, string> Headers { get; private set; }
  63. public List<Cookie> Cookies { get; private set; }
  64. public string ETag { get; set; }
  65. public TimeSpan? Age { get; set; }
  66. public TimeSpan? MaxAge { get; set; }
  67. public DateTime? Expires { get; set; }
  68. public DateTime? LastModified { get; set; }
  69. public Func<IDisposable> ResultScope { get; set; }
  70. public string Location
  71. {
  72. set
  73. {
  74. if (StatusCode == HttpStatusCode.OK)
  75. StatusCode = HttpStatusCode.Redirect;
  76. this.Headers["Location"] = value;
  77. }
  78. }
  79. public void SetPermanentCookie(string name, string value)
  80. {
  81. SetCookie(name, value, DateTime.UtcNow.AddYears(20), null);
  82. }
  83. public void SetPermanentCookie(string name, string value, string path)
  84. {
  85. SetCookie(name, value, DateTime.UtcNow.AddYears(20), path);
  86. }
  87. public void SetSessionCookie(string name, string value)
  88. {
  89. SetSessionCookie(name, value, null);
  90. }
  91. public void SetSessionCookie(string name, string value, string path)
  92. {
  93. path = path ?? "/";
  94. this.Headers["Set-Cookie"] = string.Format("{0}={1};path=" + path, name, value);
  95. }
  96. public void SetCookie(string name, string value, TimeSpan expiresIn, string path)
  97. {
  98. var expiresAt = DateTime.UtcNow.Add(expiresIn);
  99. SetCookie(name, value, expiresAt, path);
  100. }
  101. public void SetCookie(string name, string value, DateTime expiresAt, string path, bool secure = false, bool httpOnly = false)
  102. {
  103. path = path ?? "/";
  104. var cookie = string.Format("{0}={1};expires={2};path={3}", name, value, expiresAt.ToString("R"), path);
  105. if (secure)
  106. cookie += ";Secure";
  107. if (httpOnly)
  108. cookie += ";HttpOnly";
  109. this.Headers["Set-Cookie"] = cookie;
  110. }
  111. public void DeleteCookie(string name)
  112. {
  113. var cookie = string.Format("{0}=;expires={1};path=/", name, DateTime.UtcNow.AddDays(-1).ToString("R"));
  114. this.Headers["Set-Cookie"] = cookie;
  115. }
  116. public int Status { get; set; }
  117. public HttpStatusCode StatusCode
  118. {
  119. get { return (HttpStatusCode)Status; }
  120. set { Status = (int)value; }
  121. }
  122. public string StatusDescription { get; set; }
  123. public object Response { get; set; }
  124. public MediaBrowser.Model.Services.IRequest RequestContext { get; set; }
  125. public string View { get; set; }
  126. public string Template { get; set; }
  127. public int PaddingLength { get; set; }
  128. public async Task WriteToAsync(Stream responseStream, CancellationToken cancellationToken)
  129. {
  130. try
  131. {
  132. await WriteToInternalAsync(responseStream, cancellationToken).ConfigureAwait(false);
  133. responseStream.Flush();
  134. }
  135. finally
  136. {
  137. DisposeStream();
  138. }
  139. }
  140. public static Task WriteTo(Stream inStream, Stream outStream, CancellationToken cancellationToken)
  141. {
  142. var memoryStream = inStream as MemoryStream;
  143. if (memoryStream != null)
  144. {
  145. memoryStream.WriteTo(outStream);
  146. return Task.FromResult(true);
  147. }
  148. return inStream.CopyToAsync(outStream, 81920, cancellationToken);
  149. }
  150. public async Task WriteToInternalAsync(Stream responseStream, CancellationToken cancellationToken)
  151. {
  152. var response = RequestContext != null ? RequestContext.Response : null;
  153. if (this.ResponseStream != null)
  154. {
  155. if (response != null)
  156. {
  157. var ms = ResponseStream as MemoryStream;
  158. if (ms != null)
  159. {
  160. response.SetContentLength(ms.Length);
  161. await ms.CopyToAsync(responseStream, 81920, cancellationToken).ConfigureAwait(false);
  162. return;
  163. }
  164. }
  165. await WriteTo(this.ResponseStream, responseStream, cancellationToken).ConfigureAwait(false);
  166. return;
  167. }
  168. if (this.ResponseText != null)
  169. {
  170. var bytes = Encoding.UTF8.GetBytes(this.ResponseText);
  171. if (response != null)
  172. response.SetContentLength(bytes.Length);
  173. await responseStream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
  174. return;
  175. }
  176. var bytesResponse = this.Response as byte[];
  177. if (bytesResponse != null)
  178. {
  179. if (response != null)
  180. response.SetContentLength(bytesResponse.Length);
  181. await responseStream.WriteAsync(bytesResponse, 0, bytesResponse.Length).ConfigureAwait(false);
  182. return;
  183. }
  184. ContentTypes.Instance.SerializeToStream(this.RequestContext, this.Response, responseStream);
  185. }
  186. private void DisposeStream()
  187. {
  188. try
  189. {
  190. if (ResponseStream != null)
  191. {
  192. this.ResponseStream.Dispose();
  193. }
  194. }
  195. catch { /*ignore*/ }
  196. }
  197. }
  198. }