Commit a6956ee1 authored by Honfika's avatar Honfika

common read request/response method

parent d4426436
...@@ -3,6 +3,7 @@ using System.Collections.Generic; ...@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using StreamExtended.Network;
using Titanium.Web.Proxy.Decompression; using Titanium.Web.Proxy.Decompression;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
...@@ -21,6 +22,8 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -21,6 +22,8 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary> /// </summary>
public class SessionEventArgs : EventArgs, IDisposable public class SessionEventArgs : EventArgs, IDisposable
{ {
private static readonly byte[] emptyData = new byte[0];
/// <summary> /// <summary>
/// Size of Buffers used by this object /// Size of Buffers used by this object
/// </summary> /// </summary>
...@@ -144,37 +147,12 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -144,37 +147,12 @@ namespace Titanium.Web.Proxy.EventArguments
//If not already read (not cached yet) //If not already read (not cached yet)
if (!request.IsBodyRead) if (!request.IsBodyRead)
{ {
//If chunked then its easy just read the whole body with the content length mentioned in the request header var body = await ReadBody(ProxyClient.ClientStreamReader, request.IsChunked, request.ContentLength, request.ContentEncoding);
using (var bodyStream = new MemoryStream()) request.Body = body;
{
var streamReader = ProxyClient.ClientStreamReader;
//For chunked request we need to read data as they arrive, until we reach a chunk end symbol
if (request.IsChunked)
{
await streamReader.CopyBytesToStreamChunked(bodyStream);
}
else
{
//If not chunked then its easy just read the whole body with the content length mentioned in the request header
if (request.ContentLength > 0)
{
//If not chunked then its easy just read the amount of bytes mentioned in content length header of response
await streamReader.CopyBytesToStream(bodyStream, request.ContentLength);
}
else if (request.HttpVersion == HttpHeader.Version10)
{
await streamReader.CopyBytesToStream(bodyStream, long.MaxValue);
}
}
request.Body = await GetDecompressedResponseBody(request.ContentEncoding, bodyStream.ToArray());
}
//Now set the flag to true //Now set the flag to true
//So that next time we can deliver body from cache //So that next time we can deliver body from cache
request.IsBodyRead = true; request.IsBodyRead = true;
var body = request.Body;
OnDataSent(body, 0, body.Length); OnDataSent(body, 0, body.Length);
} }
} }
...@@ -215,48 +193,47 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -215,48 +193,47 @@ namespace Titanium.Web.Proxy.EventArguments
} }
var response = WebSession.Response; var response = WebSession.Response;
if (!response.HasBody)
{
return;
}
//If not already read (not cached yet) //If not already read (not cached yet)
if (!response.IsBodyRead) if (!response.IsBodyRead)
{ {
if (response.HasBody) var body = await ReadBody(WebSession.ServerConnection.StreamReader, response.IsChunked, response.ContentLength, response.ContentEncoding);
response.Body = body;
//Now set the flag to true
//So that next time we can deliver body from cache
response.IsBodyRead = true;
OnDataReceived(body, 0, body.Length);
}
}
private async Task<byte[]> ReadBody(CustomBinaryReader streamReader, bool isChunked, long contentLength, string contentEncoding)
{ {
//If chunked then its easy just read the whole body with the content length mentioned in the header
using (var bodyStream = new MemoryStream()) using (var bodyStream = new MemoryStream())
{ {
var streamReader = WebSession.ServerConnection.StreamReader;
//For chunked request we need to read data as they arrive, until we reach a chunk end symbol //For chunked request we need to read data as they arrive, until we reach a chunk end symbol
if (response.IsChunked) if (isChunked)
{ {
await streamReader.CopyBytesToStreamChunked(bodyStream); await streamReader.CopyBytesToStreamChunked(bodyStream);
} }
else else
{ {
//If not chunked then its easy just read the whole body with the content length mentioned in the request header //http 1.0
if (response.ContentLength > 0) if (contentLength == -1)
{
//If not chunked then its easy just read the amount of bytes mentioned in content length header of response
await streamReader.CopyBytesToStream(bodyStream, response.ContentLength);
}
else if (response.HttpVersion == HttpHeader.Version10 || response.ContentLength == -1)
{ {
await streamReader.CopyBytesToStream(bodyStream, long.MaxValue); contentLength = long.MaxValue;
}
} }
response.Body = await GetDecompressedResponseBody(response.ContentEncoding, bodyStream.ToArray()); //If not chunked then its easy just read the amount of bytes mentioned in content length header
} await streamReader.CopyBytesToStream(bodyStream, contentLength);
}
else
{
response.Body = new byte[0];
} }
//Now set the flag to true return await GetDecompressedBody(contentEncoding, bodyStream.ToArray());
//So that next time we can deliver body from cache
response.IsBodyRead = true;
var body = response.Body;
OnDataReceived(body, 0, body.Length);
} }
} }
...@@ -409,12 +386,12 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -409,12 +386,12 @@ namespace Titanium.Web.Proxy.EventArguments
await SetResponseBody(bodyBytes); await SetResponseBody(bodyBytes);
} }
private async Task<byte[]> GetDecompressedResponseBody(string encodingType, byte[] responseBodyStream) private async Task<byte[]> GetDecompressedBody(string encodingType, byte[] bodyStream)
{ {
var decompressionFactory = new DecompressionFactory(); var decompressionFactory = new DecompressionFactory();
var decompressor = decompressionFactory.Create(encodingType); var decompressor = decompressionFactory.Create(encodingType);
return await decompressor.Decompress(responseBodyStream, bufferSize); return await decompressor.Decompress(bodyStream, bufferSize);
} }
/// <summary> /// <summary>
...@@ -503,7 +480,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -503,7 +480,7 @@ namespace Titanium.Web.Proxy.EventArguments
var response = new RedirectResponse(); var response = new RedirectResponse();
response.HttpVersion = WebSession.Request.HttpVersion; response.HttpVersion = WebSession.Request.HttpVersion;
response.Headers.AddHeader("Location", url); response.Headers.AddHeader("Location", url);
response.Body = new byte[0]; response.Body = emptyData;
await Respond(response); await Respond(response);
} }
......
...@@ -87,13 +87,13 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -87,13 +87,13 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns></returns> /// <returns></returns>
internal async Task WriteBodyAsync(byte[] data, bool isChunked) internal async Task WriteBodyAsync(byte[] data, bool isChunked)
{ {
if (!isChunked) if (isChunked)
{ {
await WriteAsync(data); await WriteBodyChunkedAsync(data);
} }
else else
{ {
await WriteBodyChunkedAsync(data); await WriteAsync(data);
} }
} }
...@@ -107,7 +107,13 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -107,7 +107,13 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns></returns> /// <returns></returns>
internal async Task CopyBodyAsync(CustomBinaryReader streamReader, bool isChunked, long contentLength) internal async Task CopyBodyAsync(CustomBinaryReader streamReader, bool isChunked, long contentLength)
{ {
if (!isChunked) if (isChunked)
{
//Need to revist, find any potential bugs
//send the body bytes to server in chunks
await CopyBodyChunkedAsync(streamReader);
}
else
{ {
//http 1.0 //http 1.0
if (contentLength == -1) if (contentLength == -1)
...@@ -117,12 +123,6 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -117,12 +123,6 @@ namespace Titanium.Web.Proxy.Helpers
await CopyBytesFromStream(streamReader, contentLength); await CopyBytesFromStream(streamReader, contentLength);
} }
else
{
//Need to revist, find any potential bugs
//send the body bytes to server in chunks
await CopyBodyChunkedAsync(streamReader);
}
} }
/// <summary> /// <summary>
......
...@@ -61,9 +61,17 @@ namespace Titanium.Web.Proxy.Http ...@@ -61,9 +61,17 @@ namespace Titanium.Web.Proxy.Http
{ {
get get
{ {
long contentLength = ContentLength;
//If content length is set to 0 the response has no body
if (contentLength == 0)
{
return false;
}
//Has body only if response is chunked or content length >0 //Has body only if response is chunked or content length >0
//If none are true then check if connection:close header exist, if so write response until server or client terminates the connection //If none are true then check if connection:close header exist, if so write response until server or client terminates the connection
if (IsChunked || ContentLength > 0 || !KeepAlive) if (IsChunked || contentLength > 0 || !KeepAlive)
{ {
return true; return true;
} }
...@@ -119,8 +127,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -119,8 +127,7 @@ namespace Titanium.Web.Proxy.Http
return -1; return -1;
} }
long.TryParse(headerValue, out long contentLen); if (long.TryParse(headerValue, out long contentLen))
if (contentLen >= 0)
{ {
return contentLen; return contentLen;
} }
......
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