Advertisement
kema

HttpReques

Oct 12th, 2017
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.28 KB | None | 0 0
  1. namespace MyWebServer.Server.Http
  2. {
  3.     using Common;
  4.     using Contracts;
  5.     using Exceptions;
  6.     using System;
  7.     using System.Collections.Generic;
  8.     using System.Linq;
  9.     using System.Net;
  10.     using MyWebServer.Server.Enums;
  11.  
  12.     public class HttpReques : IHttpRequest
  13.     {
  14.         private readonly string requestText;
  15.  
  16.         public HttpReques(string requestText)
  17.         {
  18.             CoreValidator.ThrowIfNullOrEmpty(requestText, nameof(requestText));
  19.  
  20.             this.requestText = requestText;
  21.  
  22.             this.FormData = new Dictionary<string, string>();
  23.             this.QueryParameters = new Dictionary<string, string>();
  24.             this.UrlParameters = new Dictionary<string, string>();
  25.             this.Headers = new HttpHeaderCollection();
  26.             this.Cookies = new HttpCookieCollection();
  27.  
  28.             this.ParseRequest(requestText);
  29.  
  30.         }
  31.  
  32.  
  33.         public IDictionary<string, string> FormData { get; private set; }
  34.  
  35.         public IHttpHeaderCollection Headers { get; private set; }
  36.  
  37.         public IHttpCookieCollection Cookies { get; private set; }
  38.  
  39.         public string Path { get; private set; }
  40.  
  41.        public IDictionary<string, string> QueryParameters { get; private set; }
  42.  
  43.         public HttpRequestMethod Method { get; private set; }
  44.  
  45.         public string Url { get; private set; }
  46.  
  47.         public IDictionary<string, string> UrlParameters { get; private set; }
  48.  
  49.         public IHttpSession Session { get; set; }
  50.        
  51.         public void AddUrlParameter(string key, string value)
  52.         {
  53.             CoreValidator.ThrowIfNullOrEmpty(key, nameof(key));
  54.             CoreValidator.ThrowIfNullOrEmpty(value, nameof(value));
  55.  
  56.             this.UrlParameters[key] = value;
  57.         }
  58.  
  59.         private void ParseRequest(string requestText)
  60.         {
  61.             var requestLines = requestText.Split(Environment.NewLine);
  62.  
  63.             if (!requestLines.Any())
  64.             {
  65.                 BadRequestException.ThrowFromInvalidRequest();
  66.             }
  67.  
  68.             var requestLine = requestLines.First().Split(
  69.                 new[] { ' ' },
  70.                 StringSplitOptions.RemoveEmptyEntries);
  71.  
  72.             if (requestLine.Length != 3 || requestLine[2].ToLower() != "http/1.1")
  73.             {
  74.                 BadRequestException.ThrowFromInvalidRequest();
  75.             }
  76.  
  77.             this.Method = this.ParseMethod(requestLine.First());
  78.             this.Url = requestLine[1];
  79.             this.Path = this.ParsePath(this.Url);
  80.  
  81.             this.ParseHeaders(requestLines);
  82.             this.ParseCookies();
  83.             this.ParseParameters();
  84.             this.ParseFormData(requestLines.Last());
  85.  
  86.             this.SetSession();
  87.         }
  88.  
  89.         private HttpRequestMethod ParseMethod(string method)
  90.         {
  91.             HttpRequestMethod parsedMethod;
  92.             if (!Enum.TryParse(method, true, out parsedMethod))
  93.             {
  94.                 BadRequestException.ThrowFromInvalidRequest();
  95.             }
  96.  
  97.             return parsedMethod;
  98.         }
  99.  
  100.  
  101.         private string ParsePath(string url)
  102.         => url.Split(new char[] { '?', '#' }, StringSplitOptions.RemoveEmptyEntries)[0];
  103.        
  104.  
  105.         private void ParseHeaders(string[] requestLines)
  106.         {
  107.             var emptyLineAfteHeadersIndex = Array.IndexOf(requestLines, string.Empty);
  108.  
  109.             for (int i = 1; i < emptyLineAfteHeadersIndex; i++)
  110.             {
  111.                 var currentLine = requestLines[i];
  112.                 var headerParts = currentLine.Split(new [] { ": " }, StringSplitOptions.RemoveEmptyEntries);
  113.  
  114.                 if (headerParts.Length !=2)
  115.                 {
  116.                     BadRequestException.ThrowFromInvalidRequest();
  117.                 }
  118.  
  119.                 var headerKey = headerParts[0];
  120.                 var headerValue = headerParts[1].Trim();
  121.  
  122.                 var header = new HttpHeader(headerKey, headerValue);
  123.  
  124.                 this.Headers.Add(header);  
  125.             }
  126.  
  127.             if (!this.Headers.ContainsKey(HttpHeader.Host))
  128.             {
  129.                 BadRequestException.ThrowFromInvalidRequest();
  130.             }
  131.         }
  132.  
  133.  
  134.         private void ParseCookies()
  135.         {
  136.             if (this.Headers.ContainsKey(HttpHeader.Cookie))
  137.             {
  138.                 var allCookies = this.Headers.Get(HttpHeader.Cookie);
  139.  
  140.                 foreach (var cookie in allCookies)
  141.                 {
  142.                     if (!cookie.Value.Contains('='))
  143.                     {
  144.                         return;
  145.                     }
  146.                     var cookieParts = cookie
  147.                         .Value
  148.                         .Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries)
  149.                         .ToList();
  150.  
  151.                     if (!cookieParts.Any())
  152.                     {
  153.                         continue;
  154.                     }
  155.  
  156.                     foreach (var cookiePart in cookieParts)
  157.                     {
  158.                         var cookieKeyValuePAir = cookiePart
  159.                        .Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
  160.  
  161.                         if (cookieKeyValuePAir.Length == 2)
  162.                         {
  163.                             var key = cookieKeyValuePAir[0].Trim();
  164.                             var value = cookieKeyValuePAir[1].Trim();
  165.  
  166.                             this.Cookies.Add(new HttpCookie(key, value, false));
  167.                         }
  168.                     }
  169.                 }
  170.             }
  171.         }
  172.  
  173.         private void ParseParameters()
  174.         {
  175.             if (!this.Url.Contains('?'))
  176.             {
  177.                 return;
  178.             }
  179.  
  180.  
  181.             var query = this.Url
  182.                 .Split(new char[] { '?' }, StringSplitOptions.RemoveEmptyEntries)
  183.                 .Last();
  184.  
  185.             this.ParseQuery(query, this.UrlParameters);
  186.         }
  187.  
  188.         private void ParseFormData(string formDataLine)
  189.         {
  190.             if (this.Method == HttpRequestMethod.Get)
  191.             {
  192.                 return;
  193.             }
  194.             this.ParseQuery(formDataLine, this.FormData);
  195.         }
  196.  
  197.         private void ParseQuery(string query, IDictionary<string, string> dict)
  198.         {
  199.  
  200.             if (!query.Contains('='))
  201.             {
  202.                 return;
  203.             }
  204.  
  205.             var queryPairs = query
  206.                 .Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
  207.  
  208.             foreach (var queryPair in queryPairs)
  209.             {
  210.                 var queryKvp = queryPair.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
  211.  
  212.                 if (queryKvp.Length != 2)
  213.                 {
  214.                     return;
  215.                 }
  216.  
  217.                 var queryKey = WebUtility.UrlDecode(queryKvp[0]);
  218.                 var queryValue = WebUtility.UrlDecode(queryKvp[1]);
  219.  
  220.                 dict.Add(queryKey, queryValue);
  221.             }
  222.         }
  223.  
  224.  
  225.         private void SetSession()
  226.         {
  227.             if (this.Cookies.ContainsKey(SessionStore.SessionCookieKey))
  228.             {
  229.                 var cookie = this.Cookies.Get(SessionStore.SessionCookieKey);
  230.                 var sessionId = cookie.Value;
  231.  
  232.                 this.Session = SessionStore.Get(sessionId);
  233.             }
  234.         }
  235.  
  236.         public override string ToString() => this.requestText;
  237.        
  238.     }
  239. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement