HttpRequestHeaders.cs
/*
* All intellectual rights of this framework, including this source file belong to Appicacy, René Vaessen. * Customers of Appicacy, may copy and change it, as long as this header remains. * */ using GenXdev.Buffers; using Ninject; using System.Text; namespace GenXdev.AsyncSockets.Containers { public unsafe class HttpRequestHeaders : IHttpRequestHeaders { UTF8Encoding UTF8Encoding = new UTF8Encoding(false); public Uri Location { get; private set; } public bool IsValidRequest { get; private set; } public DynamicBuffer HeadersBuffer { get; private set; } public void Reset() { HeadersBuffer.Reset(); } public void Init(bool isHttps, int HttpsListeningPort, int HttpListeningPort, DynamicBuffer RequestBuffer, int Length) { // store references this.IsValidRequest = true; // get headers Reset(); RequestBuffer.MoveTo(HeadersBuffer, Length); try { // set location Uri SetLocation(isHttps, HttpsListeningPort, HttpListeningPort); } catch (HTTPRequestHeadersBadRequestException) { this.IsValidRequest = false; } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposing) { HeadersBuffer.Dispose(); } } ~HttpRequestHeaders() { Dispose(false); } public HttpRequestHeaders(IKernel Kernel) { // store references this.IsValidRequest = false; this.HeadersBuffer = Kernel.Get<DynamicBuffer>(); } // make sure HeaderName parameter is lowercase! public string this[string HeaderName] { get { // find end of opening int start = HeadersBuffer.IndexOf((byte)'\r'); // start there and keep going while (start > 0 && start < HeadersBuffer.Count - 1) { // find end http header name int endNameIdx = HeadersBuffer.IndexOf((byte)':', start + 1); // get http header name var endName = HeadersBuffer.ToString(UTF8Encoding, endNameIdx - start, start).Trim("\r\n ".ToCharArray()); // match? if (endName.ToLowerInvariant() == HeaderName) { // find end int endIdx = HeadersBuffer.IndexOf((byte)'\r', endNameIdx); // or default to end of buffer endIdx = endIdx < 0 ? HeadersBuffer.Count : endIdx; // get value return HeadersBuffer.ToString( UTF8Encoding, (endIdx - endNameIdx) - 1, endNameIdx + 1 ).Trim("\r\n ".ToCharArray()); } if (endNameIdx < 0) { start = HeadersBuffer.IndexOf((byte)'\r', start + 1); continue; } // find next start = HeadersBuffer.IndexOf((byte)'\r', endNameIdx); } return String.Empty; } } string GetMainHeaderSection(int section) { int i = HeadersBuffer.IndexOf((byte)'\r'); if (i > 0) { return HeadersBuffer.ToString(UTF8Encoding, i).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[section]; } return String.Empty; } public string HttpVersion { get { return GetMainHeaderSection(2).ToUpper(); } } public string Method { get { return GetMainHeaderSection(0).ToUpper(); } } void SetLocation(bool isHttps, int HttpsListeningPort, int HttpListeningPort) { string location = GetMainHeaderSection(1); string host = this["host"]; if (host == "") host = "localhost"; if (host.Contains(":")) host = host.Substring(0, host.IndexOf(":")); try { if (location.Contains("://")) { Location = new Uri(location, UriKind.Absolute); } else { if (isHttps) { Location = new Uri("https://" + host + ":" + HttpsListeningPort.ToString() + location, UriKind.Absolute); } else { Location = new Uri("http://" + host + ":" + HttpListeningPort.ToString() + location, UriKind.Absolute); } } } catch (Exception e) { throw new HTTPRequestHeadersBadRequestException("Bad Request", e); } } } [Serializable] public class HTTPRequestHeadersBadRequestException : Exception { public HTTPRequestHeadersBadRequestException(String Message, Exception InnerException = null) : base(Message, InnerException) { } }; } |