165 lines
5.6 KiB
C#
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();
|
|
}
|
|
}
|
|
} |