Commit 36be993a authored by Honfika's avatar Honfika

more cancellationtokens

parent 3aa4f2fd
......@@ -86,7 +86,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary>
/// Read request body content as bytes[] for current session
/// </summary>
private async Task ReadRequestBodyAsync()
private async Task ReadRequestBodyAsync(CancellationToken cancellationToken)
{
WebSession.Request.EnsureBodyAvailable(false);
......@@ -95,7 +95,7 @@ namespace Titanium.Web.Proxy.EventArguments
//If not already read (not cached yet)
if (!request.IsBodyRead)
{
var body = await ReadBodyAsync(true);
var body = await ReadBodyAsync(true, cancellationToken);
request.Body = body;
//Now set the flag to true
......@@ -108,10 +108,10 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary>
/// reinit response object
/// </summary>
internal async Task ClearResponse()
internal async Task ClearResponse(CancellationToken cancellationToken)
{
//syphon out the response body from server
await SyphonOutBodyAsync(false);
await SyphonOutBodyAsync(false, cancellationToken);
WebSession.Response = new Response();
}
......@@ -130,7 +130,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary>
/// Read response body as byte[] for current response
/// </summary>
private async Task ReadResponseBodyAsync()
private async Task ReadResponseBodyAsync(CancellationToken cancellationToken)
{
if (!WebSession.Request.Locked)
{
......@@ -146,7 +146,7 @@ namespace Titanium.Web.Proxy.EventArguments
//If not already read (not cached yet)
if (!response.IsBodyRead)
{
var body = await ReadBodyAsync(false);
var body = await ReadBodyAsync(false, cancellationToken);
response.Body = body;
//Now set the flag to true
......@@ -156,7 +156,7 @@ namespace Titanium.Web.Proxy.EventArguments
}
}
private async Task<byte[]> ReadBodyAsync(bool isRequest)
private async Task<byte[]> ReadBodyAsync(bool isRequest, CancellationToken cancellationToken)
{
using (var bodyStream = new MemoryStream())
{
......@@ -164,18 +164,18 @@ namespace Titanium.Web.Proxy.EventArguments
if (isRequest)
{
await CopyRequestBodyAsync(writer, TransformationMode.Uncompress);
await CopyRequestBodyAsync(writer, TransformationMode.Uncompress, cancellationToken);
}
else
{
await CopyResponseBodyAsync(writer, TransformationMode.Uncompress);
await CopyResponseBodyAsync(writer, TransformationMode.Uncompress, cancellationToken);
}
return bodyStream.ToArray();
}
}
internal async Task SyphonOutBodyAsync(bool isRequest)
internal async Task SyphonOutBodyAsync(bool isRequest, CancellationToken cancellationToken)
{
var requestResponse = isRequest ? (RequestResponseBase)WebSession.Request : WebSession.Response;
if (requestResponse.IsBodyRead || !requestResponse.OriginalHasBody)
......@@ -186,7 +186,7 @@ namespace Titanium.Web.Proxy.EventArguments
using (var bodyStream = new MemoryStream())
{
var writer = new HttpWriter(bodyStream, BufferSize);
await CopyBodyAsync(isRequest, writer, TransformationMode.None, null);
await CopyBodyAsync(isRequest, writer, TransformationMode.None, null, cancellationToken);
}
}
......@@ -194,7 +194,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// This is called when the request is PUT/POST/PATCH to read the body
/// </summary>
/// <returns></returns>
internal async Task CopyRequestBodyAsync(HttpWriter writer, TransformationMode transformation)
internal async Task CopyRequestBodyAsync(HttpWriter writer, TransformationMode transformation, CancellationToken cancellationToken)
{
var request = WebSession.Request;
......@@ -220,26 +220,26 @@ namespace Titanium.Web.Proxy.EventArguments
if (contentLength > copyStream.ReadBytes)
{
var headers = new HeaderCollection();
await HeaderParser.ReadHeaders(copyStreamReader, headers);
await HeaderParser.ReadHeaders(copyStreamReader, headers, cancellationToken);
OnMultipartRequestPartSent(boundary, headers);
}
}
await copyStream.FlushAsync();
await copyStream.FlushAsync(cancellationToken);
}
}
else
{
await CopyBodyAsync(true, writer, transformation, OnDataSent);
await CopyBodyAsync(true, writer, transformation, OnDataSent, cancellationToken);
}
}
internal async Task CopyResponseBodyAsync(HttpWriter writer, TransformationMode transformation)
internal async Task CopyResponseBodyAsync(HttpWriter writer, TransformationMode transformation, CancellationToken cancellationToken)
{
await CopyBodyAsync(false, writer, transformation, OnDataReceived);
await CopyBodyAsync(false, writer, transformation, OnDataReceived, cancellationToken);
}
private async Task CopyBodyAsync(bool isRequest, HttpWriter writer, TransformationMode transformation, Action<byte[], int, int> onCopy)
private async Task CopyBodyAsync(bool isRequest, HttpWriter writer, TransformationMode transformation, Action<byte[], int, int> onCopy, CancellationToken cancellationToken)
{
var stream = GetStream(isRequest);
var reader = GetStreamReader(isRequest);
......@@ -250,7 +250,7 @@ namespace Titanium.Web.Proxy.EventArguments
long contentLength = requestResponse.ContentLength;
if (transformation == TransformationMode.None)
{
await writer.CopyBodyAsync(reader, isChunked, contentLength, onCopy);
await writer.CopyBodyAsync(reader, isChunked, contentLength, onCopy, cancellationToken);
return;
}
......@@ -271,7 +271,7 @@ namespace Titanium.Web.Proxy.EventArguments
var bufStream = new CustomBufferedStream(s, BufferSize, true);
reader = new CustomBinaryReader(bufStream, BufferSize);
await writer.CopyBodyAsync(reader, false, -1, onCopy);
await writer.CopyBodyAsync(reader, false, -1, onCopy, cancellationToken);
}
finally
{
......@@ -349,11 +349,11 @@ namespace Titanium.Web.Proxy.EventArguments
/// Gets the request body as bytes
/// </summary>
/// <returns></returns>
public async Task<byte[]> GetRequestBody()
public async Task<byte[]> GetRequestBody(CancellationToken cancellationToken = default (CancellationToken))
{
if (!WebSession.Request.IsBodyRead)
{
await ReadRequestBodyAsync();
await ReadRequestBodyAsync(cancellationToken);
}
return WebSession.Request.Body;
......@@ -363,11 +363,11 @@ namespace Titanium.Web.Proxy.EventArguments
/// Gets the request body as string
/// </summary>
/// <returns></returns>
public async Task<string> GetRequestBodyAsString()
public async Task<string> GetRequestBodyAsString(CancellationToken cancellationToken = default(CancellationToken))
{
if (!WebSession.Request.IsBodyRead)
{
await ReadRequestBodyAsync();
await ReadRequestBodyAsync(cancellationToken);
}
return WebSession.Request.BodyString;
......@@ -406,11 +406,11 @@ namespace Titanium.Web.Proxy.EventArguments
/// Gets the response body as byte array
/// </summary>
/// <returns></returns>
public async Task<byte[]> GetResponseBody()
public async Task<byte[]> GetResponseBody(CancellationToken cancellationToken = default(CancellationToken))
{
if (!WebSession.Response.IsBodyRead)
{
await ReadResponseBodyAsync();
await ReadResponseBodyAsync(cancellationToken);
}
return WebSession.Response.Body;
......@@ -420,11 +420,11 @@ namespace Titanium.Web.Proxy.EventArguments
/// Gets the response body as string
/// </summary>
/// <returns></returns>
public async Task<string> GetResponseBodyAsString()
public async Task<string> GetResponseBodyAsString(CancellationToken cancellationToken = default(CancellationToken))
{
if (!WebSession.Response.IsBodyRead)
{
await ReadResponseBodyAsync();
await ReadResponseBodyAsync(cancellationToken);
}
return WebSession.Response.BodyString;
......
......@@ -62,7 +62,7 @@ namespace Titanium.Web.Proxy
HttpVersion = version
};
await HeaderParser.ReadHeaders(clientStreamReader, connectRequest.Headers);
await HeaderParser.ReadHeaders(clientStreamReader, connectRequest.Headers, cancellationTokenSource.Token);
var connectArgs = new TunnelConnectSessionEventArgs(BufferSize, endPoint, connectRequest,
cancellationTokenSource, ExceptionFunc);
......
......@@ -29,17 +29,17 @@ namespace Titanium.Web.Proxy.Helpers
public int BufferSize { get; }
public Task WriteLineAsync()
public Task WriteLineAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return WriteAsync(newLine);
return WriteAsync(newLine, cancellationToken: cancellationToken);
}
public Task WriteAsync(string value)
public Task WriteAsync(string value, CancellationToken cancellationToken = default (CancellationToken))
{
return WriteAsyncInternal(value, false);
return WriteAsyncInternal(value, false, cancellationToken);
}
private Task WriteAsyncInternal(string value, bool addNewLine)
private Task WriteAsyncInternal(string value, bool addNewLine, CancellationToken cancellationToken)
{
int newLineChars = addNewLine ? newLine.Length : 0;
int charCount = value.Length;
......@@ -57,7 +57,7 @@ namespace Titanium.Web.Proxy.Helpers
idx += newLineChars;
}
return WriteAsync(buffer, 0, idx);
return WriteAsync(buffer, 0, idx, cancellationToken);
}
finally
{
......@@ -77,13 +77,13 @@ namespace Titanium.Web.Proxy.Helpers
idx += newLineChars;
}
return WriteAsync(buffer, 0, idx);
return WriteAsync(buffer, 0, idx, cancellationToken);
}
}
public Task WriteLineAsync(string value)
public Task WriteLineAsync(string value, CancellationToken cancellationToken = default (CancellationToken))
{
return WriteAsyncInternal(value, true);
return WriteAsyncInternal(value, true, cancellationToken);
}
/// <summary>
......@@ -91,31 +91,32 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary>
/// <param name="headers"></param>
/// <param name="flush"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task WriteHeadersAsync(HeaderCollection headers, bool flush = true)
public async Task WriteHeadersAsync(HeaderCollection headers, bool flush = true, CancellationToken cancellationToken = default(CancellationToken))
{
foreach (var header in headers)
{
await header.WriteToStreamAsync(this);
}
await WriteLineAsync();
await WriteLineAsync(cancellationToken);
if (flush)
{
await FlushAsync();
await FlushAsync(cancellationToken);
}
}
public async Task WriteAsync(byte[] data, bool flush = false)
public async Task WriteAsync(byte[] data, bool flush = false, CancellationToken cancellationToken = default(CancellationToken))
{
await WriteAsync(data, 0, data.Length);
await WriteAsync(data, 0, data.Length, cancellationToken);
if (flush)
{
await FlushAsync();
await FlushAsync(cancellationToken);
}
}
public async Task WriteAsync(byte[] data, int offset, int count, bool flush, CancellationToken cancellationToken)
public async Task WriteAsync(byte[] data, int offset, int count, bool flush, CancellationToken cancellationToken = default (CancellationToken))
{
await WriteAsync(data, offset, count, cancellationToken);
if (flush)
......@@ -129,15 +130,16 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary>
/// <param name="data"></param>
/// <param name="isChunked"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
internal Task WriteBodyAsync(byte[] data, bool isChunked)
internal Task WriteBodyAsync(byte[] data, bool isChunked, CancellationToken cancellationToken)
{
if (isChunked)
{
return WriteBodyChunkedAsync(data);
return WriteBodyChunkedAsync(data, cancellationToken);
}
return WriteAsync(data);
return WriteAsync(data, cancellationToken: cancellationToken);
}
/// <summary>
......@@ -148,14 +150,15 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="isChunked"></param>
/// <param name="contentLength"></param>
/// <param name="onCopy"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
internal Task CopyBodyAsync(CustomBinaryReader streamReader, bool isChunked, long contentLength,
Action<byte[], int, int> onCopy)
Action<byte[], int, int> onCopy, CancellationToken cancellationToken)
{
//For chunked request we need to read data as they arrive, until we reach a chunk end symbol
if (isChunked)
{
return CopyBodyChunkedAsync(streamReader, onCopy);
return CopyBodyChunkedAsync(streamReader, onCopy, cancellationToken);
}
//http 1.0 or the stream reader limits the stream
......@@ -172,18 +175,19 @@ namespace Titanium.Web.Proxy.Helpers
/// Copies the given input bytes to output stream chunked
/// </summary>
/// <param name="data"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task WriteBodyChunkedAsync(byte[] data)
private async Task WriteBodyChunkedAsync(byte[] data, CancellationToken cancellationToken)
{
var chunkHead = Encoding.ASCII.GetBytes(data.Length.ToString("x2"));
await WriteAsync(chunkHead);
await WriteLineAsync();
await WriteAsync(data);
await WriteLineAsync();
await WriteAsync(chunkHead, cancellationToken: cancellationToken);
await WriteLineAsync(cancellationToken);
await WriteAsync(data, cancellationToken: cancellationToken);
await WriteLineAsync(cancellationToken);
await WriteLineAsync("0");
await WriteLineAsync();
await WriteLineAsync("0", cancellationToken);
await WriteLineAsync(cancellationToken);
}
/// <summary>
......@@ -191,12 +195,13 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary>
/// <param name="reader"></param>
/// <param name="onCopy"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task CopyBodyChunkedAsync(CustomBinaryReader reader, Action<byte[], int, int> onCopy)
private async Task CopyBodyChunkedAsync(CustomBinaryReader reader, Action<byte[], int, int> onCopy, CancellationToken cancellationToken)
{
while (true)
{
string chunkHead = await reader.ReadLineAsync();
string chunkHead = await reader.ReadLineAsync(cancellationToken);
int idx = chunkHead.IndexOf(";");
if (idx >= 0)
{
......@@ -205,17 +210,17 @@ namespace Titanium.Web.Proxy.Helpers
int chunkSize = int.Parse(chunkHead, NumberStyles.HexNumber);
await WriteLineAsync(chunkHead);
await WriteLineAsync(chunkHead, cancellationToken);
if (chunkSize != 0)
{
await CopyBytesFromStream(reader, chunkSize, onCopy);
}
await WriteLineAsync();
await WriteLineAsync(cancellationToken);
//chunk trail
await reader.ReadLineAsync();
await reader.ReadLineAsync(cancellationToken);
if (chunkSize == 0)
{
......@@ -263,15 +268,16 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary>
/// <param name="requestResponse"></param>
/// <param name="flush"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
protected async Task WriteAsync(RequestResponseBase requestResponse, bool flush = true)
protected async Task WriteAsync(RequestResponseBase requestResponse, bool flush = true, CancellationToken cancellationToken = default (CancellationToken))
{
var body = requestResponse.CompressBodyAndUpdateContentLength();
await WriteHeadersAsync(requestResponse.Headers, flush);
await WriteHeadersAsync(requestResponse.Headers, flush, cancellationToken);
if (body != null)
{
await WriteBodyAsync(body, requestResponse.IsChunked);
await WriteBodyAsync(body, requestResponse.IsChunked, cancellationToken);
}
}
}
......
using System;
using System.Threading;
using System.Threading.Tasks;
using StreamExtended.Network;
using Titanium.Web.Proxy.Shared;
......@@ -7,10 +8,10 @@ namespace Titanium.Web.Proxy.Http
{
internal static class HeaderParser
{
internal static async Task ReadHeaders(CustomBinaryReader reader, HeaderCollection headerCollection)
internal static async Task ReadHeaders(CustomBinaryReader reader, HeaderCollection headerCollection, CancellationToken cancellationToken)
{
string tmpLine;
while (!string.IsNullOrEmpty(tmpLine = await reader.ReadLineAsync()))
while (!string.IsNullOrEmpty(tmpLine = await reader.ReadLineAsync(cancellationToken)))
{
var header = tmpLine.Split(ProxyConstants.ColonSplit, 2);
headerCollection.AddHeader(header[0], header[1]);
......
using System;
using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Models;
......@@ -79,7 +80,7 @@ namespace Titanium.Web.Proxy.Http
/// Prepare and send the http(s) request
/// </summary>
/// <returns></returns>
internal async Task SendRequest(bool enable100ContinueBehaviour, bool isTransparent)
internal async Task SendRequest(bool enable100ContinueBehaviour, bool isTransparent, CancellationToken cancellationToken)
{
var upstreamProxy = ServerConnection.UpStreamProxy;
......@@ -90,7 +91,7 @@ namespace Titanium.Web.Proxy.Http
//prepare the request & headers
await writer.WriteLineAsync(Request.CreateRequestLine(Request.Method,
useUpstreamProxy || isTransparent ? Request.OriginalUrl : Request.RequestUri.PathAndQuery,
Request.HttpVersion));
Request.HttpVersion), cancellationToken);
//Send Authentication to Upstream proxy if needed
......@@ -113,13 +114,13 @@ namespace Titanium.Web.Proxy.Http
}
}
await writer.WriteLineAsync();
await writer.WriteLineAsync(cancellationToken);
if (enable100ContinueBehaviour)
{
if (Request.ExpectContinue)
{
string httpStatus = await ServerConnection.StreamReader.ReadLineAsync();
string httpStatus = await ServerConnection.StreamReader.ReadLineAsync(cancellationToken);
Response.ParseResponseLine(httpStatus, out _, out int responseStatusCode,
out string responseStatusDescription);
......@@ -129,13 +130,13 @@ namespace Titanium.Web.Proxy.Http
&& responseStatusDescription.EqualsIgnoreCase("continue"))
{
Request.Is100Continue = true;
await ServerConnection.StreamReader.ReadLineAsync();
await ServerConnection.StreamReader.ReadLineAsync(cancellationToken);
}
else if (responseStatusCode == (int)HttpStatusCode.ExpectationFailed
&& responseStatusDescription.EqualsIgnoreCase("expectation failed"))
{
Request.ExpectationFailed = true;
await ServerConnection.StreamReader.ReadLineAsync();
await ServerConnection.StreamReader.ReadLineAsync(cancellationToken);
}
}
}
......@@ -145,7 +146,7 @@ namespace Titanium.Web.Proxy.Http
/// Receive and parse the http response from server
/// </summary>
/// <returns></returns>
internal async Task ReceiveResponse()
internal async Task ReceiveResponse(CancellationToken cancellationToken)
{
//return if this is already read
if (Response.StatusCode != 0)
......@@ -153,7 +154,7 @@ namespace Titanium.Web.Proxy.Http
return;
}
string httpStatus = await ServerConnection.StreamReader.ReadLineAsync();
string httpStatus = await ServerConnection.StreamReader.ReadLineAsync(cancellationToken);
if (httpStatus == null)
{
throw new IOException();
......@@ -161,7 +162,7 @@ namespace Titanium.Web.Proxy.Http
if (httpStatus == string.Empty)
{
httpStatus = await ServerConnection.StreamReader.ReadLineAsync();
httpStatus = await ServerConnection.StreamReader.ReadLineAsync(cancellationToken);
}
Response.ParseResponseLine(httpStatus, out var version, out int statusCode, out string statusDescription);
......@@ -177,10 +178,10 @@ namespace Titanium.Web.Proxy.Http
//Read the next line after 100-continue
Response.Is100Continue = true;
Response.StatusCode = 0;
await ServerConnection.StreamReader.ReadLineAsync();
await ServerConnection.StreamReader.ReadLineAsync(cancellationToken);
//now receive response
await ReceiveResponse();
await ReceiveResponse(cancellationToken);
return;
}
......@@ -190,15 +191,15 @@ namespace Titanium.Web.Proxy.Http
//read next line after expectation failed response
Response.ExpectationFailed = true;
Response.StatusCode = 0;
await ServerConnection.StreamReader.ReadLineAsync();
await ServerConnection.StreamReader.ReadLineAsync(cancellationToken);
//now receive response
await ReceiveResponse();
await ReceiveResponse(cancellationToken);
return;
}
//Read the response headers in to unique and non-unique header collections
await HeaderParser.ReadHeaders(ServerConnection.StreamReader, Response.Headers);
await HeaderParser.ReadHeaders(ServerConnection.StreamReader, Response.Headers, cancellationToken);
}
/// <summary>
......
using System.Net;
using System.Web;
namespace Titanium.Web.Proxy.Http.Responses
{
......@@ -15,9 +16,13 @@ namespace Titanium.Web.Proxy.Http.Responses
{
StatusCode = (int)status;
#if NET45
StatusDescription = HttpWorkerRequest.GetStatusDescription(StatusCode);
#else
//todo: this is not really correct, status description should contain spaces, too
//see: https://tools.ietf.org/html/rfc7231#section-6.1
StatusDescription = status.ToString();
#endif
}
/// <summary>
......
......@@ -74,19 +74,19 @@ namespace Titanium.Web.Proxy.Network.Tcp
if (useUpstreamProxy && (isConnect || isHttps))
{
var writer = new HttpRequestWriter(stream, proxyServer.BufferSize);
await writer.WriteLineAsync($"CONNECT {remoteHostName}:{remotePort} HTTP/{httpVersion}");
await writer.WriteLineAsync($"Host: {remoteHostName}:{remotePort}");
await writer.WriteLineAsync($"{KnownHeaders.Connection}: {KnownHeaders.ConnectionKeepAlive}");
await writer.WriteLineAsync($"CONNECT {remoteHostName}:{remotePort} HTTP/{httpVersion}", cancellationToken);
await writer.WriteLineAsync($"Host: {remoteHostName}:{remotePort}", cancellationToken);
await writer.WriteLineAsync($"{KnownHeaders.Connection}: {KnownHeaders.ConnectionKeepAlive}", cancellationToken);
if (!string.IsNullOrEmpty(externalProxy.UserName) && externalProxy.Password != null)
{
await HttpHeader.ProxyConnectionKeepAlive.WriteToStreamAsync(writer);
await writer.WriteLineAsync(KnownHeaders.ProxyAuthorization + ": Basic " +
Convert.ToBase64String(Encoding.UTF8.GetBytes(
externalProxy.UserName + ":" + externalProxy.Password)));
externalProxy.UserName + ":" + externalProxy.Password)), cancellationToken);
}
await writer.WriteLineAsync();
await writer.WriteLineAsync(cancellationToken);
using (var reader = new CustomBinaryReader(stream, proxyServer.BufferSize))
{
......
......@@ -56,20 +56,22 @@ namespace Titanium.Web.Proxy
while (true)
{
// read the request line
string httpCmd = await clientStreamReader.ReadLineAsync();
string httpCmd = await clientStreamReader.ReadLineAsync(cancellationTokenSource.Token);
if (httpCmd == "PRI * HTTP/2.0")
{
// HTTP/2 Connection Preface
string line = await clientStreamReader.ReadLineAsync();
string line = await clientStreamReader.ReadLineAsync(cancellationTokenSource.Token);
if (line != string.Empty) throw new Exception($"HTTP/2 Protocol violation. Empty string expected, '{line}' received");
line = await clientStreamReader.ReadLineAsync();
line = await clientStreamReader.ReadLineAsync(cancellationTokenSource.Token);
if (line != "SM") throw new Exception($"HTTP/2 Protocol violation. 'SM' expected, '{line}' received");
line = await clientStreamReader.ReadLineAsync();
line = await clientStreamReader.ReadLineAsync(cancellationTokenSource.Token);
if (line != string.Empty) throw new Exception($"HTTP/2 Protocol violation. Empty string expected, '{line}' received");
// todo
var buffer = new byte[1024];
await clientStreamReader.ReadBytesAsync(buffer, 0, 3, cancellationTokenSource.Token);
}
if (string.IsNullOrEmpty(httpCmd))
......@@ -91,7 +93,7 @@ namespace Titanium.Web.Proxy
out var version);
//Read the request headers in to unique and non-unique header collections
await HeaderParser.ReadHeaders(clientStreamReader, args.WebSession.Request.Headers);
await HeaderParser.ReadHeaders(clientStreamReader, args.WebSession.Request.Headers, cancellationTokenSource.Token);
Uri httpRemoteUri;
if (uriSchemeRegex.IsMatch(httpUrl))
......@@ -171,7 +173,7 @@ namespace Titanium.Web.Proxy
if (request.CancelRequest)
{
//syphon out the request body from client before setting the new body
await args.SyphonOutBodyAsync(true);
await args.SyphonOutBodyAsync(true, cancellationTokenSource.Token);
await HandleHttpSessionResponse(args);
......@@ -205,7 +207,7 @@ namespace Titanium.Web.Proxy
//prepare the prefix content
await connection.StreamWriter.WriteLineAsync(httpCmd);
await connection.StreamWriter.WriteHeadersAsync(request.Headers);
string httpStatus = await connection.StreamReader.ReadLineAsync();
string httpStatus = await connection.StreamReader.ReadLineAsync(cancellationTokenSource.Token);
Response.ParseResponseLine(httpStatus, out var responseVersion,
out int responseStatusCode,
......@@ -214,7 +216,7 @@ namespace Titanium.Web.Proxy
response.StatusCode = responseStatusCode;
response.StatusDescription = responseStatusDescription;
await HeaderParser.ReadHeaders(connection.StreamReader, response.Headers);
await HeaderParser.ReadHeaders(connection.StreamReader, response.Headers, cancellationTokenSource.Token);
if (!args.IsTransparent)
{
......@@ -287,6 +289,7 @@ namespace Titanium.Web.Proxy
{
try
{
var cancellationToken = args.CancellationTokenSource.Token;
var request = args.WebSession.Request;
request.Locked = true;
......@@ -297,7 +300,7 @@ namespace Titanium.Web.Proxy
if (request.ExpectContinue)
{
args.WebSession.SetConnection(connection);
await args.WebSession.SendRequest(Enable100ContinueBehaviour, args.IsTransparent);
await args.WebSession.SendRequest(Enable100ContinueBehaviour, args.IsTransparent, cancellationToken);
}
//If 100 continue was the response inform that to the client
......@@ -309,13 +312,13 @@ namespace Titanium.Web.Proxy
{
await clientStreamWriter.WriteResponseStatusAsync(args.WebSession.Response.HttpVersion,
(int)HttpStatusCode.Continue, "Continue");
await clientStreamWriter.WriteLineAsync();
await clientStreamWriter.WriteLineAsync(cancellationToken);
}
else if (request.ExpectationFailed)
{
await clientStreamWriter.WriteResponseStatusAsync(args.WebSession.Response.HttpVersion,
(int)HttpStatusCode.ExpectationFailed, "Expectation Failed");
await clientStreamWriter.WriteLineAsync();
await clientStreamWriter.WriteLineAsync(cancellationToken);
}
}
......@@ -323,7 +326,7 @@ namespace Titanium.Web.Proxy
if (!request.ExpectContinue)
{
args.WebSession.SetConnection(connection);
await args.WebSession.SendRequest(Enable100ContinueBehaviour, args.IsTransparent);
await args.WebSession.SendRequest(Enable100ContinueBehaviour, args.IsTransparent, cancellationToken);
}
//check if content-length is > 0
......@@ -332,7 +335,7 @@ namespace Titanium.Web.Proxy
if (request.IsBodyRead)
{
var writer = args.WebSession.ServerConnection.StreamWriter;
await writer.WriteBodyAsync(body, request.IsChunked);
await writer.WriteBodyAsync(body, request.IsChunked, cancellationToken);
}
else
{
......@@ -341,7 +344,7 @@ namespace Titanium.Web.Proxy
if (request.HasBody)
{
HttpWriter writer = args.WebSession.ServerConnection.StreamWriter;
await args.CopyRequestBodyAsync(writer, TransformationMode.None);
await args.CopyRequestBodyAsync(writer, TransformationMode.None, cancellationToken);
}
}
}
......
......@@ -22,8 +22,9 @@ namespace Titanium.Web.Proxy
{
try
{
var cancellationToken = args.CancellationTokenSource.Token;
//read response & headers from server
await args.WebSession.ReceiveResponse();
await args.WebSession.ReceiveResponse(cancellationToken);
var response = args.WebSession.Response;
args.ReRequest = false;
......@@ -61,7 +62,7 @@ namespace Titanium.Web.Proxy
if (!response.TerminateResponse)
{
//syphon out the response body from server before setting the new body
await args.SyphonOutBodyAsync(false);
await args.SyphonOutBodyAsync(false, cancellationToken);
}
else
{
......@@ -77,7 +78,7 @@ namespace Titanium.Web.Proxy
if (args.ReRequest)
{
//clear current response
await args.ClearResponse();
await args.ClearResponse(cancellationToken);
await HandleHttpSessionRequestInternal(args.WebSession.ServerConnection, args);
return;
}
......@@ -89,13 +90,13 @@ namespace Titanium.Web.Proxy
{
await clientStreamWriter.WriteResponseStatusAsync(response.HttpVersion,
(int)HttpStatusCode.Continue, "Continue");
await clientStreamWriter.WriteLineAsync();
await clientStreamWriter.WriteLineAsync(cancellationToken);
}
else if (response.ExpectationFailed)
{
await clientStreamWriter.WriteResponseStatusAsync(response.HttpVersion,
(int)HttpStatusCode.ExpectationFailed, "Expectation Failed");
await clientStreamWriter.WriteLineAsync();
await clientStreamWriter.WriteLineAsync(cancellationToken);
}
if (!args.IsTransparent)
......@@ -112,12 +113,12 @@ namespace Titanium.Web.Proxy
//Write back response status to client
await clientStreamWriter.WriteResponseStatusAsync(response.HttpVersion, response.StatusCode,
response.StatusDescription);
await clientStreamWriter.WriteHeadersAsync(response.Headers);
await clientStreamWriter.WriteHeadersAsync(response.Headers, cancellationToken: cancellationToken);
//Write body if exists
if (response.HasBody)
{
await args.CopyResponseBodyAsync(clientStreamWriter, TransformationMode.None);
await args.CopyResponseBodyAsync(clientStreamWriter, TransformationMode.None, cancellationToken);
}
}
}
......
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
<RootNamespace>Titanium.Web.Proxy</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
<RootNamespace>Titanium.Web.Proxy</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>StrongNameKey.snk</AssemblyOriginatorKeyFile>
<DelaySign>False</DelaySign>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<LangVersion>7.1</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Portable.BouncyCastle" Version="1.8.2" />
<PackageReference Include="StreamExtended" Version="1.0.147-beta" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.Win32.Registry">
<Version>4.4.0</Version>
</PackageReference>
<PackageReference Include="System.Security.Principal.Windows">
<Version>4.4.1</Version>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'">
<PackageReference Include="Microsoft.Win32.Registry">
<Version>4.4.0</Version>
</PackageReference>
<PackageReference Include="System.Security.Principal.Windows">
<Version>4.4.1</Version>
</PackageReference>
</ItemGroup>
<AssemblyOriginatorKeyFile>StrongNameKey.snk</AssemblyOriginatorKeyFile>
<DelaySign>False</DelaySign>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<LangVersion>7.1</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Portable.BouncyCastle" Version="1.8.2" />
<PackageReference Include="StreamExtended" Version="1.0.147-beta" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.Win32.Registry">
<Version>4.4.0</Version>
</PackageReference>
<PackageReference Include="System.Security.Principal.Windows">
<Version>4.4.1</Version>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'">
<PackageReference Include="Microsoft.Win32.Registry">
<Version>4.4.0</Version>
</PackageReference>
<PackageReference Include="System.Security.Principal.Windows">
<Version>4.4.1</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Reference Include="System.Web" />
</ItemGroup>
</Project>
\ No newline at end of file
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