224 lines
8.2 KiB
C#
224 lines
8.2 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using ln.json;
|
|
using ln.json.mapping;
|
|
|
|
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)
|
|
{
|
|
Content(contentStream);
|
|
|
|
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 static HttpResponse Default(HttpMethod httpMethod)
|
|
{
|
|
switch (httpMethod)
|
|
{
|
|
case HttpMethod.DELETE:
|
|
return NoContent();
|
|
case HttpMethod.POST:
|
|
return Created();
|
|
default:
|
|
return OK();
|
|
}
|
|
}
|
|
|
|
|
|
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 HttpResponse Content(JSONValue json) => ContentType("application/json").Content(json.ToString());
|
|
|
|
public HttpResponse Content(Stream contentStream)
|
|
{
|
|
ContentStream = contentStream;
|
|
ContentWriter = null;
|
|
HasCustomContentStream = true;
|
|
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();
|
|
}
|
|
}
|
|
}
|