ln.http/ln.http/HttpRequest.cs

165 lines
5.6 KiB
C#

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using ln.protocols.helper;
using ln.rtp;
namespace ln.http
{ public class HttpRequest : IDisposable
{
public Request BaseRequest { get; }
public HTTPServer Server { get; }
public String Protocol => BaseRequest.Protocol;
public HttpMethod Method { get; }
public IPAddress ClientAddress { get; }
public String Host { get; }
public int Port { get; }
public bool TLS { get; }
public HeaderContainer Headers => BaseRequest.Headers;
public QueryStringParameters Query { get; private set; }
public Stream ContentStream => BaseRequest.ContentStream;
public Stream ConnectionStream => BaseRequest.ContentStream.BaseStream;
public Uri BaseUri { get; }
public Uri RequestUri { get; }
Dictionary<String, String> requestCookies;
Dictionary<string, String> requestParameters;
public HttpRequest(HTTPServer httpServer, Request baseRequest)
{
Server = httpServer;
BaseRequest = baseRequest;
if (Enum.TryParse(BaseRequest.Method, out HttpMethod httpMethod))
Method = httpMethod;
else
Method = HttpMethod.UNKOWN;
Headers.TryGetValue("Host", out string host);
if (Headers.TryGetValue("X-Forwarded-Host", out string forwardedHost))
host = forwardedHost;
if (Headers.TryGetValue("X-Forwarded-For", out string forwardedFor))
ClientAddress = IPAddress.Parse(forwardedFor.ReadToken(','));
if (Headers.TryGetValue("X-Forwarded-Proto", out string forwardedProto))
TLS = forwardedProto.Equals("https");
if (Headers.TryGetValue("Forwarded", out string forwarded))
{
// ToDo: Implement parser
}
int colon = host.IndexOf(':');
if (colon != -1)
{
Host = host.Substring(0, colon).Trim();
Port = int.Parse(host.Substring(colon + 1).Trim());
}
else
{
Host = host.Trim();
}
BaseUri = new UriBuilder(TLS ? "https:" : "http:", Host, Port).Uri;
RequestUri = new Uri(BaseUri, BaseRequest.RequestUri);
Query = new QueryStringParameters(RequestUri.Query);
if (Headers.TryGetValue("Cookie", out string cookies))
SetupCookies(cookies);
}
private void SetupCookies(string cookies)
{
foreach (String cookie in cookies.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
{
string[] c = cookie.Split(new char[] { '=' }, 2);
string cn, cv;
cn = c[0].Trim();
if (c.Length > 1)
cv = c[1].Trim();
else
cv = "";
if (!this.requestCookies.ContainsKey(cn))
this.requestCookies.Add(cn, cv);
}
}
public override string ToString()
{
//return string.Format("[HttpRequest: RemoteEndpoint={0}, Hostname={1} Port={2} URI={4}, Method={4}, RequestURL={5}, Protocol={6} Query={7}]", RemoteEndpoint, URI, Method, RequestURL, Protocol, Hostname, Port,Query);
return base.ToString();
}
public String GetRequestHeader(String name)
{
return GetRequestHeader(name, "");
}
public String GetRequestHeader(String name, String def)
{
if (Headers.TryGetValue(name, out string value))
return value;
return def;
}
public String[] CookieNames => requestCookies.Keys.ToArray();
public bool ContainsCookie(String name) => this.requestCookies.ContainsKey(name);
public String GetCookie(String name) => requestCookies[name];
public bool TryGetCookie(string cookieName, out string cookieValue) =>
requestCookies.TryGetValue(cookieName, out cookieValue);
public bool ContainsParameter(string parameterName) => requestParameters.ContainsKey(parameterName);
public String GetParameter(String parameterName) => GetParameter(parameterName, null);
public String GetParameter(String parameterName, String defaultValue)
{
if (!requestParameters.TryGetValue(parameterName, out string value))
value = defaultValue;
return value;
}
public void SetParameter(String parameterName, String parameterValue) =>
requestParameters[parameterName] = parameterValue;
public IEnumerable<string> ParameterNames => requestParameters.Keys;
public HttpResponse Redirect(string location, params object[] p) => Redirect(303, location, p);
public HttpResponse Redirect(int status, string location, params object[] p)
{
location = string.Format(location, p);
HttpResponse response = new HttpResponse(this);
response.StatusCode = status;
response.SetHeader("location", location);
return response;
}
public HttpResponse Redirect(HttpStatusCode statusCode, string location, params object[] p)
{
if (p?.Length > 0)
location = string.Format(location, p);
HttpResponse response = new HttpResponse(statusCode);
response.SetHeader("Location", location);
return response;
}
public void Dispose()
{
ContentStream?.Dispose();
}
}
}