Commit 23119af4 authored by Shani Elharrar's avatar Shani Elharrar

Merge pull request #6 from shanielh/RawPost

Lazy parsing of post body, Expose raw post body in the request. 
parents 1dc869a7 97154d8d

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "uhttpsharp.Demo", "uhttpsharp-demo\uhttpsharp.Demo.csproj", "{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "uhttpsharp", "uhttpsharp\uhttpsharp.csproj", "{3D681959-4DA3-4A71-A68B-704D6411D5EA}"
......@@ -32,16 +30,6 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Debug|Any CPU.ActiveCfg = Debug|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Debug|Mixed Platforms.Build.0 = Debug|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Debug|x86.ActiveCfg = Debug|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Debug|x86.Build.0 = Debug|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Release|Any CPU.ActiveCfg = Release|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Release|Mixed Platforms.ActiveCfg = Release|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Release|Mixed Platforms.Build.0 = Release|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Release|x86.ActiveCfg = Release|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Release|x86.Build.0 = Release|x86
{3D681959-4DA3-4A71-A68B-704D6411D5EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3D681959-4DA3-4A71-A68B-704D6411D5EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3D681959-4DA3-4A71-A68B-704D6411D5EA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
......@@ -62,6 +50,22 @@ Global
{41C9BDAC-21BE-4C50-933D-9E047F767E63}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{41C9BDAC-21BE-4C50-933D-9E047F767E63}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{41C9BDAC-21BE-4C50-933D-9E047F767E63}.Release|x86.ActiveCfg = Release|Any CPU
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Debug|Any CPU.ActiveCfg = Debug|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Debug|Any CPU.Build.0 = Debug|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Debug|Mixed Platforms.Build.0 = Debug|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Debug|x86.ActiveCfg = Debug|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Debug|x86.Build.0 = Debug|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Release|Any CPU.ActiveCfg = Release|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Release|Mixed Platforms.ActiveCfg = Release|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Release|Mixed Platforms.Build.0 = Release|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Release|x86.ActiveCfg = Release|x86
{55C5E8D2-F55E-4B9F-B96F-FCE201739D07}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = uhttpsharp-demo\uhttpsharp.Demo.csproj
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......
......@@ -5,9 +5,99 @@ using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Security.AccessControl;
namespace uhttpsharp.Headers
{
internal class EmptyHttpPost : IHttpPost
{
private static readonly byte[] _emptyBytes = new byte[0];
public static readonly IHttpPost Empty = new EmptyHttpPost();
private EmptyHttpPost()
{
}
#region IHttpPost implementation
public byte[] Raw
{
get
{
return _emptyBytes;
}
}
public IHttpHeaders Parsed
{
get
{
return EmptyHttpHeaders.Empty;
}
}
#endregion
}
internal class HttpPost : IHttpPost
{
public static async Task<IHttpPost> Create(StreamReader reader, int postContentLength)
{
char[] rawEncoded = new char[postContentLength];
int readBytes = await reader.ReadAsync(rawEncoded, 0, rawEncoded.Length);
byte[] raw = Encoding.UTF8.GetBytes(rawEncoded, 0, readBytes);
return new HttpPost(raw, readBytes);
}
private readonly int _readBytes;
private readonly byte[] _raw;
private readonly Lazy<IHttpHeaders> _parsed;
public HttpPost(byte[] raw, int readBytes)
{
_raw = raw;
_readBytes = readBytes;
_parsed = new Lazy<IHttpHeaders>(Parse);
}
private IHttpHeaders Parse()
{
string body = Encoding.UTF8.GetString(_raw, 0, _readBytes);
var parsed = new QueryStringHttpHeaders(body);
return parsed;
}
#region IHttpPost implementation
public byte[] Raw
{
get
{
return _raw;
}
}
public IHttpHeaders Parsed
{
get
{
return _parsed.Value;
}
}
#endregion
}
[DebuggerDisplay("{Count} Headers")]
[DebuggerTypeProxy(typeof(HttpHeadersDebuggerProxy))]
internal class HttpHeaders : IHttpHeaders
......@@ -38,16 +128,6 @@ namespace uhttpsharp.Headers
return GetEnumerator();
}
public static async Task<IHttpHeaders> FromPost(StreamReader reader, int postContentLength)
{
byte[] buffer = new byte[postContentLength];
var readBytes = await reader.BaseStream.ReadAsync(buffer, 0, postContentLength);
string body = Encoding.UTF8.GetString(buffer, 0, readBytes);
return new QueryStringHttpHeaders(body);
}
internal int Count
{
......
......@@ -22,8 +22,12 @@ namespace uhttpsharp.Headers
for (int i = 0; i < splittedKeyValues.Length; i += 2)
{
var key = Uri.UnescapeDataString(splittedKeyValues[i]);
var value = Uri.UnescapeDataString(splittedKeyValues[i + 1]).Replace('+', ' ');
string value = null;
if (splittedKeyValues.Length > i + 1)
{
value = Uri.UnescapeDataString(splittedKeyValues[i + 1]).Replace('+', ' ');
}
values[key] = value;
}
......
......@@ -33,9 +33,9 @@ namespace uhttpsharp
private readonly Uri _uri;
private readonly string[] _requestParameters;
private readonly IHttpHeaders _queryString;
private readonly IHttpHeaders _post;
private readonly IHttpPost _post;
public HttpRequest(IHttpHeaders headers, HttpMethods method, string protocol, Uri uri, string[] requestParameters, IHttpHeaders queryString, IHttpHeaders post)
public HttpRequest(IHttpHeaders headers, HttpMethods method, string protocol, Uri uri, string[] requestParameters, IHttpHeaders queryString, IHttpPost post)
{
_headers = headers;
_method = method;
......@@ -71,7 +71,7 @@ namespace uhttpsharp
get { return _requestParameters; }
}
public IHttpHeaders Post
public IHttpPost Post
{
get { return _post; }
}
......@@ -108,10 +108,18 @@ namespace uhttpsharp
string[] RequestParameters { get; }
IHttpHeaders Post { get; }
IHttpPost Post {get;}
IHttpHeaders QueryString { get; }
}
public interface IHttpPost
{
byte[] Raw {get;}
IHttpHeaders Parsed {get;}
}
......
......@@ -43,7 +43,7 @@ namespace uhttpsharp.RequestProviders
}
IHttpHeaders headers = new HttpHeaders(headersRaw);
IHttpHeaders post = await GetPostData(streamReader, headers);
IHttpPost post = await GetPostData(streamReader, headers);
return new HttpRequest(headers, httpMethod, httpProtocol, uri,
uri.OriginalString.Split(Separators, StringSplitOptions.RemoveEmptyEntries), queryString, post);
......@@ -64,17 +64,17 @@ namespace uhttpsharp.RequestProviders
return queryString;
}
private static async Task<IHttpHeaders> GetPostData(StreamReader streamReader, IHttpHeaders headers)
private static async Task<IHttpPost> GetPostData(StreamReader streamReader, IHttpHeaders headers)
{
int postContentLength;
IHttpHeaders post;
IHttpPost post;
if (headers.TryGetByName("content-length", out postContentLength))
{
post = await HttpHeaders.FromPost(streamReader, postContentLength);
post = await HttpPost.Create(streamReader, postContentLength);
}
else
{
post = EmptyHttpHeaders.Empty;
post = EmptyHttpPost.Empty;
}
return post;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment