kema

HttpReques class

Oct 10th, 2017
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.37 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.  
  27.             this.ParseRequest(requestText);
  28.  
  29.         }
  30.  
  31.  
  32.         public IDictionary<string, string> FormData { get; private set; }
  33.  
  34.         public IHttpHeaderCollection Headers { get; private set; }
  35.  
  36.         public string Path { get; private set; }
  37.  
  38.        public IDictionary<string, string> QueryParameters { get; private set; }
  39.  
  40.         public HttpRequestMethod Method { get; private set; }
  41.  
  42.         public string Url { get; private set; }
  43.  
  44.         public IDictionary<string, string> UrlParameters { get; private set; }
  45.  
  46.         //HttpRequestMethod IHttpRequest.Method => throw new NotImplementedException();
  47.  
  48.         public void AddUrlParameter(string key, string value)
  49.         {
  50.             CoreValidator.ThrowIfNullOrEmpty(key, nameof(key));
  51.             CoreValidator.ThrowIfNullOrEmpty(value, nameof(value));
  52.  
  53.             this.UrlParameters[key] = value;
  54.         }
  55.  
  56.         private void ParseRequest(string requestText)
  57.         {
  58.             var requestLines = requestText.Split(Environment.NewLine);
  59.  
  60.             if (!requestLines.Any())
  61.             {
  62.                 BadRequestException.ThrowFromInvalidRequest();
  63.             }
  64.  
  65.             var requestLine = requestLines.First().Split(
  66.                 new[] { ' ' },
  67.                 StringSplitOptions.RemoveEmptyEntries);
  68.  
  69.             if (requestLines.Length != 3 || requestLine[2].ToLower() != "http/1.1")
  70.             {
  71.                 BadRequestException.ThrowFromInvalidRequest();
  72.             }
  73.  
  74.             this.Method = this.ParseMethod(requestLine.First());
  75.             this.Url = requestLine[1];
  76.             this.Path = this.ParsePath(this.Url);
  77.  
  78.             this.ParseHeaders(requestLines);
  79.             this.ParseParameters();
  80.             this.ParseFormData(requestLines.Last());
  81.         }
  82.  
  83.         private HttpRequestMethod ParseMethod(string method)
  84.         {
  85.             HttpRequestMethod parsedMethod;
  86.             if (!Enum.TryParse(method, true, out parsedMethod))
  87.             {
  88.                 BadRequestException.ThrowFromInvalidRequest();
  89.             }
  90.  
  91.             return parsedMethod;
  92.         }
  93.  
  94.  
  95.         private string ParsePath(string url)
  96.         {
  97.             return url.Split(new char[] { '?', '#' }, StringSplitOptions.RemoveEmptyEntries)[0];
  98.         }
  99.  
  100.         private void ParseHeaders(string[] requestLines)
  101.         {
  102.             var emptyLineAfteHeadersIndex = Array.IndexOf(requestLines, string.Empty);
  103.  
  104.             for (int i = 1; i < emptyLineAfteHeadersIndex; i++)
  105.             {
  106.                 var currentLine = requestLines[i];
  107.                 var headerParts = currentLine.Split(new [] { ": " }, StringSplitOptions.RemoveEmptyEntries);
  108.  
  109.                 if (headerParts.Length !=2)
  110.                 {
  111.                     BadRequestException.ThrowFromInvalidRequest();
  112.                 }
  113.  
  114.                 var headerKey = headerParts[0];
  115.                 var headerValue = headerParts[1].Trim();
  116.  
  117.                 var header = new HttpHeader(headerKey, headerValue);
  118.  
  119.                 this.Headers.Add(header);  
  120.             }
  121.  
  122.             if (!this.Headers.ContainsKey("Host"))
  123.             {
  124.                 BadRequestException.ThrowFromInvalidRequest();
  125.             }
  126.         }
  127.  
  128.         private void ParseParameters()
  129.         {
  130.             if (!this.Url.Contains('?'))
  131.             {
  132.                 return;
  133.             }
  134.  
  135.  
  136.             var query = this.Url
  137.                 .Split(new char[] { '?' }, StringSplitOptions.RemoveEmptyEntries)
  138.                 .Last();
  139.  
  140.             this.ParseQuery(query, this.UrlParameters);
  141.         }
  142.  
  143.         private void ParseFormData(string formDataLine)
  144.         {
  145.             if (this.Method == HttpRequestMethod.Get)
  146.             {
  147.                 return;
  148.             }
  149.             this.ParseQuery(formDataLine, this.FormData);
  150.         }
  151.  
  152.         private void ParseQuery(string query, IDictionary<string, string> dict)
  153.         {
  154.  
  155.             if (!query.Contains('='))
  156.             {
  157.                 return;
  158.             }
  159.  
  160.             var queryPairs = query
  161.                 .Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
  162.  
  163.             foreach (var queryPair in queryPairs)
  164.             {
  165.                 var queryKvp = queryPair.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
  166.  
  167.                 if (query.Length != 2)
  168.                 {
  169.                     return;
  170.                 }
  171.  
  172.                 var queryKey = WebUtility.UrlDecode(queryKvp[0]);
  173.                 var queryValue = WebUtility.UrlDecode(queryKvp[1]);
  174.  
  175.                 dict.Add(queryKey, queryValue);
  176.             }
  177.         }
  178.  
  179.     }
  180. }
Advertisement
Add Comment
Please, Sign In to add comment