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
//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.Major == 1 && request.HttpVersion.Minor == 0)
else if (request.HttpVersion == HttpHeader.Version10)
{
await streamReader.CopyBytesToStream(bodyStream, long.MaxValue);
}
......@@ -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
await streamReader.CopyBytesToStream(bodyStream, response.ContentLength);
}
else if (response.HttpVersion.Major == 1 && response.HttpVersion.Minor == 0 ||
response.ContentLength == -1)
else if (response.HttpVersion == HttpHeader.Version10 || response.ContentLength == -1)
{
await streamReader.CopyBytesToStream(bodyStream, long.MaxValue);
}
......
using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using StreamExtended.Network;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Http;
namespace Titanium.Web.Proxy.Helpers
......@@ -38,7 +34,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns></returns>
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
{
if (!isChunked)
{
await BaseStream.WriteAsync(data, 0, data.Length);
await WriteAsync(data);
}
else
{
......@@ -115,7 +115,7 @@ namespace Titanium.Web.Proxy.Helpers
contentLength = long.MaxValue;
}
await streamReader.CopyBytesToStream(BaseStream, contentLength);
await CopyBytesFromStream(streamReader, contentLength);
}
else
{
......@@ -157,9 +157,10 @@ namespace Titanium.Web.Proxy.Helpers
await WriteLineAsync(chunkHead);
if (chunkSize != 0)
{
await reader.CopyBytesToStream(BaseStream, chunkSize);
await CopyBytesFromStream(reader, chunkSize);
}
await WriteLineAsync();
......@@ -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
bool useUpstreamProxy = upstreamProxy != null && ServerConnection.IsHttps == false;
//prepare the request & headers
if (useUpstreamProxy)
{
writer.WriteLine($"{Request.Method} {Request.OriginalUrl} HTTP/{Request.HttpVersion.Major}.{Request.HttpVersion.Minor}");
}
else
{
writer.WriteLine($"{Request.Method} {Request.RequestUri.PathAndQuery} HTTP/{Request.HttpVersion.Major}.{Request.HttpVersion.Minor}");
}
writer.WriteLine(Request.CreateRequestLine(Request.Method,
useUpstreamProxy ? Request.OriginalUrl : Request.RequestUri.PathAndQuery,
Request.HttpVersion));
//Send Authentication to Upstream proxy if needed
......
......@@ -275,7 +275,7 @@ namespace Titanium.Web.Proxy.Http
get
{
var sb = new StringBuilder();
sb.AppendLine($"{Method} {OriginalUrl} HTTP/{HttpVersion.Major}.{HttpVersion.Minor}");
sb.AppendLine(CreateRequestLine(Method, OriginalUrl, HttpVersion));
foreach (var header in Headers)
{
sb.AppendLine(header.ToString());
......@@ -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)
{
//break up the line into three components (method, remote URL & Http Version)
......
......@@ -47,7 +47,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// Http version
/// </summary>
public Version HttpVersion { get; set; }
public Version HttpVersion { get; set; } = HttpHeader.VersionUnknown;
/// <summary>
/// Keeps the response body data after the session is finished
......@@ -70,7 +70,7 @@ namespace Titanium.Web.Proxy.Http
//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)
if (KeepAlive && HttpVersion.Minor == 0)
if (KeepAlive && HttpVersion == HttpHeader.Version10)
{
return true;
}
......@@ -228,7 +228,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary>
/// Gets the resposne status.
/// </summary>
public string Status => $"HTTP/{HttpVersion?.Major}.{HttpVersion?.Minor} {StatusCode} {StatusDescription}";
public string Status => CreateResponseLine(HttpVersion, StatusCode, StatusDescription);
/// <summary>
/// Gets the header text.
......@@ -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)
{
var httpResult = httpStatus.Split(ProxyConstants.SpaceSplit, 3);
......
......@@ -10,6 +10,8 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
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 Version11 = new Version(1, 1);
......
......@@ -707,7 +707,7 @@ namespace Titanium.Web.Proxy
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;
await outputStream.WriteAsync(buffer, 0, buffer.Length - 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