Commit 3114902b authored by justcoding121's avatar justcoding121

private methods => camelCase

parent 300f4f80
...@@ -41,7 +41,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -41,7 +41,7 @@ namespace Titanium.Web.Proxy.EventArguments
set => throw new NotSupportedException(); set => throw new NotSupportedException();
} }
private void GetNextChunk() private void getNextChunk()
{ {
if (readChunkTrail) if (readChunkTrail)
{ {
...@@ -96,7 +96,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -96,7 +96,7 @@ namespace Titanium.Web.Proxy.EventArguments
{ {
if (isChunked) if (isChunked)
{ {
GetNextChunk(); getNextChunk();
} }
else else
{ {
......
...@@ -69,12 +69,12 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -69,12 +69,12 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary> /// </summary>
public event EventHandler<MultipartRequestPartSentEventArgs> MultipartRequestPartSent; public event EventHandler<MultipartRequestPartSentEventArgs> MultipartRequestPartSent;
private ICustomStreamReader GetStreamReader(bool isRequest) private ICustomStreamReader getStreamReader(bool isRequest)
{ {
return isRequest ? ProxyClient.ClientStream : WebSession.ServerConnection.Stream; return isRequest ? ProxyClient.ClientStream : WebSession.ServerConnection.Stream;
} }
private HttpWriter GetStreamWriter(bool isRequest) private HttpWriter getStreamWriter(bool isRequest)
{ {
return isRequest ? (HttpWriter)ProxyClient.ClientStreamWriter : WebSession.ServerConnection.StreamWriter; return isRequest ? (HttpWriter)ProxyClient.ClientStreamWriter : WebSession.ServerConnection.StreamWriter;
} }
...@@ -82,7 +82,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -82,7 +82,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary> /// <summary>
/// Read request body content as bytes[] for current session /// Read request body content as bytes[] for current session
/// </summary> /// </summary>
private async Task ReadRequestBodyAsync(CancellationToken cancellationToken) private async Task readRequestBodyAsync(CancellationToken cancellationToken)
{ {
WebSession.Request.EnsureBodyAvailable(false); WebSession.Request.EnsureBodyAvailable(false);
...@@ -91,7 +91,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -91,7 +91,7 @@ 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)
{ {
var body = await ReadBodyAsync(true, cancellationToken); var body = await readBodyAsync(true, cancellationToken);
request.Body = body; request.Body = body;
// Now set the flag to true // Now set the flag to true
...@@ -126,7 +126,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -126,7 +126,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary> /// <summary>
/// Read response body as byte[] for current response /// Read response body as byte[] for current response
/// </summary> /// </summary>
private async Task ReadResponseBodyAsync(CancellationToken cancellationToken) private async Task readResponseBodyAsync(CancellationToken cancellationToken)
{ {
if (!WebSession.Request.Locked) if (!WebSession.Request.Locked)
{ {
...@@ -142,7 +142,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -142,7 +142,7 @@ namespace Titanium.Web.Proxy.EventArguments
// If not already read (not cached yet) // If not already read (not cached yet)
if (!response.IsBodyRead) if (!response.IsBodyRead)
{ {
var body = await ReadBodyAsync(false, cancellationToken); var body = await readBodyAsync(false, cancellationToken);
response.Body = body; response.Body = body;
// Now set the flag to true // Now set the flag to true
...@@ -152,7 +152,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -152,7 +152,7 @@ namespace Titanium.Web.Proxy.EventArguments
} }
} }
private async Task<byte[]> ReadBodyAsync(bool isRequest, CancellationToken cancellationToken) private async Task<byte[]> readBodyAsync(bool isRequest, CancellationToken cancellationToken)
{ {
using (var bodyStream = new MemoryStream()) using (var bodyStream = new MemoryStream())
{ {
...@@ -182,7 +182,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -182,7 +182,7 @@ namespace Titanium.Web.Proxy.EventArguments
using (var bodyStream = new MemoryStream()) using (var bodyStream = new MemoryStream())
{ {
var writer = new HttpWriter(bodyStream, BufferSize); var writer = new HttpWriter(bodyStream, BufferSize);
await CopyBodyAsync(isRequest, writer, TransformationMode.None, null, cancellationToken); await copyBodyAsync(isRequest, writer, TransformationMode.None, null, cancellationToken);
} }
} }
...@@ -199,14 +199,14 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -199,14 +199,14 @@ namespace Titanium.Web.Proxy.EventArguments
// send the request body bytes to server // send the request body bytes to server
if (contentLength > 0 && hasMulipartEventSubscribers && request.IsMultipartFormData) if (contentLength > 0 && hasMulipartEventSubscribers && request.IsMultipartFormData)
{ {
var reader = GetStreamReader(true); var reader = getStreamReader(true);
string boundary = HttpHelper.GetBoundaryFromContentType(request.ContentType); string boundary = HttpHelper.GetBoundaryFromContentType(request.ContentType);
using (var copyStream = new CopyStream(reader, writer, BufferSize)) using (var copyStream = new CopyStream(reader, writer, BufferSize))
{ {
while (contentLength > copyStream.ReadBytes) while (contentLength > copyStream.ReadBytes)
{ {
long read = await ReadUntilBoundaryAsync(copyStream, contentLength, boundary, cancellationToken); long read = await readUntilBoundaryAsync(copyStream, contentLength, boundary, cancellationToken);
if (read == 0) if (read == 0)
{ {
break; break;
...@@ -225,18 +225,18 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -225,18 +225,18 @@ namespace Titanium.Web.Proxy.EventArguments
} }
else else
{ {
await CopyBodyAsync(true, writer, transformation, OnDataSent, cancellationToken); await copyBodyAsync(true, writer, transformation, OnDataSent, cancellationToken);
} }
} }
internal async Task CopyResponseBodyAsync(HttpWriter writer, TransformationMode transformation, CancellationToken cancellationToken) internal async Task CopyResponseBodyAsync(HttpWriter writer, TransformationMode transformation, CancellationToken cancellationToken)
{ {
await CopyBodyAsync(false, writer, transformation, OnDataReceived, cancellationToken); await copyBodyAsync(false, writer, transformation, OnDataReceived, cancellationToken);
} }
private async Task CopyBodyAsync(bool isRequest, HttpWriter writer, TransformationMode transformation, Action<byte[], int, int> onCopy, CancellationToken cancellationToken) private async Task copyBodyAsync(bool isRequest, HttpWriter writer, TransformationMode transformation, Action<byte[], int, int> onCopy, CancellationToken cancellationToken)
{ {
var stream = GetStreamReader(isRequest); var stream = getStreamReader(isRequest);
var requestResponse = isRequest ? (RequestResponseBase)WebSession.Request : WebSession.Response; var requestResponse = isRequest ? (RequestResponseBase)WebSession.Request : WebSession.Response;
...@@ -280,7 +280,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -280,7 +280,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// Read a line from the byte stream /// Read a line from the byte stream
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private async Task<long> ReadUntilBoundaryAsync(ICustomStreamReader reader, long totalBytesToRead, string boundary, CancellationToken cancellationToken) private async Task<long> readUntilBoundaryAsync(ICustomStreamReader reader, long totalBytesToRead, string boundary, CancellationToken cancellationToken)
{ {
int bufferDataLength = 0; int bufferDataLength = 0;
...@@ -347,7 +347,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -347,7 +347,7 @@ namespace Titanium.Web.Proxy.EventArguments
{ {
if (!WebSession.Request.IsBodyRead) if (!WebSession.Request.IsBodyRead)
{ {
await ReadRequestBodyAsync(cancellationToken); await readRequestBodyAsync(cancellationToken);
} }
return WebSession.Request.Body; return WebSession.Request.Body;
...@@ -362,7 +362,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -362,7 +362,7 @@ namespace Titanium.Web.Proxy.EventArguments
{ {
if (!WebSession.Request.IsBodyRead) if (!WebSession.Request.IsBodyRead)
{ {
await ReadRequestBodyAsync(cancellationToken); await readRequestBodyAsync(cancellationToken);
} }
return WebSession.Request.BodyString; return WebSession.Request.BodyString;
...@@ -407,7 +407,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -407,7 +407,7 @@ namespace Titanium.Web.Proxy.EventArguments
{ {
if (!WebSession.Response.IsBodyRead) if (!WebSession.Response.IsBodyRead)
{ {
await ReadResponseBodyAsync(cancellationToken); await readResponseBodyAsync(cancellationToken);
} }
return WebSession.Response.Body; return WebSession.Response.Body;
...@@ -422,7 +422,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -422,7 +422,7 @@ namespace Titanium.Web.Proxy.EventArguments
{ {
if (!WebSession.Response.IsBodyRead) if (!WebSession.Response.IsBodyRead)
{ {
await ReadResponseBodyAsync(cancellationToken); await readResponseBodyAsync(cancellationToken);
} }
return WebSession.Response.BodyString; return WebSession.Response.BodyString;
......
using System;
namespace Titanium.Web.Proxy.Exceptions
{
/// <summary>
/// The server connection was closed.
/// </summary>
public class ServerConnectionException : ProxyException
{
internal ServerConnectionException(string message) : base(message)
{
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="message"></param>
/// <param name="e"></param>
internal ServerConnectionException(string message, Exception e) : base(message, e)
{
}
}
}
...@@ -29,7 +29,7 @@ namespace Titanium.Web.Proxy ...@@ -29,7 +29,7 @@ namespace Titanium.Web.Proxy
/// <param name="endPoint">The explicit endpoint.</param> /// <param name="endPoint">The explicit endpoint.</param>
/// <param name="clientConnection">The client connection.</param> /// <param name="clientConnection">The client connection.</param>
/// <returns>The task.</returns> /// <returns>The task.</returns>
private async Task HandleClient(ExplicitProxyEndPoint endPoint, TcpClientConnection clientConnection) private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnection clientConnection)
{ {
var cancellationTokenSource = new CancellationTokenSource(); var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token; var cancellationToken = cancellationTokenSource.Token;
...@@ -95,7 +95,7 @@ namespace Titanium.Web.Proxy ...@@ -95,7 +95,7 @@ namespace Titanium.Web.Proxy
return; return;
} }
if (await CheckAuthorization(connectArgs) == false) if (await checkAuthorization(connectArgs) == false)
{ {
await endPoint.InvokeBeforeTunnectConnectResponse(this, connectArgs, ExceptionFunc); await endPoint.InvokeBeforeTunnectConnectResponse(this, connectArgs, ExceptionFunc);
...@@ -136,7 +136,7 @@ namespace Titanium.Web.Proxy ...@@ -136,7 +136,7 @@ namespace Titanium.Web.Proxy
{ {
// test server HTTP/2 support // test server HTTP/2 support
// todo: this is a hack, because Titanium does not support HTTP protocol changing currently // todo: this is a hack, because Titanium does not support HTTP protocol changing currently
var connection = await GetServerConnection(connectArgs, true, var connection = await getServerConnection(connectArgs, true,
SslExtensions.Http2ProtocolAsList, cancellationToken); SslExtensions.Http2ProtocolAsList, cancellationToken);
http2Supproted = connection.NegotiatedApplicationProtocol == SslApplicationProtocol.Http2; http2Supproted = connection.NegotiatedApplicationProtocol == SslApplicationProtocol.Http2;
...@@ -201,7 +201,7 @@ namespace Titanium.Web.Proxy ...@@ -201,7 +201,7 @@ namespace Titanium.Web.Proxy
if (!decryptSsl || !isClientHello) if (!decryptSsl || !isClientHello)
{ {
// create new connection // create new connection
var connection = await GetServerConnection(connectArgs, true, var connection = await getServerConnection(connectArgs, true,
clientConnection.NegotiatedApplicationProtocol, cancellationToken); clientConnection.NegotiatedApplicationProtocol, cancellationToken);
if (isClientHello) if (isClientHello)
...@@ -266,7 +266,7 @@ namespace Titanium.Web.Proxy ...@@ -266,7 +266,7 @@ namespace Titanium.Web.Proxy
} }
// create new connection // create new connection
var connection = await GetServerConnection(connectArgs, true, SslExtensions.Http2ProtocolAsList, var connection = await getServerConnection(connectArgs, true, SslExtensions.Http2ProtocolAsList,
cancellationToken); cancellationToken);
await connection.StreamWriter.WriteLineAsync("PRI * HTTP/2.0", cancellationToken); await connection.StreamWriter.WriteLineAsync("PRI * HTTP/2.0", cancellationToken);
...@@ -285,24 +285,24 @@ namespace Titanium.Web.Proxy ...@@ -285,24 +285,24 @@ namespace Titanium.Web.Proxy
} }
// Now create the request // Now create the request
await HandleHttpSessionRequest(endPoint, clientConnection, clientStream, clientStreamWriter, await handleHttpSessionRequest(endPoint, clientConnection, clientStream, clientStreamWriter,
cancellationTokenSource, connectHostname, connectArgs?.WebSession.ConnectRequest); cancellationTokenSource, connectHostname, connectArgs?.WebSession.ConnectRequest);
} }
catch (ProxyException e) catch (ProxyException e)
{ {
OnException(clientStream, e); onException(clientStream, e);
} }
catch (IOException e) catch (IOException e)
{ {
OnException(clientStream, new Exception("Connection was aborted", e)); onException(clientStream, new Exception("Connection was aborted", e));
} }
catch (SocketException e) catch (SocketException e)
{ {
OnException(clientStream, new Exception("Could not connect", e)); onException(clientStream, new Exception("Could not connect", e));
} }
catch (Exception e) catch (Exception e)
{ {
OnException(clientStream, new Exception("Error occured in whilst handling the client", e)); onException(clientStream, new Exception("Error occured in whilst handling the client", e));
} }
finally finally
{ {
......
...@@ -13,11 +13,11 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -13,11 +13,11 @@ namespace Titanium.Web.Proxy.Extensions
foreach (var @delegate in invocationList) foreach (var @delegate in invocationList)
{ {
await InternalInvokeAsync((AsyncEventHandler<T>)@delegate, sender, args, exceptionFunc); await internalInvokeAsync((AsyncEventHandler<T>)@delegate, sender, args, exceptionFunc);
} }
} }
private static async Task InternalInvokeAsync<T>(AsyncEventHandler<T> callback, object sender, T args, private static async Task internalInvokeAsync<T>(AsyncEventHandler<T> callback, object sender, T args,
ExceptionHandler exceptionFunc) ExceptionHandler exceptionFunc)
{ {
try try
......
...@@ -43,7 +43,7 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -43,7 +43,7 @@ namespace Titanium.Web.Proxy.Extensions
// cancellation is not working on Socket ReadAsync // cancellation is not working on Socket ReadAsync
// https://github.com/dotnet/corefx/issues/15033 // https://github.com/dotnet/corefx/issues/15033
int num = await input.ReadAsync(buffer, 0, buffer.Length, CancellationToken.None) int num = await input.ReadAsync(buffer, 0, buffer.Length, CancellationToken.None)
.WithCancellation(cancellationToken); .withCancellation(cancellationToken);
int bytesRead; int bytesRead;
if ((bytesRead = num) != 0 && !cancellationToken.IsCancellationRequested) if ((bytesRead = num) != 0 && !cancellationToken.IsCancellationRequested)
{ {
...@@ -62,7 +62,7 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -62,7 +62,7 @@ namespace Titanium.Web.Proxy.Extensions
} }
} }
private static async Task<T> WithCancellation<T>(this Task<T> task, CancellationToken cancellationToken) private static async Task<T> withCancellation<T>(this Task<T> task, CancellationToken cancellationToken)
{ {
var tcs = new TaskCompletionSource<bool>(); var tcs = new TaskCompletionSource<bool>();
using (cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs)) using (cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs))
......
...@@ -122,7 +122,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -122,7 +122,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns>1: when CONNECT, 0: when valid HTTP method, -1: otherwise</returns> /// <returns>1: when CONNECT, 0: when valid HTTP method, -1: otherwise</returns>
internal static Task<int> IsConnectMethod(ICustomStreamReader clientStreamReader) internal static Task<int> IsConnectMethod(ICustomStreamReader clientStreamReader)
{ {
return StartsWith(clientStreamReader, "CONNECT"); return startsWith(clientStreamReader, "CONNECT");
} }
/// <summary> /// <summary>
...@@ -132,7 +132,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -132,7 +132,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns>1: when PRI, 0: when valid HTTP method, -1: otherwise</returns> /// <returns>1: when PRI, 0: when valid HTTP method, -1: otherwise</returns>
internal static Task<int> IsPriMethod(ICustomStreamReader clientStreamReader) internal static Task<int> IsPriMethod(ICustomStreamReader clientStreamReader)
{ {
return StartsWith(clientStreamReader, "PRI"); return startsWith(clientStreamReader, "PRI");
} }
/// <summary> /// <summary>
...@@ -143,7 +143,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -143,7 +143,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns> /// <returns>
/// 1: when starts with the given string, 0: when valid HTTP method, -1: otherwise /// 1: when starts with the given string, 0: when valid HTTP method, -1: otherwise
/// </returns> /// </returns>
private static async Task<int> StartsWith(ICustomStreamReader clientStreamReader, string expectedStart) private static async Task<int> startsWith(ICustomStreamReader clientStreamReader, string expectedStart)
{ {
bool isExpected = true; bool isExpected = true;
int legthToCheck = 10; int legthToCheck = 10;
......
...@@ -44,10 +44,10 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -44,10 +44,10 @@ namespace Titanium.Web.Proxy.Helpers
internal Task WriteAsync(string value, CancellationToken cancellationToken = default) internal Task WriteAsync(string value, CancellationToken cancellationToken = default)
{ {
return WriteAsyncInternal(value, false, cancellationToken); return writeAsyncInternal(value, false, cancellationToken);
} }
private Task WriteAsyncInternal(string value, bool addNewLine, CancellationToken cancellationToken) private Task writeAsyncInternal(string value, bool addNewLine, CancellationToken cancellationToken)
{ {
int newLineChars = addNewLine ? newLine.Length : 0; int newLineChars = addNewLine ? newLine.Length : 0;
int charCount = value.Length; int charCount = value.Length;
...@@ -91,7 +91,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -91,7 +91,7 @@ namespace Titanium.Web.Proxy.Helpers
internal Task WriteLineAsync(string value, CancellationToken cancellationToken = default) internal Task WriteLineAsync(string value, CancellationToken cancellationToken = default)
{ {
return WriteAsyncInternal(value, true, cancellationToken); return writeAsyncInternal(value, true, cancellationToken);
} }
/// <summary> /// <summary>
...@@ -149,7 +149,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -149,7 +149,7 @@ namespace Titanium.Web.Proxy.Helpers
{ {
if (isChunked) if (isChunked)
{ {
return WriteBodyChunkedAsync(data, cancellationToken); return writeBodyChunkedAsync(data, cancellationToken);
} }
return WriteAsync(data, cancellationToken: cancellationToken); return WriteAsync(data, cancellationToken: cancellationToken);
...@@ -171,7 +171,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -171,7 +171,7 @@ namespace Titanium.Web.Proxy.Helpers
// 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 (isChunked) if (isChunked)
{ {
return CopyBodyChunkedAsync(streamReader, onCopy, cancellationToken); return copyBodyChunkedAsync(streamReader, onCopy, cancellationToken);
} }
// http 1.0 or the stream reader limits the stream // http 1.0 or the stream reader limits the stream
...@@ -181,7 +181,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -181,7 +181,7 @@ namespace Titanium.Web.Proxy.Helpers
} }
// If not chunked then its easy just read the amount of bytes mentioned in content length header // If not chunked then its easy just read the amount of bytes mentioned in content length header
return CopyBytesFromStream(streamReader, contentLength, onCopy, cancellationToken); return copyBytesFromStream(streamReader, contentLength, onCopy, cancellationToken);
} }
/// <summary> /// <summary>
...@@ -190,7 +190,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -190,7 +190,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="data"></param> /// <param name="data"></param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
/// <returns></returns> /// <returns></returns>
private async Task WriteBodyChunkedAsync(byte[] data, CancellationToken cancellationToken) private async Task writeBodyChunkedAsync(byte[] data, CancellationToken cancellationToken)
{ {
var chunkHead = Encoding.ASCII.GetBytes(data.Length.ToString("x2")); var chunkHead = Encoding.ASCII.GetBytes(data.Length.ToString("x2"));
...@@ -210,7 +210,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -210,7 +210,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="onCopy"></param> /// <param name="onCopy"></param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
/// <returns></returns> /// <returns></returns>
private async Task CopyBodyChunkedAsync(ICustomStreamReader reader, Action<byte[], int, int> onCopy, private async Task copyBodyChunkedAsync(ICustomStreamReader reader, Action<byte[], int, int> onCopy,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
while (true) while (true)
...@@ -228,7 +228,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -228,7 +228,7 @@ namespace Titanium.Web.Proxy.Helpers
if (chunkSize != 0) if (chunkSize != 0)
{ {
await CopyBytesFromStream(reader, chunkSize, onCopy, cancellationToken); await copyBytesFromStream(reader, chunkSize, onCopy, cancellationToken);
} }
await WriteLineAsync(cancellationToken); await WriteLineAsync(cancellationToken);
...@@ -251,7 +251,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -251,7 +251,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="onCopy"></param> /// <param name="onCopy"></param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
/// <returns></returns> /// <returns></returns>
private async Task CopyBytesFromStream(ICustomStreamReader reader, long count, Action<byte[], int, int> onCopy, private async Task copyBytesFromStream(ICustomStreamReader reader, long count, Action<byte[], int, int> onCopy,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var buffer = BufferPool.GetBuffer(BufferSize); var buffer = BufferPool.GetBuffer(BufferSize);
......
...@@ -39,7 +39,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -39,7 +39,7 @@ namespace Titanium.Web.Proxy.Helpers
} }
else else
{ {
overrides2.Add(BypassStringEscape(overrideHost)); overrides2.Add(bypassStringEscape(overrideHost));
} }
} }
...@@ -70,7 +70,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -70,7 +70,7 @@ namespace Titanium.Web.Proxy.Helpers
internal string[] BypassList { get; } internal string[] BypassList { get; }
private static string BypassStringEscape(string rawString) private static string bypassStringEscape(string rawString)
{ {
var match = var match =
new Regex("^(?<scheme>.*://)?(?<host>[^:]*)(?<port>:[0-9]{1,5})?$", new Regex("^(?<scheme>.*://)?(?<host>[^:]*)(?<port>:[0-9]{1,5})?$",
...@@ -91,9 +91,9 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -91,9 +91,9 @@ namespace Titanium.Web.Proxy.Helpers
empty2 = string.Empty; empty2 = string.Empty;
} }
string str1 = ConvertRegexReservedChars(empty1); string str1 = convertRegexReservedChars(empty1);
string str2 = ConvertRegexReservedChars(rawString1); string str2 = convertRegexReservedChars(rawString1);
string str3 = ConvertRegexReservedChars(empty2); string str3 = convertRegexReservedChars(empty2);
if (str1 == string.Empty) if (str1 == string.Empty)
{ {
str1 = "(?:.*://)?"; str1 = "(?:.*://)?";
...@@ -107,7 +107,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -107,7 +107,7 @@ namespace Titanium.Web.Proxy.Helpers
return "^" + str1 + str2 + str3 + "$"; return "^" + str1 + str2 + str3 + "$";
} }
private static string ConvertRegexReservedChars(string rawString) private static string convertRegexReservedChars(string rawString)
{ {
if (rawString.Length == 0) if (rawString.Length == 0)
{ {
...@@ -171,11 +171,11 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -171,11 +171,11 @@ namespace Titanium.Web.Proxy.Helpers
if (proxyValues.Length > 0) if (proxyValues.Length > 0)
{ {
result.AddRange(proxyValues.Select(ParseProxyValue).Where(parsedValue => parsedValue != null)); result.AddRange(proxyValues.Select(parseProxyValue).Where(parsedValue => parsedValue != null));
} }
else else
{ {
var parsedValue = ParseProxyValue(proxyServerValues); var parsedValue = parseProxyValue(proxyServerValues);
if (parsedValue != null) if (parsedValue != null)
{ {
result.Add(parsedValue); result.Add(parsedValue);
...@@ -190,7 +190,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -190,7 +190,7 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary> /// </summary>
/// <param name="value"></param> /// <param name="value"></param>
/// <returns></returns> /// <returns></returns>
private static HttpSystemProxyValue ParseProxyValue(string value) private static HttpSystemProxyValue parseProxyValue(string value)
{ {
string tmp = Regex.Replace(value, @"\s+", " ").Trim(); string tmp = Regex.Replace(value, @"\s+", " ").Trim();
......
...@@ -84,8 +84,8 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -84,8 +84,8 @@ namespace Titanium.Web.Proxy.Helpers
if (reg != null) if (reg != null)
{ {
SaveOriginalProxyConfiguration(reg); saveOriginalProxyConfiguration(reg);
PrepareRegistry(reg); prepareRegistry(reg);
string exisitingContent = reg.GetValue(regProxyServer) as string; string exisitingContent = reg.GetValue(regProxyServer) as string;
var existingSystemProxyValues = ProxyInfo.GetSystemProxyValues(exisitingContent); var existingSystemProxyValues = ProxyInfo.GetSystemProxyValues(exisitingContent);
...@@ -115,7 +115,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -115,7 +115,7 @@ namespace Titanium.Web.Proxy.Helpers
reg.SetValue(regProxyServer, reg.SetValue(regProxyServer,
string.Join(";", existingSystemProxyValues.Select(x => x.ToString()).ToArray())); string.Join(";", existingSystemProxyValues.Select(x => x.ToString()).ToArray()));
Refresh(); refresh();
} }
} }
...@@ -129,7 +129,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -129,7 +129,7 @@ namespace Titanium.Web.Proxy.Helpers
{ {
if (saveOriginalConfig) if (saveOriginalConfig)
{ {
SaveOriginalProxyConfiguration(reg); saveOriginalProxyConfiguration(reg);
} }
if (reg.GetValue(regProxyServer) != null) if (reg.GetValue(regProxyServer) != null)
...@@ -152,7 +152,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -152,7 +152,7 @@ namespace Titanium.Web.Proxy.Helpers
} }
} }
Refresh(); refresh();
} }
} }
...@@ -165,12 +165,12 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -165,12 +165,12 @@ namespace Titanium.Web.Proxy.Helpers
if (reg != null) if (reg != null)
{ {
SaveOriginalProxyConfiguration(reg); saveOriginalProxyConfiguration(reg);
reg.SetValue(regProxyEnable, 0); reg.SetValue(regProxyEnable, 0);
reg.SetValue(regProxyServer, string.Empty); reg.SetValue(regProxyServer, string.Empty);
Refresh(); refresh();
} }
} }
...@@ -180,9 +180,9 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -180,9 +180,9 @@ namespace Titanium.Web.Proxy.Helpers
if (reg != null) if (reg != null)
{ {
SaveOriginalProxyConfiguration(reg); saveOriginalProxyConfiguration(reg);
reg.SetValue(regAutoConfigUrl, url); reg.SetValue(regAutoConfigUrl, url);
Refresh(); refresh();
} }
} }
...@@ -192,9 +192,9 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -192,9 +192,9 @@ namespace Titanium.Web.Proxy.Helpers
if (reg != null) if (reg != null)
{ {
SaveOriginalProxyConfiguration(reg); saveOriginalProxyConfiguration(reg);
reg.SetValue(regProxyOverride, proxyOverride); reg.SetValue(regProxyOverride, proxyOverride);
Refresh(); refresh();
} }
} }
...@@ -247,7 +247,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -247,7 +247,7 @@ namespace Titanium.Web.Proxy.Helpers
} }
originalValues = null; originalValues = null;
Refresh(); refresh();
} }
} }
...@@ -257,13 +257,13 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -257,13 +257,13 @@ namespace Titanium.Web.Proxy.Helpers
if (reg != null) if (reg != null)
{ {
return GetProxyInfoFromRegistry(reg); return getProxyInfoFromRegistry(reg);
} }
return null; return null;
} }
private ProxyInfo GetProxyInfoFromRegistry(RegistryKey reg) private ProxyInfo getProxyInfoFromRegistry(RegistryKey reg)
{ {
var pi = new ProxyInfo(null, reg.GetValue(regAutoConfigUrl) as string, reg.GetValue(regProxyEnable) as int?, var pi = new ProxyInfo(null, reg.GetValue(regAutoConfigUrl) as string, reg.GetValue(regProxyEnable) as int?,
reg.GetValue(regProxyServer) as string, reg.GetValue(regProxyServer) as string,
...@@ -272,21 +272,21 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -272,21 +272,21 @@ namespace Titanium.Web.Proxy.Helpers
return pi; return pi;
} }
private void SaveOriginalProxyConfiguration(RegistryKey reg) private void saveOriginalProxyConfiguration(RegistryKey reg)
{ {
if (originalValues != null) if (originalValues != null)
{ {
return; return;
} }
originalValues = GetProxyInfoFromRegistry(reg); originalValues = getProxyInfoFromRegistry(reg);
} }
/// <summary> /// <summary>
/// Prepares the proxy server registry (create empty values if they don't exist) /// Prepares the proxy server registry (create empty values if they don't exist)
/// </summary> /// </summary>
/// <param name="reg"></param> /// <param name="reg"></param>
private static void PrepareRegistry(RegistryKey reg) private static void prepareRegistry(RegistryKey reg)
{ {
if (reg.GetValue(regProxyEnable) == null) if (reg.GetValue(regProxyEnable) == null)
{ {
...@@ -302,7 +302,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -302,7 +302,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <summary> /// <summary>
/// Refresh the settings so that the system know about a change in proxy setting /// Refresh the settings so that the system know about a change in proxy setting
/// </summary> /// </summary>
private void Refresh() private static void refresh()
{ {
NativeMethods.InternetSetOption(IntPtr.Zero, InternetOptionSettingsChanged, IntPtr.Zero, 0); NativeMethods.InternetSetOption(IntPtr.Zero, InternetOptionSettingsChanged, IntPtr.Zero, 0);
NativeMethods.InternetSetOption(IntPtr.Zero, InternetOptionRefresh, IntPtr.Zero, 0); NativeMethods.InternetSetOption(IntPtr.Zero, InternetOptionRefresh, IntPtr.Zero, 0);
......
...@@ -39,7 +39,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -39,7 +39,7 @@ namespace Titanium.Web.Proxy.Helpers
0) == 0) 0) == 0)
{ {
int rowCount = *(int*)tcpTable; int rowCount = *(int*)tcpTable;
uint portInNetworkByteOrder = ToNetworkByteOrder((uint)localPort); uint portInNetworkByteOrder = toNetworkByteOrder((uint)localPort);
if (ipVersion == IpVersion.Ipv4) if (ipVersion == IpVersion.Ipv4)
{ {
...@@ -90,7 +90,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -90,7 +90,7 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary> /// </summary>
/// <param name="port"></param> /// <param name="port"></param>
/// <returns></returns> /// <returns></returns>
private static uint ToNetworkByteOrder(uint port) private static uint toNetworkByteOrder(uint port)
{ {
return ((port >> 8) & 0x00FF00FFu) | ((port << 8) & 0xFF00FF00u); return ((port >> 8) & 0x00FF00FFu) | ((port << 8) & 0xFF00FF00u);
} }
...@@ -122,8 +122,8 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -122,8 +122,8 @@ namespace Titanium.Web.Proxy.Helpers
var serverBuffer = BufferPool.GetBuffer(bufferSize); var serverBuffer = BufferPool.GetBuffer(bufferSize);
try try
{ {
BeginRead(clientStream, serverStream, clientBuffer, onDataSend, cancellationTokenSource, exceptionFunc); beginRead(clientStream, serverStream, clientBuffer, onDataSend, cancellationTokenSource, exceptionFunc);
BeginRead(serverStream, clientStream, serverBuffer, onDataReceive, cancellationTokenSource, beginRead(serverStream, clientStream, serverBuffer, onDataReceive, cancellationTokenSource,
exceptionFunc); exceptionFunc);
await taskCompletionSource.Task; await taskCompletionSource.Task;
} }
...@@ -134,7 +134,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -134,7 +134,7 @@ namespace Titanium.Web.Proxy.Helpers
} }
} }
private static void BeginRead(Stream inputStream, Stream outputStream, byte[] buffer, private static void beginRead(Stream inputStream, Stream outputStream, byte[] buffer,
Action<byte[], int, int> onCopy, CancellationTokenSource cancellationTokenSource, Action<byte[], int, int> onCopy, CancellationTokenSource cancellationTokenSource,
ExceptionHandler exceptionFunc) ExceptionHandler exceptionFunc)
{ {
...@@ -174,7 +174,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -174,7 +174,7 @@ namespace Titanium.Web.Proxy.Helpers
try try
{ {
outputStream.EndWrite(ar2); outputStream.EndWrite(ar2);
BeginRead(inputStream, outputStream, buffer, onCopy, cancellationTokenSource, beginRead(inputStream, outputStream, buffer, onCopy, cancellationTokenSource,
exceptionFunc); exceptionFunc);
} }
catch (IOException ex) catch (IOException ex)
...@@ -214,7 +214,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -214,7 +214,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="cancellationTokenSource"></param> /// <param name="cancellationTokenSource"></param>
/// <param name="exceptionFunc"></param> /// <param name="exceptionFunc"></param>
/// <returns></returns> /// <returns></returns>
private static async Task SendRawTap(Stream clientStream, Stream serverStream, int bufferSize, private static async Task sendRawTap(Stream clientStream, Stream serverStream, int bufferSize,
Action<byte[], int, int> onDataSend, Action<byte[], int, int> onDataReceive, Action<byte[], int, int> onDataSend, Action<byte[], int, int> onDataReceive,
CancellationTokenSource cancellationTokenSource, CancellationTokenSource cancellationTokenSource,
ExceptionHandler exceptionFunc) ExceptionHandler exceptionFunc)
...@@ -250,7 +250,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -250,7 +250,7 @@ namespace Titanium.Web.Proxy.Helpers
ExceptionHandler exceptionFunc) ExceptionHandler exceptionFunc)
{ {
// todo: fix APM mode // todo: fix APM mode
return SendRawTap(clientStream, serverStream, bufferSize, onDataSend, onDataReceive, return sendRawTap(clientStream, serverStream, bufferSize, onDataSend, onDataReceive,
cancellationTokenSource, cancellationTokenSource,
exceptionFunc); exceptionFunc);
} }
......
...@@ -19,7 +19,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -19,7 +19,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
session = NativeMethods.WinHttp.WinHttpOpen(null, NativeMethods.WinHttp.AccessType.NoProxy, null, null, 0); session = NativeMethods.WinHttp.WinHttpOpen(null, NativeMethods.WinHttp.AccessType.NoProxy, null, null, 0);
if (session == null || session.IsInvalid) if (session == null || session.IsInvalid)
{ {
int lastWin32Error = GetLastWin32Error(); int lastWin32Error = getLastWin32Error();
} }
else else
{ {
...@@ -30,7 +30,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -30,7 +30,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
return; return;
} }
int lastWin32Error = GetLastWin32Error(); int lastWin32Error = getLastWin32Error();
} }
} }
...@@ -50,7 +50,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -50,7 +50,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
public void Dispose() public void Dispose()
{ {
Dispose(true); dispose(true);
} }
public bool GetAutoProxies(Uri destination, out IList<string> proxyList) public bool GetAutoProxies(Uri destination, out IList<string> proxyList)
...@@ -65,8 +65,8 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -65,8 +65,8 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
var errorCode = NativeMethods.WinHttp.ErrorCodes.AudodetectionFailed; var errorCode = NativeMethods.WinHttp.ErrorCodes.AudodetectionFailed;
if (AutomaticallyDetectSettings && !autoDetectFailed) if (AutomaticallyDetectSettings && !autoDetectFailed)
{ {
errorCode = (NativeMethods.WinHttp.ErrorCodes)GetAutoProxies(destination, null, out proxyListString); errorCode = (NativeMethods.WinHttp.ErrorCodes)getAutoProxies(destination, null, out proxyListString);
autoDetectFailed = IsErrorFatalForAutoDetect(errorCode); autoDetectFailed = isErrorFatalForAutoDetect(errorCode);
if (errorCode == NativeMethods.WinHttp.ErrorCodes.UnrecognizedScheme) if (errorCode == NativeMethods.WinHttp.ErrorCodes.UnrecognizedScheme)
{ {
state = AutoWebProxyState.UnrecognizedScheme; state = AutoWebProxyState.UnrecognizedScheme;
...@@ -74,13 +74,13 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -74,13 +74,13 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
} }
} }
if (AutomaticConfigurationScript != null && IsRecoverableAutoProxyError(errorCode)) if (AutomaticConfigurationScript != null && isRecoverableAutoProxyError(errorCode))
{ {
errorCode = (NativeMethods.WinHttp.ErrorCodes)GetAutoProxies(destination, AutomaticConfigurationScript, errorCode = (NativeMethods.WinHttp.ErrorCodes)getAutoProxies(destination, AutomaticConfigurationScript,
out proxyListString); out proxyListString);
} }
state = GetStateFromErrorCode(errorCode); state = getStateFromErrorCode(errorCode);
if (state != AutoWebProxyState.Completed) if (state != AutoWebProxyState.Completed)
{ {
return false; return false;
...@@ -88,7 +88,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -88,7 +88,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
if (!string.IsNullOrEmpty(proxyListString)) if (!string.IsNullOrEmpty(proxyListString))
{ {
proxyListString = RemoveWhitespaces(proxyListString); proxyListString = removeWhitespaces(proxyListString);
proxyList = proxyListString.Split(';'); proxyList = proxyListString.Split(';');
} }
...@@ -149,7 +149,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -149,7 +149,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
public void LoadFromIE() public void LoadFromIE()
{ {
var pi = GetProxyInfo(); var pi = getProxyInfo();
ProxyInfo = pi; ProxyInfo = pi;
AutomaticallyDetectSettings = pi.AutoDetect == true; AutomaticallyDetectSettings = pi.AutoDetect == true;
AutomaticConfigurationScript = pi.AutoConfigUrl == null ? null : new Uri(pi.AutoConfigUrl); AutomaticConfigurationScript = pi.AutoConfigUrl == null ? null : new Uri(pi.AutoConfigUrl);
...@@ -158,7 +158,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -158,7 +158,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
proxy = new WebProxy(new Uri("http://localhost"), BypassOnLocal, pi.BypassList); proxy = new WebProxy(new Uri("http://localhost"), BypassOnLocal, pi.BypassList);
} }
private ProxyInfo GetProxyInfo() private ProxyInfo getProxyInfo()
{ {
var proxyConfig = new NativeMethods.WinHttp.WINHTTP_CURRENT_USER_IE_PROXY_CONFIG(); var proxyConfig = new NativeMethods.WinHttp.WINHTTP_CURRENT_USER_IE_PROXY_CONFIG();
RuntimeHelpers.PrepareConstrainedRegions(); RuntimeHelpers.PrepareConstrainedRegions();
...@@ -200,7 +200,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -200,7 +200,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
autoDetectFailed = false; autoDetectFailed = false;
} }
private void Dispose(bool disposing) private void dispose(bool disposing)
{ {
if (!disposing || session == null || session.IsInvalid) if (!disposing || session == null || session.IsInvalid)
{ {
...@@ -210,7 +210,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -210,7 +210,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
session.Close(); session.Close();
} }
private int GetAutoProxies(Uri destination, Uri scriptLocation, out string proxyListString) private int getAutoProxies(Uri destination, Uri scriptLocation, out string proxyListString)
{ {
int num = 0; int num = 0;
var autoProxyOptions = new NativeMethods.WinHttp.WINHTTP_AUTOPROXY_OPTIONS(); var autoProxyOptions = new NativeMethods.WinHttp.WINHTTP_AUTOPROXY_OPTIONS();
...@@ -229,16 +229,16 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -229,16 +229,16 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
autoProxyOptions.AutoDetectFlags = NativeMethods.WinHttp.AutoDetectType.None; autoProxyOptions.AutoDetectFlags = NativeMethods.WinHttp.AutoDetectType.None;
} }
if (!WinHttpGetProxyForUrl(destination.ToString(), ref autoProxyOptions, out proxyListString)) if (!winHttpGetProxyForUrl(destination.ToString(), ref autoProxyOptions, out proxyListString))
{ {
num = GetLastWin32Error(); num = getLastWin32Error();
if (num == (int)NativeMethods.WinHttp.ErrorCodes.LoginFailure && Credentials != null) if (num == (int)NativeMethods.WinHttp.ErrorCodes.LoginFailure && Credentials != null)
{ {
autoProxyOptions.AutoLogonIfChallenged = true; autoProxyOptions.AutoLogonIfChallenged = true;
if (!WinHttpGetProxyForUrl(destination.ToString(), ref autoProxyOptions, out proxyListString)) if (!winHttpGetProxyForUrl(destination.ToString(), ref autoProxyOptions, out proxyListString))
{ {
num = GetLastWin32Error(); num = getLastWin32Error();
} }
} }
} }
...@@ -246,7 +246,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -246,7 +246,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
return num; return num;
} }
private bool WinHttpGetProxyForUrl(string destination, private bool winHttpGetProxyForUrl(string destination,
ref NativeMethods.WinHttp.WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions, out string proxyListString) ref NativeMethods.WinHttp.WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions, out string proxyListString)
{ {
proxyListString = null; proxyListString = null;
...@@ -271,7 +271,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -271,7 +271,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
return flag; return flag;
} }
private static int GetLastWin32Error() private static int getLastWin32Error()
{ {
int lastWin32Error = Marshal.GetLastWin32Error(); int lastWin32Error = Marshal.GetLastWin32Error();
if (lastWin32Error == 8) if (lastWin32Error == 8)
...@@ -282,7 +282,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -282,7 +282,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
return lastWin32Error; return lastWin32Error;
} }
private static bool IsRecoverableAutoProxyError(NativeMethods.WinHttp.ErrorCodes errorCode) private static bool isRecoverableAutoProxyError(NativeMethods.WinHttp.ErrorCodes errorCode)
{ {
switch (errorCode) switch (errorCode)
{ {
...@@ -300,7 +300,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -300,7 +300,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
} }
} }
private static AutoWebProxyState GetStateFromErrorCode(NativeMethods.WinHttp.ErrorCodes errorCode) private static AutoWebProxyState getStateFromErrorCode(NativeMethods.WinHttp.ErrorCodes errorCode)
{ {
if (errorCode == 0L) if (errorCode == 0L)
{ {
...@@ -324,7 +324,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -324,7 +324,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
} }
} }
private static string RemoveWhitespaces(string value) private static string removeWhitespaces(string value)
{ {
var stringBuilder = new StringBuilder(); var stringBuilder = new StringBuilder();
foreach (char c in value) foreach (char c in value)
...@@ -338,7 +338,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -338,7 +338,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
return stringBuilder.ToString(); return stringBuilder.ToString();
} }
private static bool IsErrorFatalForAutoDetect(NativeMethods.WinHttp.ErrorCodes errorCode) private static bool isErrorFatalForAutoDetect(NativeMethods.WinHttp.ErrorCodes errorCode)
{ {
switch (errorCode) switch (errorCode)
{ {
......
...@@ -24,7 +24,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -24,7 +24,7 @@ namespace Titanium.Web.Proxy.Http
/// </summary> /// </summary>
/// <param name="buffer"></param> /// <param name="buffer"></param>
/// <param name="size"></param> /// <param name="size"></param>
private static void ResizeBuffer(ref byte[] buffer, long size) private static void resizeBuffer(ref byte[] buffer, long size)
{ {
var newBuffer = new byte[size]; var newBuffer = new byte[size];
Buffer.BlockCopy(buffer, 0, newBuffer, 0, buffer.Length); Buffer.BlockCopy(buffer, 0, newBuffer, 0, buffer.Length);
......
...@@ -4,6 +4,7 @@ using System.Net; ...@@ -4,6 +4,7 @@ using System.Net;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Titanium.Web.Proxy.Exceptions;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Network.Tcp; using Titanium.Web.Proxy.Network.Tcp;
...@@ -160,7 +161,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -160,7 +161,7 @@ namespace Titanium.Web.Proxy.Http
string httpStatus = await ServerConnection.Stream.ReadLineAsync(cancellationToken); string httpStatus = await ServerConnection.Stream.ReadLineAsync(cancellationToken);
if (httpStatus == null) if (httpStatus == null)
{ {
throw new IOException(); throw new ServerConnectionException("Server connection was closed.");
} }
if (httpStatus == string.Empty) if (httpStatus == string.Empty)
......
...@@ -199,7 +199,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -199,7 +199,7 @@ namespace Titanium.Web.Proxy.Http
// Find the request Verb // Find the request Verb
httpMethod = httpCmdSplit[0]; httpMethod = httpCmdSplit[0];
if (!IsAllUpper(httpMethod)) if (!isAllUpper(httpMethod))
{ {
httpMethod = httpMethod.ToUpper(); httpMethod = httpMethod.ToUpper();
} }
...@@ -219,7 +219,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -219,7 +219,7 @@ namespace Titanium.Web.Proxy.Http
} }
} }
private static bool IsAllUpper(string input) private static bool isAllUpper(string input)
{ {
for (int i = 0; i < input.Length; i++) for (int i = 0; i < input.Length; i++)
{ {
......
...@@ -49,7 +49,7 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -49,7 +49,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// <returns>X509Certificate2 instance.</returns> /// <returns>X509Certificate2 instance.</returns>
public X509Certificate2 MakeCertificate(string sSubjectCn, bool isRoot, X509Certificate2 signingCert = null) public X509Certificate2 MakeCertificate(string sSubjectCn, bool isRoot, X509Certificate2 signingCert = null)
{ {
return MakeCertificateInternal(sSubjectCn, isRoot, true, signingCert); return makeCertificateInternal(sSubjectCn, isRoot, true, signingCert);
} }
/// <summary> /// <summary>
...@@ -65,7 +65,7 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -65,7 +65,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// <param name="hostName">The host name</param> /// <param name="hostName">The host name</param>
/// <returns>X509Certificate2 instance.</returns> /// <returns>X509Certificate2 instance.</returns>
/// <exception cref="PemException">Malformed sequence in RSA private key</exception> /// <exception cref="PemException">Malformed sequence in RSA private key</exception>
private static X509Certificate2 GenerateCertificate(string hostName, private static X509Certificate2 generateCertificate(string hostName,
string subjectName, string subjectName,
string issuerName, DateTime validFrom, string issuerName, DateTime validFrom,
DateTime validTo, int keyStrength = 2048, DateTime validTo, int keyStrength = 2048,
...@@ -145,7 +145,7 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -145,7 +145,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
var x509Certificate = new X509Certificate2(certificate.GetEncoded()); var x509Certificate = new X509Certificate2(certificate.GetEncoded());
x509Certificate.PrivateKey = DotNetUtilities.ToRSA(rsaparams); x509Certificate.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
#else #else
var x509Certificate = WithPrivateKey(certificate, rsaparams); var x509Certificate = withPrivateKey(certificate, rsaparams);
x509Certificate.FriendlyName = subjectName; x509Certificate.FriendlyName = subjectName;
#endif #endif
...@@ -164,7 +164,7 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -164,7 +164,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
return x509Certificate; return x509Certificate;
} }
private static X509Certificate2 WithPrivateKey(X509Certificate certificate, AsymmetricKeyParameter privateKey) private static X509Certificate2 withPrivateKey(X509Certificate certificate, AsymmetricKeyParameter privateKey)
{ {
const string password = "password"; const string password = "password";
var store = new Pkcs12Store(); var store = new Pkcs12Store();
...@@ -194,7 +194,7 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -194,7 +194,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// You must specify a Signing Certificate if and only if you are not creating a /// You must specify a Signing Certificate if and only if you are not creating a
/// root. /// root.
/// </exception> /// </exception>
private X509Certificate2 MakeCertificateInternal(bool isRoot, private X509Certificate2 makeCertificateInternal(bool isRoot,
string hostName, string subjectName, string hostName, string subjectName,
DateTime validFrom, DateTime validTo, X509Certificate2 signingCertificate) DateTime validFrom, DateTime validTo, X509Certificate2 signingCertificate)
{ {
...@@ -207,11 +207,11 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -207,11 +207,11 @@ namespace Titanium.Web.Proxy.Network.Certificate
if (isRoot) if (isRoot)
{ {
return GenerateCertificate(null, subjectName, subjectName, validFrom, validTo); return generateCertificate(null, subjectName, subjectName, validFrom, validTo);
} }
var kp = DotNetUtilities.GetKeyPair(signingCertificate.PrivateKey); var kp = DotNetUtilities.GetKeyPair(signingCertificate.PrivateKey);
return GenerateCertificate(hostName, subjectName, signingCertificate.Subject, validFrom, validTo, return generateCertificate(hostName, subjectName, signingCertificate.Subject, validFrom, validTo,
issuerPrivateKey: kp.Private); issuerPrivateKey: kp.Private);
} }
...@@ -224,7 +224,7 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -224,7 +224,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// <param name="signingCert">The signing cert.</param> /// <param name="signingCert">The signing cert.</param>
/// <param name="cancellationToken">Task cancellation token</param> /// <param name="cancellationToken">Task cancellation token</param>
/// <returns>X509Certificate2.</returns> /// <returns>X509Certificate2.</returns>
private X509Certificate2 MakeCertificateInternal(string subject, bool isRoot, private X509Certificate2 makeCertificateInternal(string subject, bool isRoot,
bool switchToMtaIfNeeded, X509Certificate2 signingCert = null, bool switchToMtaIfNeeded, X509Certificate2 signingCert = null,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
...@@ -238,7 +238,7 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -238,7 +238,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
{ {
try try
{ {
certificate = MakeCertificateInternal(subject, isRoot, false, signingCert); certificate = makeCertificateInternal(subject, isRoot, false, signingCert);
} }
catch (Exception ex) catch (Exception ex)
{ {
...@@ -258,7 +258,7 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -258,7 +258,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
} }
#endif #endif
return MakeCertificateInternal(isRoot, subject, $"CN={subject}", return makeCertificateInternal(isRoot, subject, $"CN={subject}",
DateTime.UtcNow.AddDays(-certificateGraceDays), DateTime.UtcNow.AddDays(certificateValidDays), DateTime.UtcNow.AddDays(-certificateGraceDays), DateTime.UtcNow.AddDays(certificateValidDays),
isRoot ? null : signingCert); isRoot ? null : signingCert);
} }
......
...@@ -80,10 +80,10 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -80,10 +80,10 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// <returns></returns> /// <returns></returns>
public X509Certificate2 MakeCertificate(string sSubjectCN, bool isRoot, X509Certificate2 signingCert = null) public X509Certificate2 MakeCertificate(string sSubjectCN, bool isRoot, X509Certificate2 signingCert = null)
{ {
return MakeCertificateInternal(sSubjectCN, isRoot, true, signingCert); return makeCertificateInternal(sSubjectCN, isRoot, true, signingCert);
} }
private X509Certificate2 MakeCertificate(bool isRoot, string subject, string fullSubject, private X509Certificate2 makeCertificate(bool isRoot, string subject, string fullSubject,
int privateKeyLength, string hashAlg, DateTime validFrom, DateTime validTo, int privateKeyLength, string hashAlg, DateTime validFrom, DateTime validTo,
X509Certificate2 signingCertificate) X509Certificate2 signingCertificate)
{ {
...@@ -274,13 +274,13 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -274,13 +274,13 @@ namespace Titanium.Web.Proxy.Network.Certificate
return new X509Certificate2(Convert.FromBase64String(empty), string.Empty, X509KeyStorageFlags.Exportable); return new X509Certificate2(Convert.FromBase64String(empty), string.Empty, X509KeyStorageFlags.Exportable);
} }
private X509Certificate2 MakeCertificateInternal(string sSubjectCN, bool isRoot, private X509Certificate2 makeCertificateInternal(string sSubjectCN, bool isRoot,
bool switchToMTAIfNeeded, X509Certificate2 signingCert = null, bool switchToMTAIfNeeded, X509Certificate2 signingCert = null,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
if (switchToMTAIfNeeded && Thread.CurrentThread.GetApartmentState() != ApartmentState.MTA) if (switchToMTAIfNeeded && Thread.CurrentThread.GetApartmentState() != ApartmentState.MTA)
{ {
return Task.Run(() => MakeCertificateInternal(sSubjectCN, isRoot, false, signingCert), return Task.Run(() => makeCertificateInternal(sSubjectCN, isRoot, false, signingCert),
cancellationToken).Result; cancellationToken).Result;
} }
...@@ -301,7 +301,7 @@ namespace Titanium.Web.Proxy.Network.Certificate ...@@ -301,7 +301,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
var graceTime = DateTime.Now.AddDays(graceDays); var graceTime = DateTime.Now.AddDays(graceDays);
var now = DateTime.Now; var now = DateTime.Now;
var certificate = MakeCertificate(isRoot, sSubjectCN, fullSubject, keyLength, hashAlgo, graceTime, var certificate = makeCertificate(isRoot, sSubjectCN, fullSubject, keyLength, hashAlgo, graceTime,
now.AddDays(validDays), isRoot ? null : signingCert); now.AddDays(validDays), isRoot ? null : signingCert);
return certificate; return certificate;
} }
......
...@@ -239,7 +239,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -239,7 +239,7 @@ namespace Titanium.Web.Proxy.Network
{ {
} }
private string GetRootCertificateDirectory() private string getRootCertificateDirectory()
{ {
string assemblyLocation = Assembly.GetExecutingAssembly().Location; string assemblyLocation = Assembly.GetExecutingAssembly().Location;
...@@ -258,9 +258,9 @@ namespace Titanium.Web.Proxy.Network ...@@ -258,9 +258,9 @@ namespace Titanium.Web.Proxy.Network
return path; return path;
} }
private string GetCertificatePath() private string getCertificatePath()
{ {
string path = GetRootCertificateDirectory(); string path = getRootCertificateDirectory();
string certPath = Path.Combine(path, "crts"); string certPath = Path.Combine(path, "crts");
if (!Directory.Exists(certPath)) if (!Directory.Exists(certPath))
...@@ -271,9 +271,9 @@ namespace Titanium.Web.Proxy.Network ...@@ -271,9 +271,9 @@ namespace Titanium.Web.Proxy.Network
return certPath; return certPath;
} }
private string GetRootCertificatePath() private string getRootCertificatePath()
{ {
string path = GetRootCertificateDirectory(); string path = getRootCertificateDirectory();
string fileName = PfxFilePath; string fileName = PfxFilePath;
if (fileName == string.Empty) if (fileName == string.Empty)
...@@ -290,15 +290,15 @@ namespace Titanium.Web.Proxy.Network ...@@ -290,15 +290,15 @@ namespace Titanium.Web.Proxy.Network
/// </summary> /// </summary>
/// <param name="storeLocation"></param> /// <param name="storeLocation"></param>
/// <returns></returns> /// <returns></returns>
private bool RootCertificateInstalled(StoreLocation storeLocation) private bool rootCertificateInstalled(StoreLocation storeLocation)
{ {
string value = $"{RootCertificate.Issuer}"; string value = $"{RootCertificate.Issuer}";
return FindCertificates(StoreName.Root, storeLocation, value).Count > 0 return findCertificates(StoreName.Root, storeLocation, value).Count > 0
&& (CertificateEngine != CertificateEngine.DefaultWindows && (CertificateEngine != CertificateEngine.DefaultWindows
|| FindCertificates(StoreName.My, storeLocation, value).Count > 0); || findCertificates(StoreName.My, storeLocation, value).Count > 0);
} }
private X509Certificate2Collection FindCertificates(StoreName storeName, StoreLocation storeLocation, private static X509Certificate2Collection findCertificates(StoreName storeName, StoreLocation storeLocation,
string findValue) string findValue)
{ {
var x509Store = new X509Store(storeName, storeLocation); var x509Store = new X509Store(storeName, storeLocation);
...@@ -318,7 +318,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -318,7 +318,7 @@ namespace Titanium.Web.Proxy.Network
/// </summary> /// </summary>
/// <param name="storeName"></param> /// <param name="storeName"></param>
/// <param name="storeLocation"></param> /// <param name="storeLocation"></param>
private void InstallCertificate(StoreName storeName, StoreLocation storeLocation) private void installCertificate(StoreName storeName, StoreLocation storeLocation)
{ {
if (RootCertificate == null) if (RootCertificate == null)
{ {
...@@ -354,7 +354,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -354,7 +354,7 @@ namespace Titanium.Web.Proxy.Network
/// <param name="storeName"></param> /// <param name="storeName"></param>
/// <param name="storeLocation"></param> /// <param name="storeLocation"></param>
/// <param name="certificate"></param> /// <param name="certificate"></param>
private void UninstallCertificate(StoreName storeName, StoreLocation storeLocation, private void uninstallCertificate(StoreName storeName, StoreLocation storeLocation,
X509Certificate2 certificate) X509Certificate2 certificate)
{ {
if (certificate == null) if (certificate == null)
...@@ -383,7 +383,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -383,7 +383,7 @@ namespace Titanium.Web.Proxy.Network
} }
} }
private X509Certificate2 MakeCertificate(string certificateName, bool isRootCertificate) private X509Certificate2 makeCertificate(string certificateName, bool isRootCertificate)
{ {
if (!isRootCertificate && RootCertificate == null) if (!isRootCertificate && RootCertificate == null)
{ {
...@@ -394,7 +394,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -394,7 +394,7 @@ namespace Titanium.Web.Proxy.Network
if (CertificateEngine == CertificateEngine.DefaultWindows) if (CertificateEngine == CertificateEngine.DefaultWindows)
{ {
Task.Run(() => UninstallCertificate(StoreName.My, StoreLocation.CurrentUser, certificate)); Task.Run(() => uninstallCertificate(StoreName.My, StoreLocation.CurrentUser, certificate));
} }
return certificate; return certificate;
...@@ -413,14 +413,14 @@ namespace Titanium.Web.Proxy.Network ...@@ -413,14 +413,14 @@ namespace Titanium.Web.Proxy.Network
{ {
if (!isRootCertificate && SaveFakeCertificates) if (!isRootCertificate && SaveFakeCertificates)
{ {
string path = GetCertificatePath(); string path = getCertificatePath();
string subjectName = ProxyConstants.CNRemoverRegex.Replace(certificateName, string.Empty); string subjectName = ProxyConstants.CNRemoverRegex.Replace(certificateName, string.Empty);
subjectName = subjectName.Replace("*", "$x$"); subjectName = subjectName.Replace("*", "$x$");
string certificatePath = Path.Combine(path, subjectName + ".pfx"); string certificatePath = Path.Combine(path, subjectName + ".pfx");
if (!File.Exists(certificatePath)) if (!File.Exists(certificatePath))
{ {
certificate = MakeCertificate(certificateName, false); certificate = makeCertificate(certificateName, false);
// store as cache // store as cache
Task.Run(() => Task.Run(() =>
...@@ -444,13 +444,13 @@ namespace Titanium.Web.Proxy.Network ...@@ -444,13 +444,13 @@ namespace Titanium.Web.Proxy.Network
catch catch
{ {
// if load failed create again // if load failed create again
certificate = MakeCertificate(certificateName, false); certificate = makeCertificate(certificateName, false);
} }
} }
} }
else else
{ {
certificate = MakeCertificate(certificateName, isRootCertificate); certificate = makeCertificate(certificateName, isRootCertificate);
} }
} }
catch (Exception e) catch (Exception e)
...@@ -574,14 +574,14 @@ namespace Titanium.Web.Proxy.Network ...@@ -574,14 +574,14 @@ namespace Titanium.Web.Proxy.Network
{ {
try try
{ {
Directory.Delete(GetCertificatePath(), true); Directory.Delete(getCertificatePath(), true);
} }
catch catch
{ {
// ignore // ignore
} }
string fileName = GetRootCertificatePath(); string fileName = getRootCertificatePath();
File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12, PfxPassword)); File.WriteAllBytes(fileName, RootCertificate.Export(X509ContentType.Pkcs12, PfxPassword));
} }
catch (Exception e) catch (Exception e)
...@@ -599,7 +599,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -599,7 +599,7 @@ namespace Titanium.Web.Proxy.Network
/// <returns></returns> /// <returns></returns>
public X509Certificate2 LoadRootCertificate() public X509Certificate2 LoadRootCertificate()
{ {
string fileName = GetRootCertificatePath(); string fileName = getRootCertificatePath();
pfxFileExists = File.Exists(fileName); pfxFileExists = File.Exists(fileName);
if (!pfxFileExists) if (!pfxFileExists)
{ {
...@@ -653,20 +653,20 @@ namespace Titanium.Web.Proxy.Network ...@@ -653,20 +653,20 @@ namespace Titanium.Web.Proxy.Network
public void TrustRootCertificate(bool machineTrusted = false) public void TrustRootCertificate(bool machineTrusted = false)
{ {
// currentUser\personal // currentUser\personal
InstallCertificate(StoreName.My, StoreLocation.CurrentUser); installCertificate(StoreName.My, StoreLocation.CurrentUser);
if (!machineTrusted) if (!machineTrusted)
{ {
// currentUser\Root // currentUser\Root
InstallCertificate(StoreName.Root, StoreLocation.CurrentUser); installCertificate(StoreName.Root, StoreLocation.CurrentUser);
} }
else else
{ {
// current system // current system
InstallCertificate(StoreName.My, StoreLocation.LocalMachine); installCertificate(StoreName.My, StoreLocation.LocalMachine);
// this adds to both currentUser\Root & currentMachine\Root // this adds to both currentUser\Root & currentMachine\Root
InstallCertificate(StoreName.Root, StoreLocation.LocalMachine); installCertificate(StoreName.Root, StoreLocation.LocalMachine);
} }
} }
...@@ -683,7 +683,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -683,7 +683,7 @@ namespace Titanium.Web.Proxy.Network
} }
// currentUser\Personal // currentUser\Personal
InstallCertificate(StoreName.My, StoreLocation.CurrentUser); installCertificate(StoreName.My, StoreLocation.CurrentUser);
string pfxFileName = Path.GetTempFileName(); string pfxFileName = Path.GetTempFileName();
File.WriteAllBytes(pfxFileName, RootCertificate.Export(X509ContentType.Pkcs12, PfxPassword)); File.WriteAllBytes(pfxFileName, RootCertificate.Export(X509ContentType.Pkcs12, PfxPassword));
...@@ -778,7 +778,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -778,7 +778,7 @@ namespace Titanium.Web.Proxy.Network
/// </summary> /// </summary>
public bool IsRootCertificateUserTrusted() public bool IsRootCertificateUserTrusted()
{ {
return RootCertificateInstalled(StoreLocation.CurrentUser) || IsRootCertificateMachineTrusted(); return rootCertificateInstalled(StoreLocation.CurrentUser) || IsRootCertificateMachineTrusted();
} }
/// <summary> /// <summary>
...@@ -786,7 +786,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -786,7 +786,7 @@ namespace Titanium.Web.Proxy.Network
/// </summary> /// </summary>
public bool IsRootCertificateMachineTrusted() public bool IsRootCertificateMachineTrusted()
{ {
return RootCertificateInstalled(StoreLocation.LocalMachine); return rootCertificateInstalled(StoreLocation.LocalMachine);
} }
/// <summary> /// <summary>
...@@ -797,20 +797,20 @@ namespace Titanium.Web.Proxy.Network ...@@ -797,20 +797,20 @@ namespace Titanium.Web.Proxy.Network
public void RemoveTrustedRootCertificate(bool machineTrusted = false) public void RemoveTrustedRootCertificate(bool machineTrusted = false)
{ {
// currentUser\personal // currentUser\personal
UninstallCertificate(StoreName.My, StoreLocation.CurrentUser, RootCertificate); uninstallCertificate(StoreName.My, StoreLocation.CurrentUser, RootCertificate);
if (!machineTrusted) if (!machineTrusted)
{ {
// currentUser\Root // currentUser\Root
UninstallCertificate(StoreName.Root, StoreLocation.CurrentUser, RootCertificate); uninstallCertificate(StoreName.Root, StoreLocation.CurrentUser, RootCertificate);
} }
else else
{ {
// current system // current system
UninstallCertificate(StoreName.My, StoreLocation.LocalMachine, RootCertificate); uninstallCertificate(StoreName.My, StoreLocation.LocalMachine, RootCertificate);
// this adds to both currentUser\Root & currentMachine\Root // this adds to both currentUser\Root & currentMachine\Root
UninstallCertificate(StoreName.Root, StoreLocation.LocalMachine, RootCertificate); uninstallCertificate(StoreName.Root, StoreLocation.LocalMachine, RootCertificate);
} }
} }
...@@ -826,7 +826,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -826,7 +826,7 @@ namespace Titanium.Web.Proxy.Network
} }
// currentUser\Personal // currentUser\Personal
UninstallCertificate(StoreName.My, StoreLocation.CurrentUser, RootCertificate); uninstallCertificate(StoreName.My, StoreLocation.CurrentUser, RootCertificate);
var infos = new List<ProcessStartInfo>(); var infos = new List<ProcessStartInfo>();
if (!machineTrusted) if (!machineTrusted)
......
using System; using System;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Net.Security;
using System.Net.Sockets; using System.Net.Sockets;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
......
...@@ -40,7 +40,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -40,7 +40,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
internal TcpConnectionFactory(ProxyServer server) internal TcpConnectionFactory(ProxyServer server)
{ {
this.server = server; this.server = server;
Task.Run(async () => await ClearOutdatedConnections()); Task.Run(async () => await clearOutdatedConnections());
} }
/// <summary> /// <summary>
...@@ -88,7 +88,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -88,7 +88,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
var cutOff = DateTime.Now.AddSeconds(-1 * proxyServer.ConnectionTimeOutSeconds + 3); var cutOff = DateTime.Now.AddSeconds(-1 * proxyServer.ConnectionTimeOutSeconds + 3);
if (recentConnection.LastAccess > cutOff if (recentConnection.LastAccess > cutOff
&& IsGoodConnection(recentConnection.TcpClient)) && isGoodConnection(recentConnection.TcpClient))
{ {
return recentConnection; return recentConnection;
} }
...@@ -99,7 +99,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -99,7 +99,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
} }
} }
var connection = await CreateClient(remoteHostName, remotePort, httpVersion, isHttps, var connection = await createClient(remoteHostName, remotePort, httpVersion, isHttps,
applicationProtocols, isConnect, proxyServer, upStreamEndPoint, externalProxy, cancellationToken); applicationProtocols, isConnect, proxyServer, upStreamEndPoint, externalProxy, cancellationToken);
connection.CacheKey = cacheKey; connection.CacheKey = cacheKey;
...@@ -121,7 +121,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -121,7 +121,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <param name="externalProxy">The external proxy to make request via.</param> /// <param name="externalProxy">The external proxy to make request via.</param>
/// <param name="cancellationToken">The cancellation token for this async task.</param> /// <param name="cancellationToken">The cancellation token for this async task.</param>
/// <returns></returns> /// <returns></returns>
private async Task<TcpServerConnection> CreateClient(string remoteHostName, int remotePort, private async Task<TcpServerConnection> createClient(string remoteHostName, int remotePort,
Version httpVersion, bool isHttps, List<SslApplicationProtocol> applicationProtocols, bool isConnect, Version httpVersion, bool isHttps, List<SslApplicationProtocol> applicationProtocols, bool isConnect,
ProxyServer proxyServer, IPEndPoint upStreamEndPoint, ExternalProxy externalProxy, ProxyServer proxyServer, IPEndPoint upStreamEndPoint, ExternalProxy externalProxy,
CancellationToken cancellationToken) CancellationToken cancellationToken)
...@@ -280,7 +280,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -280,7 +280,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
@lock.Release(); @lock.Release();
} }
private async Task ClearOutdatedConnections() private async Task clearOutdatedConnections()
{ {
while (runCleanUpTask) while (runCleanUpTask)
{ {
...@@ -326,7 +326,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -326,7 +326,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// </summary> /// </summary>
/// <param name="client"></param> /// <param name="client"></param>
/// <returns></returns> /// <returns></returns>
private static bool IsGoodConnection(TcpClient client) private static bool isGoodConnection(TcpClient client)
{ {
var socket = client.Client; var socket = client.Client;
......
...@@ -18,7 +18,7 @@ namespace Titanium.Web.Proxy ...@@ -18,7 +18,7 @@ namespace Titanium.Web.Proxy
/// </summary> /// </summary>
/// <param name="session">The session event arguments.</param> /// <param name="session">The session event arguments.</param>
/// <returns>True if authorized.</returns> /// <returns>True if authorized.</returns>
private async Task<bool> CheckAuthorization(SessionEventArgsBase session) private async Task<bool> checkAuthorization(SessionEventArgsBase session)
{ {
// If we are not authorizing clients return true // If we are not authorizing clients return true
if (AuthenticateUserFunc == null) if (AuthenticateUserFunc == null)
...@@ -33,7 +33,7 @@ namespace Titanium.Web.Proxy ...@@ -33,7 +33,7 @@ namespace Titanium.Web.Proxy
var header = httpHeaders.GetFirstHeader(KnownHeaders.ProxyAuthorization); var header = httpHeaders.GetFirstHeader(KnownHeaders.ProxyAuthorization);
if (header == null) if (header == null)
{ {
session.WebSession.Response = CreateAuthentication407Response("Proxy Authentication Required"); session.WebSession.Response = createAuthentication407Response("Proxy Authentication Required");
return false; return false;
} }
...@@ -42,7 +42,7 @@ namespace Titanium.Web.Proxy ...@@ -42,7 +42,7 @@ namespace Titanium.Web.Proxy
!headerValueParts[0].EqualsIgnoreCase(KnownHeaders.ProxyAuthorizationBasic)) !headerValueParts[0].EqualsIgnoreCase(KnownHeaders.ProxyAuthorizationBasic))
{ {
// Return not authorized // Return not authorized
session.WebSession.Response = CreateAuthentication407Response("Proxy Authentication Invalid"); session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid");
return false; return false;
} }
...@@ -51,7 +51,7 @@ namespace Titanium.Web.Proxy ...@@ -51,7 +51,7 @@ namespace Titanium.Web.Proxy
if (colonIndex == -1) if (colonIndex == -1)
{ {
// Return not authorized // Return not authorized
session.WebSession.Response = CreateAuthentication407Response("Proxy Authentication Invalid"); session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid");
return false; return false;
} }
...@@ -60,7 +60,7 @@ namespace Titanium.Web.Proxy ...@@ -60,7 +60,7 @@ namespace Titanium.Web.Proxy
bool authenticated = await AuthenticateUserFunc(username, password); bool authenticated = await AuthenticateUserFunc(username, password);
if (!authenticated) if (!authenticated)
{ {
session.WebSession.Response = CreateAuthentication407Response("Proxy Authentication Invalid"); session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid");
} }
return authenticated; return authenticated;
...@@ -71,7 +71,7 @@ namespace Titanium.Web.Proxy ...@@ -71,7 +71,7 @@ namespace Titanium.Web.Proxy
httpHeaders)); httpHeaders));
// Return not authorized // Return not authorized
session.WebSession.Response = CreateAuthentication407Response("Proxy Authentication Invalid"); session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid");
return false; return false;
} }
} }
...@@ -81,7 +81,7 @@ namespace Titanium.Web.Proxy ...@@ -81,7 +81,7 @@ namespace Titanium.Web.Proxy
/// </summary> /// </summary>
/// <param name="description">Response description.</param> /// <param name="description">Response description.</param>
/// <returns></returns> /// <returns></returns>
private Response CreateAuthentication407Response(string description) private Response createAuthentication407Response(string description)
{ {
var response = new Response var response = new Response
{ {
......
...@@ -314,7 +314,7 @@ namespace Titanium.Web.Proxy ...@@ -314,7 +314,7 @@ namespace Titanium.Web.Proxy
if (ProxyRunning) if (ProxyRunning)
{ {
Listen(endPoint); listen(endPoint);
} }
} }
...@@ -334,7 +334,7 @@ namespace Titanium.Web.Proxy ...@@ -334,7 +334,7 @@ namespace Titanium.Web.Proxy
if (ProxyRunning) if (ProxyRunning)
{ {
QuitListen(endPoint); quitListen(endPoint);
} }
} }
...@@ -368,7 +368,7 @@ namespace Titanium.Web.Proxy ...@@ -368,7 +368,7 @@ namespace Titanium.Web.Proxy
throw new Exception("Mono Runtime do not support system proxy settings."); throw new Exception("Mono Runtime do not support system proxy settings.");
} }
ValidateEndPointAsSystemProxy(endPoint); validateEndPointAsSystemProxy(endPoint);
bool isHttp = (protocolType & ProxyProtocolType.Http) > 0; bool isHttp = (protocolType & ProxyProtocolType.Http) > 0;
bool isHttps = (protocolType & ProxyProtocolType.Https) > 0; bool isHttps = (protocolType & ProxyProtocolType.Https) > 0;
...@@ -523,7 +523,7 @@ namespace Titanium.Web.Proxy ...@@ -523,7 +523,7 @@ namespace Titanium.Web.Proxy
systemProxyResolver = new WinHttpWebProxyFinder(); systemProxyResolver = new WinHttpWebProxyFinder();
systemProxyResolver.LoadFromIE(); systemProxyResolver.LoadFromIE();
GetCustomUpStreamProxyFunc = GetSystemUpStreamProxy; GetCustomUpStreamProxyFunc = getSystemUpStreamProxy;
} }
ProxyRunning = true; ProxyRunning = true;
...@@ -532,7 +532,7 @@ namespace Titanium.Web.Proxy ...@@ -532,7 +532,7 @@ namespace Titanium.Web.Proxy
foreach (var endPoint in ProxyEndPoints) foreach (var endPoint in ProxyEndPoints)
{ {
Listen(endPoint); listen(endPoint);
} }
} }
...@@ -559,7 +559,7 @@ namespace Titanium.Web.Proxy ...@@ -559,7 +559,7 @@ namespace Titanium.Web.Proxy
foreach (var endPoint in ProxyEndPoints) foreach (var endPoint in ProxyEndPoints)
{ {
QuitListen(endPoint); quitListen(endPoint);
} }
ProxyEndPoints.Clear(); ProxyEndPoints.Clear();
...@@ -574,7 +574,7 @@ namespace Titanium.Web.Proxy ...@@ -574,7 +574,7 @@ namespace Titanium.Web.Proxy
/// Listen on given end point of local machine. /// Listen on given end point of local machine.
/// </summary> /// </summary>
/// <param name="endPoint">The end point to listen.</param> /// <param name="endPoint">The end point to listen.</param>
private void Listen(ProxyEndPoint endPoint) private void listen(ProxyEndPoint endPoint)
{ {
endPoint.Listener = new TcpListener(endPoint.IpAddress, endPoint.Port); endPoint.Listener = new TcpListener(endPoint.IpAddress, endPoint.Port);
try try
...@@ -584,7 +584,7 @@ namespace Titanium.Web.Proxy ...@@ -584,7 +584,7 @@ namespace Titanium.Web.Proxy
endPoint.Port = ((IPEndPoint)endPoint.Listener.LocalEndpoint).Port; endPoint.Port = ((IPEndPoint)endPoint.Listener.LocalEndpoint).Port;
// accept clients asynchronously // accept clients asynchronously
endPoint.Listener.BeginAcceptTcpClient(OnAcceptConnection, endPoint); endPoint.Listener.BeginAcceptTcpClient(onAcceptConnection, endPoint);
} }
catch (SocketException ex) catch (SocketException ex)
{ {
...@@ -600,7 +600,7 @@ namespace Titanium.Web.Proxy ...@@ -600,7 +600,7 @@ namespace Titanium.Web.Proxy
/// Verify if its safe to set this end point as system proxy. /// Verify if its safe to set this end point as system proxy.
/// </summary> /// </summary>
/// <param name="endPoint">The end point to validate.</param> /// <param name="endPoint">The end point to validate.</param>
private void ValidateEndPointAsSystemProxy(ExplicitProxyEndPoint endPoint) private void validateEndPointAsSystemProxy(ExplicitProxyEndPoint endPoint)
{ {
if (endPoint == null) if (endPoint == null)
{ {
...@@ -623,7 +623,7 @@ namespace Titanium.Web.Proxy ...@@ -623,7 +623,7 @@ namespace Titanium.Web.Proxy
/// </summary> /// </summary>
/// <param name="sessionEventArgs">The session.</param> /// <param name="sessionEventArgs">The session.</param>
/// <returns>The external proxy as task result.</returns> /// <returns>The external proxy as task result.</returns>
private Task<ExternalProxy> GetSystemUpStreamProxy(SessionEventArgsBase sessionEventArgs) private Task<ExternalProxy> getSystemUpStreamProxy(SessionEventArgsBase sessionEventArgs)
{ {
var proxy = systemProxyResolver.GetProxy(sessionEventArgs.WebSession.Request.RequestUri); var proxy = systemProxyResolver.GetProxy(sessionEventArgs.WebSession.Request.RequestUri);
return Task.FromResult(proxy); return Task.FromResult(proxy);
...@@ -632,7 +632,7 @@ namespace Titanium.Web.Proxy ...@@ -632,7 +632,7 @@ namespace Titanium.Web.Proxy
/// <summary> /// <summary>
/// Act when a connection is received from client. /// Act when a connection is received from client.
/// </summary> /// </summary>
private void OnAcceptConnection(IAsyncResult asyn) private void onAcceptConnection(IAsyncResult asyn)
{ {
var endPoint = (ProxyEndPoint)asyn.AsyncState; var endPoint = (ProxyEndPoint)asyn.AsyncState;
...@@ -657,11 +657,11 @@ namespace Titanium.Web.Proxy ...@@ -657,11 +657,11 @@ namespace Titanium.Web.Proxy
if (tcpClient != null) if (tcpClient != null)
{ {
Task.Run(async () => { await HandleClient(tcpClient, endPoint); }); Task.Run(async () => { await handleClient(tcpClient, endPoint); });
} }
// Get the listener that handles the client request. // Get the listener that handles the client request.
endPoint.Listener.BeginAcceptTcpClient(OnAcceptConnection, endPoint); endPoint.Listener.BeginAcceptTcpClient(onAcceptConnection, endPoint);
} }
/// <summary> /// <summary>
...@@ -670,7 +670,7 @@ namespace Titanium.Web.Proxy ...@@ -670,7 +670,7 @@ namespace Titanium.Web.Proxy
/// <param name="tcpClient">The client.</param> /// <param name="tcpClient">The client.</param>
/// <param name="endPoint">The proxy endpoint.</param> /// <param name="endPoint">The proxy endpoint.</param>
/// <returns>The task.</returns> /// <returns>The task.</returns>
private async Task HandleClient(TcpClient tcpClient, ProxyEndPoint endPoint) private async Task handleClient(TcpClient tcpClient, ProxyEndPoint endPoint)
{ {
tcpClient.ReceiveTimeout = ConnectionTimeOutSeconds * 1000; tcpClient.ReceiveTimeout = ConnectionTimeOutSeconds * 1000;
tcpClient.SendTimeout = ConnectionTimeOutSeconds * 1000; tcpClient.SendTimeout = ConnectionTimeOutSeconds * 1000;
...@@ -683,11 +683,11 @@ namespace Titanium.Web.Proxy ...@@ -683,11 +683,11 @@ namespace Titanium.Web.Proxy
{ {
if (endPoint is TransparentProxyEndPoint tep) if (endPoint is TransparentProxyEndPoint tep)
{ {
await HandleClient(tep, clientConnection); await handleClient(tep, clientConnection);
} }
else else
{ {
await HandleClient((ExplicitProxyEndPoint)endPoint, clientConnection); await handleClient((ExplicitProxyEndPoint)endPoint, clientConnection);
} }
} }
} }
...@@ -697,7 +697,7 @@ namespace Titanium.Web.Proxy ...@@ -697,7 +697,7 @@ namespace Titanium.Web.Proxy
/// </summary> /// </summary>
/// <param name="clientStream">The client stream.</param> /// <param name="clientStream">The client stream.</param>
/// <param name="exception">The exception.</param> /// <param name="exception">The exception.</param>
private void OnException(CustomBufferedStream clientStream, Exception exception) private void onException(CustomBufferedStream clientStream, Exception exception)
{ {
#if DEBUG #if DEBUG
if (clientStream is DebugCustomBufferedStream debugStream) if (clientStream is DebugCustomBufferedStream debugStream)
...@@ -712,7 +712,7 @@ namespace Titanium.Web.Proxy ...@@ -712,7 +712,7 @@ namespace Titanium.Web.Proxy
/// <summary> /// <summary>
/// Quit listening on the given end point. /// Quit listening on the given end point.
/// </summary> /// </summary>
private void QuitListen(ProxyEndPoint endPoint) private void quitListen(ProxyEndPoint endPoint)
{ {
endPoint.Listener.Stop(); endPoint.Listener.Stop();
endPoint.Listener.Server.Dispose(); endPoint.Listener.Server.Dispose();
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Text; using System.Text;
...@@ -33,7 +34,7 @@ namespace Titanium.Web.Proxy ...@@ -33,7 +34,7 @@ namespace Titanium.Web.Proxy
private bool isWindowsAuthenticationEnabledAndSupported => private bool isWindowsAuthenticationEnabledAndSupported =>
EnableWinAuth && RunTime.IsWindows && !RunTime.IsRunningOnMono; EnableWinAuth && RunTime.IsWindows && !RunTime.IsRunningOnMono;
/// <summary> /// <summary>
/// This is the core request handler method for a particular connection from client. /// This is the core request handler method for a particular connection from client.
/// Will create new session (request/response) sequence until /// Will create new session (request/response) sequence until
...@@ -49,7 +50,7 @@ namespace Titanium.Web.Proxy ...@@ -49,7 +50,7 @@ namespace Titanium.Web.Proxy
/// explicit endpoint. /// explicit endpoint.
/// </param> /// </param>
/// <param name="connectRequest">The Connect request if this is a HTTPS request from explicit endpoint.</param> /// <param name="connectRequest">The Connect request if this is a HTTPS request from explicit endpoint.</param>
private async Task HandleHttpSessionRequest(ProxyEndPoint endPoint, TcpClientConnection clientConnection, private async Task handleHttpSessionRequest(ProxyEndPoint endPoint, TcpClientConnection clientConnection,
CustomBufferedStream clientStream, HttpResponseWriter clientStreamWriter, CustomBufferedStream clientStream, HttpResponseWriter clientStreamWriter,
CancellationTokenSource cancellationTokenSource, string httpsConnectHostname, ConnectRequest connectRequest) CancellationTokenSource cancellationTokenSource, string httpsConnectHostname, ConnectRequest connectRequest)
{ {
...@@ -133,9 +134,9 @@ namespace Titanium.Web.Proxy ...@@ -133,9 +134,9 @@ namespace Titanium.Web.Proxy
if (!args.IsTransparent) if (!args.IsTransparent)
{ {
// proxy authorization check // proxy authorization check
if (httpsConnectHostname == null && await CheckAuthorization(args) == false) if (httpsConnectHostname == null && await checkAuthorization(args) == false)
{ {
await InvokeBeforeResponse(args); await invokeBeforeResponse(args);
// send the response // send the response
await clientStreamWriter.WriteResponseAsync(args.WebSession.Response, await clientStreamWriter.WriteResponseAsync(args.WebSession.Response,
...@@ -143,7 +144,7 @@ namespace Titanium.Web.Proxy ...@@ -143,7 +144,7 @@ namespace Titanium.Web.Proxy
return; return;
} }
PrepareRequestHeaders(request.Headers); prepareRequestHeaders(request.Headers);
request.Host = request.RequestUri.Authority; request.Host = request.RequestUri.Authority;
} }
...@@ -158,7 +159,7 @@ namespace Titanium.Web.Proxy ...@@ -158,7 +159,7 @@ namespace Titanium.Web.Proxy
request.OriginalHasBody = request.HasBody; request.OriginalHasBody = request.HasBody;
// If user requested interception do it // If user requested interception do it
await InvokeBeforeRequest(args); await invokeBeforeRequest(args);
var response = args.WebSession.Response; var response = args.WebSession.Response;
...@@ -167,7 +168,7 @@ namespace Titanium.Web.Proxy ...@@ -167,7 +168,7 @@ namespace Titanium.Web.Proxy
// syphon out the request body from client before setting the new body // syphon out the request body from client before setting the new body
await args.SyphonOutBodyAsync(true, cancellationToken); await args.SyphonOutBodyAsync(true, cancellationToken);
await HandleHttpSessionResponse(args); await handleHttpSessionResponse(args);
if (!response.KeepAlive) if (!response.KeepAlive)
{ {
...@@ -187,53 +188,49 @@ namespace Titanium.Web.Proxy ...@@ -187,53 +188,49 @@ namespace Titanium.Web.Proxy
serverConnection = null; serverConnection = null;
} }
var connectionChanged = false;
if (serverConnection == null) if (serverConnection == null)
{ {
serverConnection = await GetServerConnection(args, false, clientConnection.NegotiatedApplicationProtocol, cancellationToken); serverConnection = await getServerConnection(args, false, clientConnection.NegotiatedApplicationProtocol, cancellationToken);
connectionChanged = true;
} }
// if upgrading to websocket then relay the requet without reading the contents var attemt = 0;
if (request.UpgradeToWebSocket) //for connection pool retry
while (attemt < 3)
{ {
// prepare the prefix content try
await serverConnection.StreamWriter.WriteLineAsync(httpCmd, cancellationToken);
await serverConnection.StreamWriter.WriteHeadersAsync(request.Headers,
cancellationToken: cancellationToken);
string httpStatus = await serverConnection.Stream.ReadLineAsync(cancellationToken);
Response.ParseResponseLine(httpStatus, out var responseVersion,
out int responseStatusCode,
out string responseStatusDescription);
response.HttpVersion = responseVersion;
response.StatusCode = responseStatusCode;
response.StatusDescription = responseStatusDescription;
await HeaderParser.ReadHeaders(serverConnection.Stream, response.Headers,
cancellationToken);
if (!args.IsTransparent)
{ {
await clientStreamWriter.WriteResponseAsync(response, // if upgrading to websocket then relay the requet without reading the contents
cancellationToken: cancellationToken); if (request.UpgradeToWebSocket)
{
await handleWebSocketUpgrade(httpCmd, args, request,
response, clientStream, clientStreamWriter,
serverConnection, cancellationTokenSource, cancellationToken);
return;
}
// construct the web request that we are going to issue on behalf of the client.
await handleHttpSessionRequestInternal(serverConnection, args);
} }
//connection pool retry
// If user requested call back then do it catch (ServerConnectionException)
if (!args.WebSession.Response.Locked)
{ {
await InvokeBeforeResponse(args); if (!connectionChanged || !EnableConnectionPool || attemt == 3)
{
throw;
}
//get new connection from pool
tcpConnectionFactory.Release(serverConnection, true);
serverConnection = await getServerConnection(args, false, clientConnection.NegotiatedApplicationProtocol, cancellationToken);
attemt++;
continue;
} }
await TcpHelper.SendRaw(clientStream, serverConnection.Stream, BufferSize, break;
(buffer, offset, count) => { args.OnDataSent(buffer, offset, count); },
(buffer, offset, count) => { args.OnDataReceived(buffer, offset, count); },
cancellationTokenSource, ExceptionFunc);
return;
} }
// construct the web request that we are going to issue on behalf of the client.
await HandleHttpSessionRequestInternal(serverConnection, args);
if (args.WebSession.ServerConnection == null) if (args.WebSession.ServerConnection == null)
{ {
return; return;
...@@ -264,7 +261,7 @@ namespace Titanium.Web.Proxy ...@@ -264,7 +261,7 @@ namespace Titanium.Web.Proxy
} }
finally finally
{ {
await InvokeAfterResponse(args); await invokeAfterResponse(args);
args.Dispose(); args.Dispose();
} }
} }
...@@ -281,83 +278,77 @@ namespace Titanium.Web.Proxy ...@@ -281,83 +278,77 @@ namespace Titanium.Web.Proxy
/// <param name="serverConnection">The tcp connection.</param> /// <param name="serverConnection">The tcp connection.</param>
/// <param name="args">The session event arguments.</param> /// <param name="args">The session event arguments.</param>
/// <returns></returns> /// <returns></returns>
private async Task HandleHttpSessionRequestInternal(TcpServerConnection serverConnection, SessionEventArgs args) private async Task handleHttpSessionRequestInternal(TcpServerConnection serverConnection, SessionEventArgs args)
{ {
try var cancellationToken = args.CancellationTokenSource.Token;
var request = args.WebSession.Request;
request.Locked = true;
var body = request.CompressBodyAndUpdateContentLength();
// if expect continue is enabled then send the headers first
// and see if server would return 100 conitinue
if (request.ExpectContinue)
{ {
var cancellationToken = args.CancellationTokenSource.Token; args.WebSession.SetConnection(serverConnection);
var request = args.WebSession.Request; await args.WebSession.SendRequest(Enable100ContinueBehaviour, args.IsTransparent,
request.Locked = true; cancellationToken);
}
var body = request.CompressBodyAndUpdateContentLength(); // If 100 continue was the response inform that to the client
if (Enable100ContinueBehaviour)
{
var clientStreamWriter = args.ProxyClient.ClientStreamWriter;
// if expect continue is enabled then send the headers first if (request.Is100Continue)
// and see if server would return 100 conitinue
if (request.ExpectContinue)
{ {
args.WebSession.SetConnection(serverConnection); await clientStreamWriter.WriteResponseStatusAsync(args.WebSession.Response.HttpVersion,
await args.WebSession.SendRequest(Enable100ContinueBehaviour, args.IsTransparent, (int)HttpStatusCode.Continue, "Continue", cancellationToken);
cancellationToken); await clientStreamWriter.WriteLineAsync(cancellationToken);
} }
else if (request.ExpectationFailed)
// If 100 continue was the response inform that to the client
if (Enable100ContinueBehaviour)
{ {
var clientStreamWriter = args.ProxyClient.ClientStreamWriter; await clientStreamWriter.WriteResponseStatusAsync(args.WebSession.Response.HttpVersion,
(int)HttpStatusCode.ExpectationFailed, "Expectation Failed", cancellationToken);
if (request.Is100Continue) await clientStreamWriter.WriteLineAsync(cancellationToken);
{
await clientStreamWriter.WriteResponseStatusAsync(args.WebSession.Response.HttpVersion,
(int)HttpStatusCode.Continue, "Continue", cancellationToken);
await clientStreamWriter.WriteLineAsync(cancellationToken);
}
else if (request.ExpectationFailed)
{
await clientStreamWriter.WriteResponseStatusAsync(args.WebSession.Response.HttpVersion,
(int)HttpStatusCode.ExpectationFailed, "Expectation Failed", cancellationToken);
await clientStreamWriter.WriteLineAsync(cancellationToken);
}
} }
}
// If expect continue is not enabled then set the connectio and send request headers
if (!request.ExpectContinue)
{
args.WebSession.SetConnection(serverConnection);
await args.WebSession.SendRequest(Enable100ContinueBehaviour, args.IsTransparent,
cancellationToken);
}
// If expect continue is not enabled then set the connectio and send request headers // check if content-length is > 0
if (!request.ExpectContinue) if (request.ContentLength > 0)
{
if (request.IsBodyRead)
{ {
args.WebSession.SetConnection(serverConnection); var writer = args.WebSession.ServerConnection.StreamWriter;
await args.WebSession.SendRequest(Enable100ContinueBehaviour, args.IsTransparent, await writer.WriteBodyAsync(body, request.IsChunked, cancellationToken);
cancellationToken);
} }
else
// check if content-length is > 0
if (request.ContentLength > 0)
{ {
if (request.IsBodyRead) if (!request.ExpectationFailed)
{
var writer = args.WebSession.ServerConnection.StreamWriter;
await writer.WriteBodyAsync(body, request.IsChunked, cancellationToken);
}
else
{ {
if (!request.ExpectationFailed) if (request.HasBody)
{ {
if (request.HasBody) HttpWriter writer = args.WebSession.ServerConnection.StreamWriter;
{ await args.CopyRequestBodyAsync(writer, TransformationMode.None, cancellationToken);
HttpWriter writer = args.WebSession.ServerConnection.StreamWriter;
await args.CopyRequestBodyAsync(writer, TransformationMode.None, cancellationToken);
}
} }
} }
} }
// If not expectation failed response was returned by server then parse response
if (!request.ExpectationFailed)
{
await HandleHttpSessionResponse(args);
}
} }
catch (Exception e) when (!(e is ProxyHttpException))
// If not expectation failed response was returned by server then parse response
if (!request.ExpectationFailed)
{ {
throw new ProxyHttpException("Error occured whilst handling session request (internal)", e, args); await handleHttpSessionResponse(args);
} }
} }
/// <summary> /// <summary>
...@@ -368,7 +359,7 @@ namespace Titanium.Web.Proxy ...@@ -368,7 +359,7 @@ namespace Titanium.Web.Proxy
/// <param name="applicationProtocol"></param> /// <param name="applicationProtocol"></param>
/// <param name="cancellationToken">The cancellation token for this async task.</param> /// <param name="cancellationToken">The cancellation token for this async task.</param>
/// <returns></returns> /// <returns></returns>
private Task<TcpServerConnection> GetServerConnection(SessionEventArgsBase args, bool isConnect, private Task<TcpServerConnection> getServerConnection(SessionEventArgsBase args, bool isConnect,
SslApplicationProtocol applicationProtocol, CancellationToken cancellationToken) SslApplicationProtocol applicationProtocol, CancellationToken cancellationToken)
{ {
List<SslApplicationProtocol> applicationProtocols = null; List<SslApplicationProtocol> applicationProtocols = null;
...@@ -377,7 +368,7 @@ namespace Titanium.Web.Proxy ...@@ -377,7 +368,7 @@ namespace Titanium.Web.Proxy
applicationProtocols = new List<SslApplicationProtocol> { applicationProtocol }; applicationProtocols = new List<SslApplicationProtocol> { applicationProtocol };
} }
return GetServerConnection(args, isConnect, applicationProtocols, cancellationToken); return getServerConnection(args, isConnect, applicationProtocols, cancellationToken);
} }
/// <summary> /// <summary>
...@@ -388,7 +379,7 @@ namespace Titanium.Web.Proxy ...@@ -388,7 +379,7 @@ namespace Titanium.Web.Proxy
/// <param name="applicationProtocols"></param> /// <param name="applicationProtocols"></param>
/// <param name="cancellationToken">The cancellation token for this async task.</param> /// <param name="cancellationToken">The cancellation token for this async task.</param>
/// <returns></returns> /// <returns></returns>
private async Task<TcpServerConnection> GetServerConnection(SessionEventArgsBase args, bool isConnect, private async Task<TcpServerConnection> getServerConnection(SessionEventArgsBase args, bool isConnect,
List<SslApplicationProtocol> applicationProtocols, CancellationToken cancellationToken) List<SslApplicationProtocol> applicationProtocols, CancellationToken cancellationToken)
{ {
ExternalProxy customUpStreamProxy = null; ExternalProxy customUpStreamProxy = null;
...@@ -404,7 +395,7 @@ namespace Titanium.Web.Proxy ...@@ -404,7 +395,7 @@ namespace Titanium.Web.Proxy
return await tcpConnectionFactory.GetClient( return await tcpConnectionFactory.GetClient(
args.WebSession.Request.RequestUri.Host, args.WebSession.Request.RequestUri.Host,
args.WebSession.Request.RequestUri.Port, args.WebSession.Request.RequestUri.Port,
args.WebSession.Request.HttpVersion, args.WebSession.Request.HttpVersion,
isHttps, applicationProtocols, isConnect, isHttps, applicationProtocols, isConnect,
this, args.WebSession.UpStreamEndPoint ?? UpStreamEndPoint, this, args.WebSession.UpStreamEndPoint ?? UpStreamEndPoint,
customUpStreamProxy ?? (isHttps ? UpStreamHttpsProxy : UpStreamHttpProxy), customUpStreamProxy ?? (isHttps ? UpStreamHttpsProxy : UpStreamHttpProxy),
...@@ -414,7 +405,7 @@ namespace Titanium.Web.Proxy ...@@ -414,7 +405,7 @@ namespace Titanium.Web.Proxy
/// <summary> /// <summary>
/// Prepare the request headers so that we can avoid encodings not parsable by this proxy /// Prepare the request headers so that we can avoid encodings not parsable by this proxy
/// </summary> /// </summary>
private void PrepareRequestHeaders(HeaderCollection requestHeaders) private void prepareRequestHeaders(HeaderCollection requestHeaders)
{ {
var acceptEncoding = requestHeaders.GetHeaderValueOrNull(KnownHeaders.AcceptEncoding); var acceptEncoding = requestHeaders.GetHeaderValueOrNull(KnownHeaders.AcceptEncoding);
...@@ -436,12 +427,69 @@ namespace Titanium.Web.Proxy ...@@ -436,12 +427,69 @@ namespace Titanium.Web.Proxy
requestHeaders.FixProxyHeaders(); requestHeaders.FixProxyHeaders();
} }
/// <summary>
/// Handle upgrade to websocket
/// </summary>
private async Task handleWebSocketUpgrade(string httpCmd,
SessionEventArgs args, Request request, Response response,
CustomBufferedStream clientStream, HttpResponseWriter clientStreamWriter,
TcpServerConnection serverConnection,
CancellationTokenSource cancellationTokenSource, CancellationToken cancellationToken)
{
// prepare the prefix content
await serverConnection.StreamWriter.WriteLineAsync(httpCmd, cancellationToken);
await serverConnection.StreamWriter.WriteHeadersAsync(request.Headers,
cancellationToken: cancellationToken);
string httpStatus;
try
{
httpStatus = await serverConnection.Stream.ReadLineAsync(cancellationToken);
if (httpStatus == null)
{
throw new ServerConnectionException("Server connection was closed.");
}
}
catch (Exception e) when (!(e is ServerConnectionException))
{
throw new ServerConnectionException("Server connection was closed.", e);
}
Response.ParseResponseLine(httpStatus, out var responseVersion,
out int responseStatusCode,
out string responseStatusDescription);
response.HttpVersion = responseVersion;
response.StatusCode = responseStatusCode;
response.StatusDescription = responseStatusDescription;
await HeaderParser.ReadHeaders(serverConnection.Stream, response.Headers,
cancellationToken);
if (!args.IsTransparent)
{
await clientStreamWriter.WriteResponseAsync(response,
cancellationToken: cancellationToken);
}
// If user requested call back then do it
if (!args.WebSession.Response.Locked)
{
await invokeBeforeResponse(args);
}
await TcpHelper.SendRaw(clientStream, serverConnection.Stream, BufferSize,
(buffer, offset, count) => { args.OnDataSent(buffer, offset, count); },
(buffer, offset, count) => { args.OnDataReceived(buffer, offset, count); },
cancellationTokenSource, ExceptionFunc);
}
/// <summary> /// <summary>
/// Invoke before request handler if it is set. /// Invoke before request handler if it is set.
/// </summary> /// </summary>
/// <param name="args">The session event arguments.</param> /// <param name="args">The session event arguments.</param>
/// <returns></returns> /// <returns></returns>
private async Task InvokeBeforeRequest(SessionEventArgs args) private async Task invokeBeforeRequest(SessionEventArgs args)
{ {
if (BeforeRequest != null) if (BeforeRequest != null)
{ {
......
using System; using System.Net;
using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments; using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Exceptions;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Network.WinAuth.Security; using Titanium.Web.Proxy.Network.WinAuth.Security;
...@@ -18,116 +16,111 @@ namespace Titanium.Web.Proxy ...@@ -18,116 +16,111 @@ namespace Titanium.Web.Proxy
/// </summary> /// </summary>
/// <param name="args">The session event arguments.</param> /// <param name="args">The session event arguments.</param>
/// <returns> The task.</returns> /// <returns> The task.</returns>
private async Task HandleHttpSessionResponse(SessionEventArgs args) private async Task handleHttpSessionResponse(SessionEventArgs args)
{ {
try
{
var cancellationToken = args.CancellationTokenSource.Token;
// read response & headers from server
await args.WebSession.ReceiveResponse(cancellationToken);
var response = args.WebSession.Response; var cancellationToken = args.CancellationTokenSource.Token;
args.ReRequest = false;
// check for windows authentication // read response & headers from server
if (isWindowsAuthenticationEnabledAndSupported) await args.WebSession.ReceiveResponse(cancellationToken);
{
if (response.StatusCode == (int)HttpStatusCode.Unauthorized)
{
await Handle401UnAuthorized(args);
}
else
{
WinAuthEndPoint.AuthenticatedResponse(args.WebSession.Data);
}
}
response.OriginalHasBody = response.HasBody; var response = args.WebSession.Response;
args.ReRequest = false;
// if user requested call back then do it // check for windows authentication
if (!response.Locked) if (isWindowsAuthenticationEnabledAndSupported)
{
if (response.StatusCode == (int)HttpStatusCode.Unauthorized)
{ {
await InvokeBeforeResponse(args); await handle401UnAuthorized(args);
} }
else
// it may changed in the user event
response = args.WebSession.Response;
var clientStreamWriter = args.ProxyClient.ClientStreamWriter;
if (response.TerminateResponse || response.Locked)
{ {
await clientStreamWriter.WriteResponseAsync(response, cancellationToken: cancellationToken); WinAuthEndPoint.AuthenticatedResponse(args.WebSession.Data);
if (!response.TerminateResponse)
{
// syphon out the response body from server before setting the new body
await args.SyphonOutBodyAsync(false, cancellationToken);
}
else
{
tcpConnectionFactory.Release(args.WebSession.ServerConnection, true);
args.WebSession.ServerConnection = null;
}
return;
} }
}
// if user requested to send request again response.OriginalHasBody = response.HasBody;
// likely after making modifications from User Response Handler
if (args.ReRequest)
{
// clear current response
await args.ClearResponse(cancellationToken);
await HandleHttpSessionRequestInternal(args.WebSession.ServerConnection, args);
return;
}
response.Locked = true; // if user requested call back then do it
if (!response.Locked)
{
await invokeBeforeResponse(args);
}
// Write back to client 100-conitinue response if that's what server returned // it may changed in the user event
if (response.Is100Continue) response = args.WebSession.Response;
{
await clientStreamWriter.WriteResponseStatusAsync(response.HttpVersion,
(int)HttpStatusCode.Continue, "Continue", cancellationToken);
await clientStreamWriter.WriteLineAsync(cancellationToken);
}
else if (response.ExpectationFailed)
{
await clientStreamWriter.WriteResponseStatusAsync(response.HttpVersion,
(int)HttpStatusCode.ExpectationFailed, "Expectation Failed", cancellationToken);
await clientStreamWriter.WriteLineAsync(cancellationToken);
}
if (!args.IsTransparent) var clientStreamWriter = args.ProxyClient.ClientStreamWriter;
{
response.Headers.FixProxyHeaders(); if (response.TerminateResponse || response.Locked)
} {
await clientStreamWriter.WriteResponseAsync(response, cancellationToken: cancellationToken);
if (response.IsBodyRead) if (!response.TerminateResponse)
{ {
await clientStreamWriter.WriteResponseAsync(response, cancellationToken: cancellationToken); // syphon out the response body from server before setting the new body
await args.SyphonOutBodyAsync(false, cancellationToken);
} }
else else
{ {
// Write back response status to client tcpConnectionFactory.Release(args.WebSession.ServerConnection, true);
await clientStreamWriter.WriteResponseStatusAsync(response.HttpVersion, response.StatusCode, args.WebSession.ServerConnection = null;
response.StatusDescription, cancellationToken);
await clientStreamWriter.WriteHeadersAsync(response.Headers, cancellationToken: cancellationToken);
// Write body if exists
if (response.HasBody)
{
await args.CopyResponseBodyAsync(clientStreamWriter, TransformationMode.None,
cancellationToken);
}
} }
return;
}
// if user requested to send request again
// likely after making modifications from User Response Handler
if (args.ReRequest)
{
// clear current response
await args.ClearResponse(cancellationToken);
await handleHttpSessionRequestInternal(args.WebSession.ServerConnection, args);
return;
}
response.Locked = true;
// Write back to client 100-conitinue response if that's what server returned
if (response.Is100Continue)
{
await clientStreamWriter.WriteResponseStatusAsync(response.HttpVersion,
(int)HttpStatusCode.Continue, "Continue", cancellationToken);
await clientStreamWriter.WriteLineAsync(cancellationToken);
}
else if (response.ExpectationFailed)
{
await clientStreamWriter.WriteResponseStatusAsync(response.HttpVersion,
(int)HttpStatusCode.ExpectationFailed, "Expectation Failed", cancellationToken);
await clientStreamWriter.WriteLineAsync(cancellationToken);
} }
catch (Exception e) when (!(e is ProxyHttpException))
if (!args.IsTransparent)
{
response.Headers.FixProxyHeaders();
}
if (response.IsBodyRead)
{
await clientStreamWriter.WriteResponseAsync(response, cancellationToken: cancellationToken);
}
else
{ {
throw new ProxyHttpException("Error occured whilst handling session response", e, args); // Write back response status to client
await clientStreamWriter.WriteResponseStatusAsync(response.HttpVersion, response.StatusCode,
response.StatusDescription, cancellationToken);
await clientStreamWriter.WriteHeadersAsync(response.Headers, cancellationToken: cancellationToken);
// Write body if exists
if (response.HasBody)
{
await args.CopyResponseBodyAsync(clientStreamWriter, TransformationMode.None,
cancellationToken);
}
} }
} }
/// <summary> /// <summary>
...@@ -135,7 +128,7 @@ namespace Titanium.Web.Proxy ...@@ -135,7 +128,7 @@ namespace Titanium.Web.Proxy
/// </summary> /// </summary>
/// <param name="args"></param> /// <param name="args"></param>
/// <returns></returns> /// <returns></returns>
private async Task InvokeBeforeResponse(SessionEventArgs args) private async Task invokeBeforeResponse(SessionEventArgs args)
{ {
if (BeforeResponse != null) if (BeforeResponse != null)
{ {
...@@ -148,7 +141,7 @@ namespace Titanium.Web.Proxy ...@@ -148,7 +141,7 @@ namespace Titanium.Web.Proxy
/// </summary> /// </summary>
/// <param name="args"></param> /// <param name="args"></param>
/// <returns></returns> /// <returns></returns>
private async Task InvokeAfterResponse(SessionEventArgs args) private async Task invokeAfterResponse(SessionEventArgs args)
{ {
if (AfterResponse != null) if (AfterResponse != null)
{ {
......
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net.Security; using System.Net.Security;
using System.Net.Sockets; using System.Net.Sockets;
...@@ -27,7 +26,7 @@ namespace Titanium.Web.Proxy ...@@ -27,7 +26,7 @@ namespace Titanium.Web.Proxy
/// <param name="endPoint">The transparent endpoint.</param> /// <param name="endPoint">The transparent endpoint.</param>
/// <param name="clientConnection">The client connection.</param> /// <param name="clientConnection">The client connection.</param>
/// <returns></returns> /// <returns></returns>
private async Task HandleClient(TransparentProxyEndPoint endPoint, TcpClientConnection clientConnection) private async Task handleClient(TransparentProxyEndPoint endPoint, TcpClientConnection clientConnection)
{ {
var cancellationTokenSource = new CancellationTokenSource(); var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token; var cancellationToken = cancellationTokenSource.Token;
...@@ -125,24 +124,24 @@ namespace Titanium.Web.Proxy ...@@ -125,24 +124,24 @@ namespace Titanium.Web.Proxy
// HTTPS server created - we can now decrypt the client's traffic // HTTPS server created - we can now decrypt the client's traffic
// Now create the request // Now create the request
await HandleHttpSessionRequest(endPoint, clientConnection, clientStream, clientStreamWriter, await handleHttpSessionRequest(endPoint, clientConnection, clientStream, clientStreamWriter,
cancellationTokenSource, isHttps ? httpsHostName : null, null); cancellationTokenSource, isHttps ? httpsHostName : null, null);
} }
catch (ProxyException e) catch (ProxyException e)
{ {
OnException(clientStream, e); onException(clientStream, e);
} }
catch (IOException e) catch (IOException e)
{ {
OnException(clientStream, new Exception("Connection was aborted", e)); onException(clientStream, new Exception("Connection was aborted", e));
} }
catch (SocketException e) catch (SocketException e)
{ {
OnException(clientStream, new Exception("Could not connect", e)); onException(clientStream, new Exception("Could not connect", e));
} }
catch (Exception e) catch (Exception e)
{ {
OnException(clientStream, new Exception("Error occured in whilst handling the client", e)); onException(clientStream, new Exception("Error occured in whilst handling the client", e));
} }
finally finally
{ {
......
...@@ -45,7 +45,7 @@ namespace Titanium.Web.Proxy ...@@ -45,7 +45,7 @@ namespace Titanium.Web.Proxy
/// User to server to authenticate requests. /// User to server to authenticate requests.
/// To disable this set ProxyServer.EnableWinAuth to false. /// To disable this set ProxyServer.EnableWinAuth to false.
/// </summary> /// </summary>
internal async Task Handle401UnAuthorized(SessionEventArgs args) private async Task handle401UnAuthorized(SessionEventArgs args)
{ {
string headerName = null; string headerName = null;
HttpHeader authHeader = null; HttpHeader authHeader = null;
...@@ -99,7 +99,7 @@ namespace Titanium.Web.Proxy ...@@ -99,7 +99,7 @@ namespace Titanium.Web.Proxy
if (!WinAuthEndPoint.ValidateWinAuthState(args.WebSession.Data, expectedAuthState)) if (!WinAuthEndPoint.ValidateWinAuthState(args.WebSession.Data, expectedAuthState))
{ {
// Invalid state, create proper error message to client // Invalid state, create proper error message to client
await RewriteUnauthorizedResponse(args); await rewriteUnauthorizedResponse(args);
return; return;
} }
...@@ -163,7 +163,7 @@ namespace Titanium.Web.Proxy ...@@ -163,7 +163,7 @@ namespace Titanium.Web.Proxy
/// </summary> /// </summary>
/// <param name="args"></param> /// <param name="args"></param>
/// <returns></returns> /// <returns></returns>
internal async Task RewriteUnauthorizedResponse(SessionEventArgs args) private async Task rewriteUnauthorizedResponse(SessionEventArgs args)
{ {
var response = args.WebSession.Response; var response = args.WebSession.Response;
......
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