ln.http/ln.http/HttpResponse.cs

202 lines
7.6 KiB
C#

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
namespace ln.http
{
public class HttpResponse
{
public Stream ContentStream { get; private set; }
public TextWriter ContentWriter { get; private set; }
public bool HasCustomContentStream { get; private set; }
Dictionary<string, List<String>> headers = new Dictionary<string, List<string>>();
List<HttpCookie> cookies = new List<HttpCookie>();
public HttpResponse() : this(HttpStatusCode.OK)
{
}
public HttpResponse(HttpStatusCode statusCode)
{
HttpStatusCode = statusCode;
ContentStream = new MemoryStream();
ContentWriter = new StreamWriter(ContentStream);
SetHeader("content-type", "text/html");
}
[Obsolete]
public HttpResponse(HttpRequest httpRequest) : this() { }
[Obsolete]
public HttpResponse(HttpRequest httpRequest,string contentType) : this(contentType) { }
public HttpResponse(string contentType)
:this()
{
SetHeader("content-type", contentType);
}
[Obsolete]
public HttpResponse(HttpRequest httpRequest, Stream contentStream) : this(contentStream) { }
public HttpResponse(Stream contentStream)
{
ContentStream = contentStream;
ContentWriter = null;
HasCustomContentStream = true;
HttpStatusCode = HttpStatusCode.OK;
SetHeader("content-type", "text/html");
}
[Obsolete]
public HttpResponse(HttpRequest httpRequest, Stream contentStream,string contentType) : this(contentStream, contentType){ }
public HttpResponse(Stream contentStream,string contentType)
:this(contentStream)
{
SetHeader("content-type", contentType);
}
public String GetHeader(string name) => GetHeader(name, null);
public String GetHeader(string name, string defValue)
{
return headers.ContainsKey(name) ? String.Join(",", headers[name.ToUpper()]) : defValue;
}
public String[] GetHeaderValues(string name)
{
return headers[name.ToUpper()].ToArray();
}
public String[] GetHeaderNames()
{
return headers.Keys.ToArray();
}
public void SetHeader(String name, String value)
{
name = name.ToUpper();
headers[name] = new List<string>();
headers[name].Add(value);
}
public void AddHeader(String name, String value)
{
name = name.ToUpper();
if (!headers.ContainsKey(name))
headers[name] = new List<string>();
headers[name].Add(value);
}
public void RemoveHeader(String name) => headers.Remove(name.ToUpper());
public bool ContainsHeader(string headerName) => headers.ContainsKey(headerName.ToUpper());
public void AddCookie(string name,string value)
{
AddCookie(new HttpCookie(name, value));
}
public void AddCookie(HttpCookie httpCookie) => cookies.Add(httpCookie);
public void RemoveCookie(HttpCookie httpCookie) => cookies.Remove(httpCookie);
public HttpCookie[] Cookies => cookies.ToArray();
public HttpStatusCode HttpStatusCode { get; set; }
[Obsolete]
public int StatusCode
{
get => (int)HttpStatusCode;
set => HttpStatusCode = (HttpStatusCode)value;
}
[Obsolete]
public String StatusMessage
{
get => HttpStatusCode.ToString();
}
public HttpResponse Header(string name,string value)
{
SetHeader(name, value);
return this;
}
public HttpResponse ContentType(string contentType)
{
SetHeader("content-type", contentType);
return this;
}
public static HttpResponse OK() => new HttpResponse(HttpStatusCode.OK);
public static HttpResponse Created() => new HttpResponse(HttpStatusCode.Created);
public static HttpResponse Accepted() => new HttpResponse(HttpStatusCode.Accepted);
public static HttpResponse NoContent() => new HttpResponse(HttpStatusCode.NoContent);
public static HttpResponse MultiStatus() =>
new HttpResponse(HttpStatusCode.MultiStatus).Header("content-type", "application/xml");
public static HttpResponse MovedPermanently() => new HttpResponse(HttpStatusCode.MovedPermanently);
public static HttpResponse TemporaryRedirect() => new HttpResponse(HttpStatusCode.TemporaryRedirect);
public static HttpResponse PermanentRedirect() => new HttpResponse(HttpStatusCode.PermanentRedirect);
public static HttpResponse NotFound() => new HttpResponse(HttpStatusCode.NotFound);
public static HttpResponse BadRequest() => new HttpResponse(HttpStatusCode.BadRequest);
public static HttpResponse Unauthorized() => new HttpResponse(HttpStatusCode.Unauthorized);
public static HttpResponse Forbidden() => new HttpResponse(HttpStatusCode.Forbidden);
public static HttpResponse MethodNotAllowed() => new HttpResponse(HttpStatusCode.MethodNotAllowed);
public static HttpResponse RequestTimeout() => new HttpResponse(HttpStatusCode.RequestTimeout);
public static HttpResponse Conflict() => new HttpResponse(HttpStatusCode.Conflict);
public static HttpResponse UnsupportedMediaType() => new HttpResponse(HttpStatusCode.UnsupportedMediaType);
public static HttpResponse ImATeapot() => new HttpResponse(HttpStatusCode.ImATeapot);
public static HttpResponse UpgradeRequired() => new HttpResponse(HttpStatusCode.UpgradeRequired);
public static HttpResponse InternalServerError() => new HttpResponse(HttpStatusCode.InternalServerError);
public static HttpResponse NotImplemented() => new HttpResponse(HttpStatusCode.NotImplemented);
public static HttpResponse BadGateway() => new HttpResponse(HttpStatusCode.BadGateway);
public static HttpResponse ServiceUnavailable() => new HttpResponse(HttpStatusCode.ServiceUnavailable);
public static HttpResponse GatewayTimeout() => new HttpResponse(HttpStatusCode.GatewayTimeout);
public HttpResponse Content(Exception exception)
{
SetHeader("content-type", "text/plain");
ContentWriter.WriteLine("{0}", exception);
ContentWriter.Flush();
return this;
}
public HttpResponse Content(string text)
{
ContentWriter.Write(text);
ContentWriter.Flush();
return this;
}
public virtual void WriteTo(Stream stream)
{
SetHeader("Content-Length", ContentStream.Length.ToString());
StreamWriter streamWriter = new StreamWriter(stream) {NewLine = "\r\n"};
streamWriter.WriteLine("{0} {1} {2}", "HTTP/1.1", (int)HttpStatusCode, HttpStatusCode.ToString());
foreach (String headerName in GetHeaderNames())
{
streamWriter.WriteLine("{0}: {1}", headerName, GetHeader(headerName));
}
foreach (HttpCookie httpCookie in Cookies)
{
streamWriter.WriteLine("Set-Cookie: {0}", httpCookie.ToString());
}
streamWriter.WriteLine();
streamWriter.Flush();
ContentStream.Position = 0;
ContentStream.CopyTo(stream);
ContentStream.Close();
ContentStream.Dispose();
stream.Flush();
}
}
}