forked from Code-Sharp/uHttpSharp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHttpRequestProvider.cs
More file actions
107 lines (89 loc) · 3.58 KB
/
Copy pathHttpRequestProvider.cs
File metadata and controls
107 lines (89 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using uhttpsharp.Headers;
namespace uhttpsharp.RequestProviders
{
public class HttpRequestProvider : IHttpRequestProvider
{
private static readonly char[] Separators = { '/' };
public async Task<IHttpRequest> Provide(StreamReader streamReader)
{
// parse the http request
var request = await streamReader.ReadLineAsync().ConfigureAwait(false);
if (request == null)
return null;
var firstSpace = request.IndexOf(' ');
var lastSpace = request.LastIndexOf(' ');
var tokens = new []
{
request.Substring(0, firstSpace),
request.Substring(firstSpace + 1, lastSpace - firstSpace - 1),
request.Substring(lastSpace + 1)
};
if (tokens.Length != 3)
{
return null;
}
var httpProtocol = tokens[2];
var url = tokens[1];
var queryString = GetQueryStringData(ref url);
var uri = new Uri(url, UriKind.Relative);
var headersRaw = new List<KeyValuePair<string, string>>();
// get the headers
string line;
while (!string.IsNullOrEmpty((line = await streamReader.ReadLineAsync().ConfigureAwait(false))))
{
string currentLine = line;
var headerKvp = SplitHeader(currentLine);
headersRaw.Add(headerKvp);
}
IHttpHeaders headers = new HttpHeaders(headersRaw.ToDictionary(k => k.Key, k => k.Value, StringComparer.InvariantCultureIgnoreCase));
IHttpPost post = await GetPostData(streamReader, headers).ConfigureAwait(false);
string verb;
if (!headers.TryGetByName("_method", out verb))
{
verb = tokens[0];
}
var httpMethod = HttpMethodProvider.Default.Provide(verb);
return new HttpRequest(headers, httpMethod, httpProtocol, uri,
uri.OriginalString.Split(Separators, StringSplitOptions.RemoveEmptyEntries), queryString, post);
}
private static IHttpHeaders GetQueryStringData(ref string url)
{
var queryStringIndex = url.IndexOf('?');
IHttpHeaders queryString;
if (queryStringIndex != -1)
{
queryString = new QueryStringHttpHeaders(url.Substring(queryStringIndex + 1));
url = url.Substring(0, queryStringIndex);
}
else
{
queryString = EmptyHttpHeaders.Empty;
}
return queryString;
}
private static async Task<IHttpPost> GetPostData(StreamReader streamReader, IHttpHeaders headers)
{
int postContentLength;
IHttpPost post;
if (headers.TryGetByName("content-length", out postContentLength) && postContentLength > 0)
{
post = await HttpPost.Create(streamReader, postContentLength).ConfigureAwait(false);
}
else
{
post = EmptyHttpPost.Empty;
}
return post;
}
private KeyValuePair<string, string> SplitHeader(string header)
{
var index = header.IndexOf(": ", StringComparison.InvariantCultureIgnoreCase);
return new KeyValuePair<string, string>(header.Substring(0, index), header.Substring(index + 2));
}
}
}