Commit d4426436 authored by Honfika's avatar Honfika

Flush the writer before writing to the base stream, http request/response...

Flush the writer before writing to the base stream, http request/response first line is created in a single method
parent 9927f5b6
...@@ -162,7 +162,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -162,7 +162,7 @@ namespace Titanium.Web.Proxy.EventArguments
//If not chunked then its easy just read the amount of bytes mentioned in content length header of response //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); await streamReader.CopyBytesToStream(bodyStream, request.ContentLength);
} }
else if (request.HttpVersion.Major == 1 && request.HttpVersion.Minor == 0) else if (request.HttpVersion == HttpHeader.Version10)
{ {
await streamReader.CopyBytesToStream(bodyStream, long.MaxValue); await streamReader.CopyBytesToStream(bodyStream, long.MaxValue);
} }
...@@ -238,8 +238,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -238,8 +238,7 @@ namespace Titanium.Web.Proxy.EventArguments
//If not chunked then its easy just read the amount of bytes mentioned in content length header of response //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); await streamReader.CopyBytesToStream(bodyStream, response.ContentLength);
} }
else if (response.HttpVersion.Major == 1 && response.HttpVersion.Minor == 0 || else if (response.HttpVersion == HttpHeader.Version10 || response.ContentLength == -1)
response.ContentLength == -1)
{ {
await streamReader.CopyBytesToStream(bodyStream, long.MaxValue); await streamReader.CopyBytesToStream(bodyStream, long.MaxValue);
} }
......
using System; using System;
using System.Globalization;
using System.IO; using System.IO;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using StreamExtended.Network;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
namespace Titanium.Web.Proxy.Helpers namespace Titanium.Web.Proxy.Helpers
...@@ -38,7 +34,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -38,7 +34,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns></returns> /// <returns></returns>
public Task WriteResponseStatusAsync(Version version, int code, string description) public Task WriteResponseStatusAsync(Version version, int code, string description)
{ {
return WriteLineAsync($"HTTP/{version.Major}.{version.Minor} {code} {description}"); return WriteLineAsync(Response.CreateResponseLine(version, code, description));
} }
} }
} }
...@@ -89,7 +89,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -89,7 +89,7 @@ namespace Titanium.Web.Proxy.Helpers
{ {
if (!isChunked) if (!isChunked)
{ {
await BaseStream.WriteAsync(data, 0, data.Length); await WriteAsync(data);
} }
else else
{ {
...@@ -115,7 +115,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -115,7 +115,7 @@ namespace Titanium.Web.Proxy.Helpers
contentLength = long.MaxValue; contentLength = long.MaxValue;
} }
await streamReader.CopyBytesToStream(BaseStream, contentLength); await CopyBytesFromStream(streamReader, contentLength);
} }
else else
{ {
...@@ -157,9 +157,10 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -157,9 +157,10 @@ namespace Titanium.Web.Proxy.Helpers
await WriteLineAsync(chunkHead); await WriteLineAsync(chunkHead);
if (chunkSize != 0) if (chunkSize != 0)
{ {
await reader.CopyBytesToStream(BaseStream, chunkSize); await CopyBytesFromStream(reader, chunkSize);
} }
await WriteLineAsync(); await WriteLineAsync();
...@@ -173,5 +174,11 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -173,5 +174,11 @@ namespace Titanium.Web.Proxy.Helpers
} }
} }
} }
private async Task CopyBytesFromStream(CustomBinaryReader reader, long count)
{
await FlushAsync();
await reader.CopyBytesToStream(BaseStream, count);
}
} }
} }
...@@ -90,14 +90,9 @@ namespace Titanium.Web.Proxy.Http ...@@ -90,14 +90,9 @@ namespace Titanium.Web.Proxy.Http
bool useUpstreamProxy = upstreamProxy != null && ServerConnection.IsHttps == false; bool useUpstreamProxy = upstreamProxy != null && ServerConnection.IsHttps == false;
//prepare the request & headers //prepare the request & headers
if (useUpstreamProxy) writer.WriteLine(Request.CreateRequestLine(Request.Method,
{ useUpstreamProxy ? Request.OriginalUrl : Request.RequestUri.PathAndQuery,
writer.WriteLine($"{Request.Method} {Request.OriginalUrl} HTTP/{Request.HttpVersion.Major}.{Request.HttpVersion.Minor}"); Request.HttpVersion));
}
else
{
writer.WriteLine($"{Request.Method} {Request.RequestUri.PathAndQuery} HTTP/{Request.HttpVersion.Major}.{Request.HttpVersion.Minor}");
}
//Send Authentication to Upstream proxy if needed //Send Authentication to Upstream proxy if needed
......
...@@ -275,7 +275,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -275,7 +275,7 @@ namespace Titanium.Web.Proxy.Http
get get
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.AppendLine($"{Method} {OriginalUrl} HTTP/{HttpVersion.Major}.{HttpVersion.Minor}"); sb.AppendLine(CreateRequestLine(Method, OriginalUrl, HttpVersion));
foreach (var header in Headers) foreach (var header in Headers)
{ {
sb.AppendLine(header.ToString()); sb.AppendLine(header.ToString());
...@@ -286,6 +286,11 @@ namespace Titanium.Web.Proxy.Http ...@@ -286,6 +286,11 @@ namespace Titanium.Web.Proxy.Http
} }
} }
internal static string CreateRequestLine(string httpMethod, string httpUrl, Version version)
{
return $"{httpMethod} {httpUrl} HTTP/{version.Major}.{version.Minor}";
}
internal static void ParseRequestLine(string httpCmd, out string httpMethod, out string httpUrl, out Version version) internal static void ParseRequestLine(string httpCmd, out string httpMethod, out string httpUrl, out Version version)
{ {
//break up the line into three components (method, remote URL & Http Version) //break up the line into three components (method, remote URL & Http Version)
......
...@@ -47,7 +47,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -47,7 +47,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary> /// <summary>
/// Http version /// Http version
/// </summary> /// </summary>
public Version HttpVersion { get; set; } public Version HttpVersion { get; set; } = HttpHeader.VersionUnknown;
/// <summary> /// <summary>
/// Keeps the response body data after the session is finished /// Keeps the response body data after the session is finished
...@@ -70,7 +70,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -70,7 +70,7 @@ namespace Titanium.Web.Proxy.Http
//has response if connection:keep-alive header exist and when version is http/1.0 //has response if connection:keep-alive header exist and when version is http/1.0
//Because in Http 1.0 server can return a response without content-length (expectation being client would read until end of stream) //Because in Http 1.0 server can return a response without content-length (expectation being client would read until end of stream)
if (KeepAlive && HttpVersion.Minor == 0) if (KeepAlive && HttpVersion == HttpHeader.Version10)
{ {
return true; return true;
} }
...@@ -228,7 +228,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -228,7 +228,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary> /// <summary>
/// Gets the resposne status. /// Gets the resposne status.
/// </summary> /// </summary>
public string Status => $"HTTP/{HttpVersion?.Major}.{HttpVersion?.Minor} {StatusCode} {StatusDescription}"; public string Status => CreateResponseLine(HttpVersion, StatusCode, StatusDescription);
/// <summary> /// <summary>
/// Gets the header text. /// Gets the header text.
...@@ -249,6 +249,11 @@ namespace Titanium.Web.Proxy.Http ...@@ -249,6 +249,11 @@ namespace Titanium.Web.Proxy.Http
} }
} }
internal static string CreateResponseLine(Version version, int statusCode, string statusDescription)
{
return $"HTTP/{version.Major}.{version.Minor} {statusCode} {statusDescription}";
}
internal static void ParseResponseLine(string httpStatus, out Version version, out int statusCode, out string statusDescription) internal static void ParseResponseLine(string httpStatus, out Version version, out int statusCode, out string statusDescription)
{ {
var httpResult = httpStatus.Split(ProxyConstants.SpaceSplit, 3); var httpResult = httpStatus.Split(ProxyConstants.SpaceSplit, 3);
......
...@@ -10,6 +10,8 @@ namespace Titanium.Web.Proxy.Models ...@@ -10,6 +10,8 @@ namespace Titanium.Web.Proxy.Models
/// </summary> /// </summary>
public class HttpHeader public class HttpHeader
{ {
internal static readonly Version VersionUnknown = new Version(0, 0);
internal static readonly Version Version10 = new Version(1, 0); internal static readonly Version Version10 = new Version(1, 0);
internal static readonly Version Version11 = new Version(1, 1); internal static readonly Version Version11 = new Version(1, 1);
......
...@@ -707,7 +707,7 @@ namespace Titanium.Web.Proxy ...@@ -707,7 +707,7 @@ namespace Titanium.Web.Proxy
if (bufferDataLength == buffer.Length) if (bufferDataLength == buffer.Length)
{ {
//boundary is not longer than 70 bytes accounrding to the specification, so keeping the last 100 (minimum 74) bytes is enough //boundary is not longer than 70 bytes according to the specification, so keeping the last 100 (minimum 74) bytes is enough
const int bytesToKeep = 100; const int bytesToKeep = 100;
await outputStream.WriteAsync(buffer, 0, buffer.Length - bytesToKeep); await outputStream.WriteAsync(buffer, 0, buffer.Length - bytesToKeep);
Buffer.BlockCopy(buffer, buffer.Length - bytesToKeep, buffer, 0, bytesToKeep); Buffer.BlockCopy(buffer, buffer.Length - bytesToKeep, buffer, 0, bytesToKeep);
......
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