Commit a7cab15f authored by justcoding121's avatar justcoding121

#519 handle change in hostname on ReRequest

parent 8311e6b5
...@@ -118,7 +118,7 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -118,7 +118,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
private async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e) private async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)
{ {
string hostname = e.WebSession.Request.RequestUri.Host; string hostname = e.HttpClient.Request.RequestUri.Host;
await WriteToConsole("Tunnel to: " + hostname); await WriteToConsole("Tunnel to: " + hostname);
if (hostname.Contains("dropbox.com")) if (hostname.Contains("dropbox.com"))
...@@ -139,7 +139,7 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -139,7 +139,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
private async Task OnRequest(object sender, SessionEventArgs e) private async Task OnRequest(object sender, SessionEventArgs e)
{ {
await WriteToConsole("Active Client Connections:" + ((ProxyServer)sender).ClientConnectionCount); await WriteToConsole("Active Client Connections:" + ((ProxyServer)sender).ClientConnectionCount);
await WriteToConsole(e.WebSession.Request.Url); await WriteToConsole(e.HttpClient.Request.Url);
// store it in the UserData property // store it in the UserData property
// It can be a simple integer, Guid, or any type // It can be a simple integer, Guid, or any type
...@@ -191,7 +191,7 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -191,7 +191,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
{ {
await WriteToConsole("Active Server Connections:" + ((ProxyServer)sender).ServerConnectionCount); await WriteToConsole("Active Server Connections:" + ((ProxyServer)sender).ServerConnectionCount);
string ext = System.IO.Path.GetExtension(e.WebSession.Request.RequestUri.AbsolutePath); string ext = System.IO.Path.GetExtension(e.HttpClient.Request.RequestUri.AbsolutePath);
//access user data set in request to do something with it //access user data set in request to do something with it
//var userData = e.WebSession.UserData as CustomUserData; //var userData = e.WebSession.UserData as CustomUserData;
......
...@@ -122,7 +122,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -122,7 +122,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
private async Task ProxyServer_BeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e) private async Task ProxyServer_BeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)
{ {
string hostname = e.WebSession.Request.RequestUri.Host; string hostname = e.HttpClient.Request.RequestUri.Host;
if (hostname.EndsWith("webex.com")) if (hostname.EndsWith("webex.com"))
{ {
e.DecryptSsl = false; e.DecryptSsl = false;
...@@ -135,7 +135,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -135,7 +135,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
{ {
await Dispatcher.InvokeAsync(() => await Dispatcher.InvokeAsync(() =>
{ {
if (sessionDictionary.TryGetValue(e.WebSession, out var item)) if (sessionDictionary.TryGetValue(e.HttpClient, out var item))
{ {
item.Update(); item.Update();
} }
...@@ -147,9 +147,9 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -147,9 +147,9 @@ namespace Titanium.Web.Proxy.Examples.Wpf
SessionListItem item = null; SessionListItem item = null;
await Dispatcher.InvokeAsync(() => { item = AddSession(e); }); await Dispatcher.InvokeAsync(() => { item = AddSession(e); });
if (e.WebSession.Request.HasBody) if (e.HttpClient.Request.HasBody)
{ {
e.WebSession.Request.KeepBody = true; e.HttpClient.Request.KeepBody = true;
await e.GetRequestBody(); await e.GetRequestBody();
} }
} }
...@@ -159,7 +159,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -159,7 +159,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
SessionListItem item = null; SessionListItem item = null;
await Dispatcher.InvokeAsync(() => await Dispatcher.InvokeAsync(() =>
{ {
if (sessionDictionary.TryGetValue(e.WebSession, out item)) if (sessionDictionary.TryGetValue(e.HttpClient, out item))
{ {
item.Update(); item.Update();
} }
...@@ -167,9 +167,9 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -167,9 +167,9 @@ namespace Titanium.Web.Proxy.Examples.Wpf
if (item != null) if (item != null)
{ {
if (e.WebSession.Response.HasBody) if (e.HttpClient.Response.HasBody)
{ {
e.WebSession.Response.KeepBody = true; e.HttpClient.Response.KeepBody = true;
await e.GetResponseBody(); await e.GetResponseBody();
await Dispatcher.InvokeAsync(() => { item.Update(); }); await Dispatcher.InvokeAsync(() => { item.Update(); });
...@@ -181,7 +181,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -181,7 +181,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
{ {
await Dispatcher.InvokeAsync(() => await Dispatcher.InvokeAsync(() =>
{ {
if (sessionDictionary.TryGetValue(e.WebSession, out var item)) if (sessionDictionary.TryGetValue(e.HttpClient, out var item))
{ {
item.Exception = e.Exception; item.Exception = e.Exception;
} }
...@@ -192,7 +192,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -192,7 +192,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
{ {
var item = CreateSessionListItem(e); var item = CreateSessionListItem(e);
Sessions.Add(item); Sessions.Add(item);
sessionDictionary.Add(e.WebSession, item); sessionDictionary.Add(e.HttpClient, item);
return item; return item;
} }
...@@ -203,16 +203,16 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -203,16 +203,16 @@ namespace Titanium.Web.Proxy.Examples.Wpf
var item = new SessionListItem var item = new SessionListItem
{ {
Number = lastSessionNumber, Number = lastSessionNumber,
WebSession = e.WebSession, WebSession = e.HttpClient,
IsTunnelConnect = isTunnelConnect IsTunnelConnect = isTunnelConnect
}; };
if (isTunnelConnect || e.WebSession.Request.UpgradeToWebSocket) if (isTunnelConnect || e.HttpClient.Request.UpgradeToWebSocket)
{ {
e.DataReceived += (sender, args) => e.DataReceived += (sender, args) =>
{ {
var session = (SessionEventArgs)sender; var session = (SessionEventArgs)sender;
if (sessionDictionary.TryGetValue(session.WebSession, out var li)) if (sessionDictionary.TryGetValue(session.HttpClient, out var li))
{ {
li.ReceivedDataCount += args.Count; li.ReceivedDataCount += args.Count;
} }
...@@ -221,7 +221,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -221,7 +221,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
e.DataSent += (sender, args) => e.DataSent += (sender, args) =>
{ {
var session = (SessionEventArgs)sender; var session = (SessionEventArgs)sender;
if (sessionDictionary.TryGetValue(session.WebSession, out var li)) if (sessionDictionary.TryGetValue(session.HttpClient, out var li))
{ {
li.SentDataCount += args.Count; li.SentDataCount += args.Count;
} }
......
...@@ -53,7 +53,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -53,7 +53,7 @@ namespace Titanium.Web.Proxy.EventArguments
get => reRequest; get => reRequest;
set set
{ {
if (WebSession.Response.StatusCode == 0) if (HttpClient.Response.StatusCode == 0)
{ {
throw new Exception("Response status code is empty. Cannot request again a request " + "which was never send to server."); throw new Exception("Response status code is empty. Cannot request again a request " + "which was never send to server.");
} }
...@@ -69,12 +69,12 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -69,12 +69,12 @@ namespace Titanium.Web.Proxy.EventArguments
private ICustomStreamReader getStreamReader(bool isRequest) private ICustomStreamReader getStreamReader(bool isRequest)
{ {
return isRequest ? ProxyClient.ClientStream : WebSession.ServerConnection.Stream; return isRequest ? ProxyClient.ClientStream : HttpClient.Connection.Stream;
} }
private HttpWriter getStreamWriter(bool isRequest) private HttpWriter getStreamWriter(bool isRequest)
{ {
return isRequest ? (HttpWriter)ProxyClient.ClientStreamWriter : WebSession.ServerConnection.StreamWriter; return isRequest ? (HttpWriter)ProxyClient.ClientStreamWriter : HttpClient.Connection.StreamWriter;
} }
/// <summary> /// <summary>
...@@ -82,9 +82,9 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -82,9 +82,9 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary> /// </summary>
private async Task readRequestBodyAsync(CancellationToken cancellationToken) private async Task readRequestBodyAsync(CancellationToken cancellationToken)
{ {
WebSession.Request.EnsureBodyAvailable(false); HttpClient.Request.EnsureBodyAvailable(false);
var request = WebSession.Request; var request = HttpClient.Request;
// If not already read (not cached yet) // If not already read (not cached yet)
if (!request.IsBodyRead) if (!request.IsBodyRead)
...@@ -106,7 +106,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -106,7 +106,7 @@ namespace Titanium.Web.Proxy.EventArguments
{ {
// syphon out the response body from server // syphon out the response body from server
await SyphonOutBodyAsync(false, cancellationToken); await SyphonOutBodyAsync(false, cancellationToken);
WebSession.Response = new Response(); HttpClient.Response = new Response();
} }
internal void OnMultipartRequestPartSent(string boundary, HeaderCollection headers) internal void OnMultipartRequestPartSent(string boundary, HeaderCollection headers)
...@@ -126,12 +126,12 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -126,12 +126,12 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary> /// </summary>
private async Task readResponseBodyAsync(CancellationToken cancellationToken) private async Task readResponseBodyAsync(CancellationToken cancellationToken)
{ {
if (!WebSession.Request.Locked) if (!HttpClient.Request.Locked)
{ {
throw new Exception("You cannot read the response body before request is made to server."); throw new Exception("You cannot read the response body before request is made to server.");
} }
var response = WebSession.Response; var response = HttpClient.Response;
if (!response.HasBody) if (!response.HasBody)
{ {
return; return;
...@@ -178,7 +178,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -178,7 +178,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <returns></returns> /// <returns></returns>
internal async Task SyphonOutBodyAsync(bool isRequest, CancellationToken cancellationToken) internal async Task SyphonOutBodyAsync(bool isRequest, CancellationToken cancellationToken)
{ {
var requestResponse = isRequest ? (RequestResponseBase)WebSession.Request : WebSession.Response; var requestResponse = isRequest ? (RequestResponseBase)HttpClient.Request : HttpClient.Response;
if (requestResponse.IsBodyRead || !requestResponse.OriginalHasBody) if (requestResponse.IsBodyRead || !requestResponse.OriginalHasBody)
{ {
return; return;
...@@ -197,7 +197,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -197,7 +197,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <returns></returns> /// <returns></returns>
internal async Task CopyRequestBodyAsync(HttpWriter writer, TransformationMode transformation, CancellationToken cancellationToken) internal async Task CopyRequestBodyAsync(HttpWriter writer, TransformationMode transformation, CancellationToken cancellationToken)
{ {
var request = WebSession.Request; var request = HttpClient.Request;
long contentLength = request.ContentLength; long contentLength = request.ContentLength;
...@@ -243,7 +243,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -243,7 +243,7 @@ namespace Titanium.Web.Proxy.EventArguments
{ {
var stream = getStreamReader(isRequest); var stream = getStreamReader(isRequest);
var requestResponse = isRequest ? (RequestResponseBase)WebSession.Request : WebSession.Response; var requestResponse = isRequest ? (RequestResponseBase)HttpClient.Request : HttpClient.Response;
bool isChunked = useOriginalHeaderValues? requestResponse.OriginalIsChunked : requestResponse.IsChunked; bool isChunked = useOriginalHeaderValues? requestResponse.OriginalIsChunked : requestResponse.IsChunked;
long contentLength = useOriginalHeaderValues ? requestResponse.OriginalContentLength : requestResponse.ContentLength; long contentLength = useOriginalHeaderValues ? requestResponse.OriginalContentLength : requestResponse.ContentLength;
...@@ -351,12 +351,12 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -351,12 +351,12 @@ namespace Titanium.Web.Proxy.EventArguments
/// <returns>The body as bytes.</returns> /// <returns>The body as bytes.</returns>
public async Task<byte[]> GetRequestBody(CancellationToken cancellationToken = default) public async Task<byte[]> GetRequestBody(CancellationToken cancellationToken = default)
{ {
if (!WebSession.Request.IsBodyRead) if (!HttpClient.Request.IsBodyRead)
{ {
await readRequestBodyAsync(cancellationToken); await readRequestBodyAsync(cancellationToken);
} }
return WebSession.Request.Body; return HttpClient.Request.Body;
} }
/// <summary> /// <summary>
...@@ -366,12 +366,12 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -366,12 +366,12 @@ namespace Titanium.Web.Proxy.EventArguments
/// <returns>The body as string.</returns> /// <returns>The body as string.</returns>
public async Task<string> GetRequestBodyAsString(CancellationToken cancellationToken = default) public async Task<string> GetRequestBodyAsString(CancellationToken cancellationToken = default)
{ {
if (!WebSession.Request.IsBodyRead) if (!HttpClient.Request.IsBodyRead)
{ {
await readRequestBodyAsync(cancellationToken); await readRequestBodyAsync(cancellationToken);
} }
return WebSession.Request.BodyString; return HttpClient.Request.BodyString;
} }
/// <summary> /// <summary>
...@@ -380,7 +380,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -380,7 +380,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <param name="body">The request body bytes.</param> /// <param name="body">The request body bytes.</param>
public void SetRequestBody(byte[] body) public void SetRequestBody(byte[] body)
{ {
var request = WebSession.Request; var request = HttpClient.Request;
if (request.Locked) if (request.Locked)
{ {
throw new Exception("You cannot call this function after request is made to server."); throw new Exception("You cannot call this function after request is made to server.");
...@@ -395,12 +395,12 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -395,12 +395,12 @@ namespace Titanium.Web.Proxy.EventArguments
/// <param name="body">The request body string to set.</param> /// <param name="body">The request body string to set.</param>
public void SetRequestBodyString(string body) public void SetRequestBodyString(string body)
{ {
if (WebSession.Request.Locked) if (HttpClient.Request.Locked)
{ {
throw new Exception("You cannot call this function after request is made to server."); throw new Exception("You cannot call this function after request is made to server.");
} }
SetRequestBody(WebSession.Request.Encoding.GetBytes(body)); SetRequestBody(HttpClient.Request.Encoding.GetBytes(body));
} }
...@@ -411,12 +411,12 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -411,12 +411,12 @@ namespace Titanium.Web.Proxy.EventArguments
/// <returns>The resulting bytes.</returns> /// <returns>The resulting bytes.</returns>
public async Task<byte[]> GetResponseBody(CancellationToken cancellationToken = default) public async Task<byte[]> GetResponseBody(CancellationToken cancellationToken = default)
{ {
if (!WebSession.Response.IsBodyRead) if (!HttpClient.Response.IsBodyRead)
{ {
await readResponseBodyAsync(cancellationToken); await readResponseBodyAsync(cancellationToken);
} }
return WebSession.Response.Body; return HttpClient.Response.Body;
} }
/// <summary> /// <summary>
...@@ -426,12 +426,12 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -426,12 +426,12 @@ namespace Titanium.Web.Proxy.EventArguments
/// <returns>The string body.</returns> /// <returns>The string body.</returns>
public async Task<string> GetResponseBodyAsString(CancellationToken cancellationToken = default) public async Task<string> GetResponseBodyAsString(CancellationToken cancellationToken = default)
{ {
if (!WebSession.Response.IsBodyRead) if (!HttpClient.Response.IsBodyRead)
{ {
await readResponseBodyAsync(cancellationToken); await readResponseBodyAsync(cancellationToken);
} }
return WebSession.Response.BodyString; return HttpClient.Response.BodyString;
} }
/// <summary> /// <summary>
...@@ -440,12 +440,12 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -440,12 +440,12 @@ namespace Titanium.Web.Proxy.EventArguments
/// <param name="body">The body bytes to set.</param> /// <param name="body">The body bytes to set.</param>
public void SetResponseBody(byte[] body) public void SetResponseBody(byte[] body)
{ {
if (!WebSession.Request.Locked) if (!HttpClient.Request.Locked)
{ {
throw new Exception("You cannot call this function before request is made to server."); throw new Exception("You cannot call this function before request is made to server.");
} }
var response = WebSession.Response; var response = HttpClient.Response;
response.Body = body; response.Body = body;
} }
...@@ -455,12 +455,12 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -455,12 +455,12 @@ namespace Titanium.Web.Proxy.EventArguments
/// <param name="body">The body string to set.</param> /// <param name="body">The body string to set.</param>
public void SetResponseBodyString(string body) public void SetResponseBodyString(string body)
{ {
if (!WebSession.Request.Locked) if (!HttpClient.Request.Locked)
{ {
throw new Exception("You cannot call this function before request is made to server."); throw new Exception("You cannot call this function before request is made to server.");
} }
var bodyBytes = WebSession.Response.Encoding.GetBytes(body); var bodyBytes = HttpClient.Response.Encoding.GetBytes(body);
SetResponseBody(bodyBytes); SetResponseBody(bodyBytes);
} }
...@@ -481,7 +481,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -481,7 +481,7 @@ namespace Titanium.Web.Proxy.EventArguments
response.Headers.AddHeaders(headers); response.Headers.AddHeaders(headers);
} }
response.HttpVersion = WebSession.Request.HttpVersion; response.HttpVersion = HttpClient.Request.HttpVersion;
response.Body = response.Encoding.GetBytes(html ?? string.Empty); response.Body = response.Encoding.GetBytes(html ?? string.Empty);
Respond(response, closeServerConnection); Respond(response, closeServerConnection);
...@@ -499,7 +499,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -499,7 +499,7 @@ namespace Titanium.Web.Proxy.EventArguments
{ {
var response = new OkResponse(); var response = new OkResponse();
response.Headers.AddHeaders(headers); response.Headers.AddHeaders(headers);
response.HttpVersion = WebSession.Request.HttpVersion; response.HttpVersion = HttpClient.Request.HttpVersion;
response.Body = result; response.Body = result;
Respond(response, closeServerConnection); Respond(response, closeServerConnection);
...@@ -518,7 +518,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -518,7 +518,7 @@ namespace Titanium.Web.Proxy.EventArguments
Dictionary<string, HttpHeader> headers = null, bool closeServerConnection = false) Dictionary<string, HttpHeader> headers = null, bool closeServerConnection = false)
{ {
var response = new GenericResponse(status); var response = new GenericResponse(status);
response.HttpVersion = WebSession.Request.HttpVersion; response.HttpVersion = HttpClient.Request.HttpVersion;
response.Headers.AddHeaders(headers); response.Headers.AddHeaders(headers);
response.Body = response.Encoding.GetBytes(html ?? string.Empty); response.Body = response.Encoding.GetBytes(html ?? string.Empty);
...@@ -537,7 +537,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -537,7 +537,7 @@ namespace Titanium.Web.Proxy.EventArguments
Dictionary<string, HttpHeader> headers, bool closeServerConnection = false) Dictionary<string, HttpHeader> headers, bool closeServerConnection = false)
{ {
var response = new GenericResponse(status); var response = new GenericResponse(status);
response.HttpVersion = WebSession.Request.HttpVersion; response.HttpVersion = HttpClient.Request.HttpVersion;
response.Headers.AddHeaders(headers); response.Headers.AddHeaders(headers);
response.Body = result; response.Body = result;
...@@ -552,7 +552,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -552,7 +552,7 @@ namespace Titanium.Web.Proxy.EventArguments
public void Redirect(string url, bool closeServerConnection = false) public void Redirect(string url, bool closeServerConnection = false)
{ {
var response = new RedirectResponse(); var response = new RedirectResponse();
response.HttpVersion = WebSession.Request.HttpVersion; response.HttpVersion = HttpClient.Request.HttpVersion;
response.Headers.AddHeader(KnownHeaders.Location, url); response.Headers.AddHeader(KnownHeaders.Location, url);
response.Body = emptyData; response.Body = emptyData;
...@@ -567,10 +567,10 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -567,10 +567,10 @@ namespace Titanium.Web.Proxy.EventArguments
public void Respond(Response response, bool closeServerConnection = false) public void Respond(Response response, bool closeServerConnection = false)
{ {
//request already send/ready to be sent. //request already send/ready to be sent.
if (WebSession.Request.Locked) if (HttpClient.Request.Locked)
{ {
//response already received from server and ready to be sent to client. //response already received from server and ready to be sent to client.
if (WebSession.Response.Locked) if (HttpClient.Response.Locked)
{ {
throw new Exception("You cannot call this function after response is sent to the client."); throw new Exception("You cannot call this function after response is sent to the client.");
} }
...@@ -583,21 +583,21 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -583,21 +583,21 @@ namespace Titanium.Web.Proxy.EventArguments
TerminateServerConnection(); TerminateServerConnection();
} }
response.SetOriginalHeaders(WebSession.Response); response.SetOriginalHeaders(HttpClient.Response);
//response already received from server but not yet ready to sent to client. //response already received from server but not yet ready to sent to client.
WebSession.Response = response; HttpClient.Response = response;
WebSession.Response.Locked = true; HttpClient.Response.Locked = true;
} }
//request not yet sent/not yet ready to be sent. //request not yet sent/not yet ready to be sent.
else else
{ {
WebSession.Request.Locked = true; HttpClient.Request.Locked = true;
WebSession.Request.CancelRequest = true; HttpClient.Request.CancelRequest = true;
//set new response. //set new response.
WebSession.Response = response; HttpClient.Response = response;
WebSession.Response.Locked = true; HttpClient.Response.Locked = true;
} }
} }
...@@ -607,7 +607,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -607,7 +607,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary> /// </summary>
public void TerminateServerConnection() public void TerminateServerConnection()
{ {
WebSession.CloseServerConnection = true; HttpClient.CloseServerConnection = true;
} }
/// <summary> /// <summary>
......
...@@ -8,6 +8,7 @@ using Titanium.Web.Proxy.Helpers; ...@@ -8,6 +8,7 @@ using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Network; using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Network.Tcp;
namespace Titanium.Web.Proxy.EventArguments namespace Titanium.Web.Proxy.EventArguments
{ {
...@@ -19,8 +20,9 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -19,8 +20,9 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary> /// </summary>
public abstract class SessionEventArgsBase : EventArgs, IDisposable public abstract class SessionEventArgsBase : EventArgs, IDisposable
{ {
internal readonly CancellationTokenSource CancellationTokenSource; internal readonly CancellationTokenSource CancellationTokenSource;
internal TcpServerConnection ServerConnection => HttpClient.Connection;
internal TcpClientConnection ClientConnection => ProxyClient.Connection;
protected readonly int bufferSize; protected readonly int bufferSize;
protected readonly IBufferPool bufferPool; protected readonly IBufferPool bufferPool;
...@@ -50,10 +52,10 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -50,10 +52,10 @@ namespace Titanium.Web.Proxy.EventArguments
CancellationTokenSource = cancellationTokenSource; CancellationTokenSource = cancellationTokenSource;
ProxyClient = new ProxyClient(); ProxyClient = new ProxyClient();
WebSession = new HttpWebClient(request); HttpClient = new HttpWebClient(request);
LocalEndPoint = endPoint; LocalEndPoint = endPoint;
WebSession.ProcessId = new Lazy<int>(() => HttpClient.ProcessId = new Lazy<int>(() =>
{ {
if (RunTime.IsWindows) if (RunTime.IsWindows)
{ {
...@@ -85,25 +87,27 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -85,25 +87,27 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary> /// </summary>
public object UserData public object UserData
{ {
get => WebSession.UserData; get => HttpClient.UserData;
set => WebSession.UserData = value; set => HttpClient.UserData = value;
} }
/// <summary> /// <summary>
/// Does this session uses SSL? /// Does this session uses SSL?
/// </summary> /// </summary>
public bool IsHttps => WebSession.Request.IsHttps; public bool IsHttps => HttpClient.Request.IsHttps;
/// <summary> /// <summary>
/// Client End Point. /// Client End Point.
/// </summary> /// </summary>
public IPEndPoint ClientEndPoint => (IPEndPoint)ProxyClient.ClientConnection.RemoteEndPoint; public IPEndPoint ClientEndPoint => (IPEndPoint)ProxyClient.Connection.RemoteEndPoint;
/// <summary> /// <summary>
/// A web session corresponding to a single request/response sequence /// The web client used to communicate with server for this session.
/// within a proxy connection.
/// </summary> /// </summary>
public HttpWebClient WebSession { get; } public HttpWebClient HttpClient { get; }
[Obsolete("Use HttpClient instead.")]
public HttpWebClient WebSession => HttpClient;
/// <summary> /// <summary>
/// Are we using a custom upstream HTTP(S) proxy? /// Are we using a custom upstream HTTP(S) proxy?
...@@ -136,7 +140,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -136,7 +140,7 @@ namespace Titanium.Web.Proxy.EventArguments
DataReceived = null; DataReceived = null;
Exception = null; Exception = null;
WebSession.FinishSession(); HttpClient.FinishSession();
} }
/// <summary> /// <summary>
......
...@@ -16,7 +16,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -16,7 +16,7 @@ namespace Titanium.Web.Proxy.EventArguments
CancellationTokenSource cancellationTokenSource) CancellationTokenSource cancellationTokenSource)
: base(server, endPoint, cancellationTokenSource, connectRequest) : base(server, endPoint, cancellationTokenSource, connectRequest)
{ {
WebSession.ConnectRequest = connectRequest; HttpClient.ConnectRequest = connectRequest;
} }
/// <summary> /// <summary>
......
...@@ -73,7 +73,7 @@ namespace Titanium.Web.Proxy ...@@ -73,7 +73,7 @@ namespace Titanium.Web.Proxy
connectArgs = new TunnelConnectSessionEventArgs(this, endPoint, connectRequest, connectArgs = new TunnelConnectSessionEventArgs(this, endPoint, connectRequest,
cancellationTokenSource); cancellationTokenSource);
connectArgs.ProxyClient.ClientConnection = clientConnection; connectArgs.ProxyClient.Connection = clientConnection;
connectArgs.ProxyClient.ClientStream = clientStream; connectArgs.ProxyClient.ClientStream = clientStream;
await endPoint.InvokeBeforeTunnelConnectRequest(this, connectArgs, ExceptionFunc); await endPoint.InvokeBeforeTunnelConnectRequest(this, connectArgs, ExceptionFunc);
...@@ -83,9 +83,9 @@ namespace Titanium.Web.Proxy ...@@ -83,9 +83,9 @@ namespace Titanium.Web.Proxy
if (connectArgs.DenyConnect) if (connectArgs.DenyConnect)
{ {
if (connectArgs.WebSession.Response.StatusCode == 0) if (connectArgs.HttpClient.Response.StatusCode == 0)
{ {
connectArgs.WebSession.Response = new Response connectArgs.HttpClient.Response = new Response
{ {
HttpVersion = HttpHeader.Version11, HttpVersion = HttpHeader.Version11,
StatusCode = (int)HttpStatusCode.Forbidden, StatusCode = (int)HttpStatusCode.Forbidden,
...@@ -94,7 +94,7 @@ namespace Titanium.Web.Proxy ...@@ -94,7 +94,7 @@ namespace Titanium.Web.Proxy
} }
// send the response // send the response
await clientStreamWriter.WriteResponseAsync(connectArgs.WebSession.Response, await clientStreamWriter.WriteResponseAsync(connectArgs.HttpClient.Response,
cancellationToken: cancellationToken); cancellationToken: cancellationToken);
return; return;
} }
...@@ -104,7 +104,7 @@ namespace Titanium.Web.Proxy ...@@ -104,7 +104,7 @@ namespace Titanium.Web.Proxy
await endPoint.InvokeBeforeTunnectConnectResponse(this, connectArgs, ExceptionFunc); await endPoint.InvokeBeforeTunnectConnectResponse(this, connectArgs, ExceptionFunc);
// send the response // send the response
await clientStreamWriter.WriteResponseAsync(connectArgs.WebSession.Response, await clientStreamWriter.WriteResponseAsync(connectArgs.HttpClient.Response,
cancellationToken: cancellationToken); cancellationToken: cancellationToken);
return; return;
} }
...@@ -115,7 +115,7 @@ namespace Titanium.Web.Proxy ...@@ -115,7 +115,7 @@ namespace Titanium.Web.Proxy
// Set ContentLength explicitly to properly handle HTTP 1.0 // Set ContentLength explicitly to properly handle HTTP 1.0
response.ContentLength = 0; response.ContentLength = 0;
response.Headers.FixProxyHeaders(); response.Headers.FixProxyHeaders();
connectArgs.WebSession.Response = response; connectArgs.HttpClient.Response = response;
await clientStreamWriter.WriteResponseAsync(response, cancellationToken: cancellationToken); await clientStreamWriter.WriteResponseAsync(response, cancellationToken: cancellationToken);
...@@ -252,7 +252,7 @@ namespace Titanium.Web.Proxy ...@@ -252,7 +252,7 @@ namespace Titanium.Web.Proxy
} }
var serverHelloInfo = await SslTools.PeekServerHello(connection.Stream, BufferPool, cancellationToken); var serverHelloInfo = await SslTools.PeekServerHello(connection.Stream, BufferPool, cancellationToken);
((ConnectResponse)connectArgs.WebSession.Response).ServerHelloInfo = serverHelloInfo; ((ConnectResponse)connectArgs.HttpClient.Response).ServerHelloInfo = serverHelloInfo;
} }
await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool, BufferSize, await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool, BufferSize,
...@@ -321,7 +321,7 @@ namespace Titanium.Web.Proxy ...@@ -321,7 +321,7 @@ namespace Titanium.Web.Proxy
calledRequestHandler = true; calledRequestHandler = true;
// 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, prefetchConnectionTask); cancellationTokenSource, connectHostname, connectArgs?.HttpClient.ConnectRequest, prefetchConnectionTask);
} }
catch (ProxyException e) catch (ProxyException e)
{ {
......
...@@ -17,16 +17,16 @@ namespace Titanium.Web.Proxy.Http ...@@ -17,16 +17,16 @@ namespace Titanium.Web.Proxy.Http
/// </summary> /// </summary>
public class HttpWebClient public class HttpWebClient
{ {
internal HttpWebClient(Request request = null, Response response = null) internal HttpWebClient(Request request)
{ {
Request = request ?? new Request(); Request = request ?? new Request();
Response = response ?? new Response(); Response = new Response();
} }
/// <summary> /// <summary>
/// Connection to server /// Connection to server
/// </summary> /// </summary>
internal TcpServerConnection ServerConnection { get; set; } internal TcpServerConnection Connection { get; set; }
/// <summary> /// <summary>
/// Should we close the server connection at the end of this HTTP request/response session. /// Should we close the server connection at the end of this HTTP request/response session.
...@@ -81,7 +81,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -81,7 +81,7 @@ namespace Titanium.Web.Proxy.Http
internal void SetConnection(TcpServerConnection serverConnection) internal void SetConnection(TcpServerConnection serverConnection)
{ {
serverConnection.LastAccess = DateTime.Now; serverConnection.LastAccess = DateTime.Now;
ServerConnection = serverConnection; Connection = serverConnection;
} }
/// <summary> /// <summary>
...@@ -91,11 +91,11 @@ namespace Titanium.Web.Proxy.Http ...@@ -91,11 +91,11 @@ namespace Titanium.Web.Proxy.Http
internal async Task SendRequest(bool enable100ContinueBehaviour, bool isTransparent, internal async Task SendRequest(bool enable100ContinueBehaviour, bool isTransparent,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var upstreamProxy = ServerConnection.UpStreamProxy; var upstreamProxy = Connection.UpStreamProxy;
bool useUpstreamProxy = upstreamProxy != null && ServerConnection.IsHttps == false; bool useUpstreamProxy = upstreamProxy != null && Connection.IsHttps == false;
var writer = ServerConnection.StreamWriter; var writer = Connection.StreamWriter;
// prepare the request & headers // prepare the request & headers
await writer.WriteLineAsync(Request.CreateRequestLine(Request.Method, await writer.WriteLineAsync(Request.CreateRequestLine(Request.Method,
...@@ -106,7 +106,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -106,7 +106,7 @@ namespace Titanium.Web.Proxy.Http
// Send Authentication to Upstream proxy if needed // Send Authentication to Upstream proxy if needed
if (!isTransparent && upstreamProxy != null if (!isTransparent && upstreamProxy != null
&& ServerConnection.IsHttps == false && Connection.IsHttps == false
&& !string.IsNullOrEmpty(upstreamProxy.UserName) && !string.IsNullOrEmpty(upstreamProxy.UserName)
&& upstreamProxy.Password != null) && upstreamProxy.Password != null)
{ {
...@@ -134,7 +134,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -134,7 +134,7 @@ namespace Titanium.Web.Proxy.Http
string httpStatus; string httpStatus;
try try
{ {
httpStatus = await ServerConnection.Stream.ReadLineAsync(cancellationToken); httpStatus = await Connection.Stream.ReadLineAsync(cancellationToken);
if (httpStatus == null) if (httpStatus == null)
{ {
throw new ServerConnectionException("Server connection was closed."); throw new ServerConnectionException("Server connection was closed.");
...@@ -153,13 +153,13 @@ namespace Titanium.Web.Proxy.Http ...@@ -153,13 +153,13 @@ namespace Titanium.Web.Proxy.Http
&& responseStatusDescription.EqualsIgnoreCase("continue")) && responseStatusDescription.EqualsIgnoreCase("continue"))
{ {
Request.Is100Continue = true; Request.Is100Continue = true;
await ServerConnection.Stream.ReadLineAsync(cancellationToken); await Connection.Stream.ReadLineAsync(cancellationToken);
} }
else if (responseStatusCode == (int)HttpStatusCode.ExpectationFailed else if (responseStatusCode == (int)HttpStatusCode.ExpectationFailed
&& responseStatusDescription.EqualsIgnoreCase("expectation failed")) && responseStatusDescription.EqualsIgnoreCase("expectation failed"))
{ {
Request.ExpectationFailed = true; Request.ExpectationFailed = true;
await ServerConnection.Stream.ReadLineAsync(cancellationToken); await Connection.Stream.ReadLineAsync(cancellationToken);
} }
} }
} }
...@@ -180,7 +180,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -180,7 +180,7 @@ namespace Titanium.Web.Proxy.Http
string httpStatus; string httpStatus;
try try
{ {
httpStatus = await ServerConnection.Stream.ReadLineAsync(cancellationToken); httpStatus = await Connection.Stream.ReadLineAsync(cancellationToken);
if (httpStatus == null) if (httpStatus == null)
{ {
throw new ServerConnectionException("Server connection was closed."); throw new ServerConnectionException("Server connection was closed.");
...@@ -193,7 +193,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -193,7 +193,7 @@ namespace Titanium.Web.Proxy.Http
if (httpStatus == string.Empty) if (httpStatus == string.Empty)
{ {
httpStatus = await ServerConnection.Stream.ReadLineAsync(cancellationToken); httpStatus = await Connection.Stream.ReadLineAsync(cancellationToken);
} }
Response.ParseResponseLine(httpStatus, out var version, out int statusCode, out string statusDescription); Response.ParseResponseLine(httpStatus, out var version, out int statusCode, out string statusDescription);
...@@ -209,7 +209,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -209,7 +209,7 @@ namespace Titanium.Web.Proxy.Http
// Read the next line after 100-continue // Read the next line after 100-continue
Response.Is100Continue = true; Response.Is100Continue = true;
Response.StatusCode = 0; Response.StatusCode = 0;
await ServerConnection.Stream.ReadLineAsync(cancellationToken); await Connection.Stream.ReadLineAsync(cancellationToken);
// now receive response // now receive response
await ReceiveResponse(cancellationToken); await ReceiveResponse(cancellationToken);
...@@ -222,7 +222,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -222,7 +222,7 @@ namespace Titanium.Web.Proxy.Http
// read next line after expectation failed response // read next line after expectation failed response
Response.ExpectationFailed = true; Response.ExpectationFailed = true;
Response.StatusCode = 0; Response.StatusCode = 0;
await ServerConnection.Stream.ReadLineAsync(cancellationToken); await Connection.Stream.ReadLineAsync(cancellationToken);
// now receive response // now receive response
await ReceiveResponse(cancellationToken); await ReceiveResponse(cancellationToken);
...@@ -230,7 +230,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -230,7 +230,7 @@ namespace Titanium.Web.Proxy.Http
} }
// Read the response headers in to unique and non-unique header collections // Read the response headers in to unique and non-unique header collections
await HeaderParser.ReadHeaders(ServerConnection.Stream, Response.Headers, cancellationToken); await HeaderParser.ReadHeaders(Connection.Stream, Response.Headers, cancellationToken);
} }
/// <summary> /// <summary>
...@@ -238,7 +238,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -238,7 +238,7 @@ namespace Titanium.Web.Proxy.Http
/// </summary> /// </summary>
internal void FinishSession() internal void FinishSession()
{ {
ServerConnection = null; Connection = null;
ConnectRequest?.FinishSession(); ConnectRequest?.FinishSession();
Request?.FinishSession(); Request?.FinishSession();
......
...@@ -12,7 +12,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -12,7 +12,7 @@ namespace Titanium.Web.Proxy.Network
/// <summary> /// <summary>
/// TcpClient connection used to communicate with client /// TcpClient connection used to communicate with client
/// </summary> /// </summary>
internal TcpClientConnection ClientConnection { get; set; } internal TcpClientConnection Connection { get; set; }
/// <summary> /// <summary>
/// Holds the stream to client /// Holds the stream to client
......
...@@ -98,10 +98,10 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -98,10 +98,10 @@ namespace Titanium.Web.Proxy.Network.Tcp
session.CustomUpStreamProxyUsed = customUpStreamProxy; session.CustomUpStreamProxyUsed = customUpStreamProxy;
return GetConnectionCacheKey( return GetConnectionCacheKey(
session.WebSession.Request.RequestUri.Host, session.HttpClient.Request.RequestUri.Host,
session.WebSession.Request.RequestUri.Port, session.HttpClient.Request.RequestUri.Port,
isHttps, applicationProtocols, isHttps, applicationProtocols,
server, session.WebSession.UpStreamEndPoint ?? server.UpStreamEndPoint, server, session.HttpClient.UpStreamEndPoint ?? server.UpStreamEndPoint,
customUpStreamProxy ?? (isHttps ? server.UpStreamHttpsProxy : server.UpStreamHttpProxy)); customUpStreamProxy ?? (isHttps ? server.UpStreamHttpsProxy : server.UpStreamHttpProxy));
} }
...@@ -148,11 +148,11 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -148,11 +148,11 @@ namespace Titanium.Web.Proxy.Network.Tcp
session.CustomUpStreamProxyUsed = customUpStreamProxy; session.CustomUpStreamProxyUsed = customUpStreamProxy;
return await GetServerConnection( return await GetServerConnection(
session.WebSession.Request.RequestUri.Host, session.HttpClient.Request.RequestUri.Host,
session.WebSession.Request.RequestUri.Port, session.HttpClient.Request.RequestUri.Port,
session.WebSession.Request.HttpVersion, session.HttpClient.Request.HttpVersion,
isHttps, applicationProtocols, isConnect, isHttps, applicationProtocols, isConnect,
server, session, session.WebSession.UpStreamEndPoint ?? server.UpStreamEndPoint, server, session, session.HttpClient.UpStreamEndPoint ?? server.UpStreamEndPoint,
customUpStreamProxy ?? (isHttps ? server.UpStreamHttpsProxy : server.UpStreamHttpProxy), customUpStreamProxy ?? (isHttps ? server.UpStreamHttpsProxy : server.UpStreamHttpProxy),
noCache, cancellationToken); noCache, cancellationToken);
} }
......
...@@ -26,14 +26,14 @@ namespace Titanium.Web.Proxy ...@@ -26,14 +26,14 @@ namespace Titanium.Web.Proxy
return true; return true;
} }
var httpHeaders = session.WebSession.Request.Headers; var httpHeaders = session.HttpClient.Request.Headers;
try try
{ {
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.HttpClient.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
if (headerValueParts.Length != 2) if (headerValueParts.Length != 2)
{ {
// Return not authorized // Return not authorized
session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid"); session.HttpClient.Response = createAuthentication407Response("Proxy Authentication Invalid");
return false; return false;
} }
...@@ -57,7 +57,7 @@ namespace Titanium.Web.Proxy ...@@ -57,7 +57,7 @@ namespace Titanium.Web.Proxy
if (result.Result == ProxyAuthenticationResult.ContinuationNeeded) if (result.Result == ProxyAuthenticationResult.ContinuationNeeded)
{ {
session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid", result.Continuation); session.HttpClient.Response = createAuthentication407Response("Proxy Authentication Invalid", result.Continuation);
return false; return false;
} }
...@@ -73,7 +73,7 @@ namespace Titanium.Web.Proxy ...@@ -73,7 +73,7 @@ namespace Titanium.Web.Proxy
httpHeaders)); httpHeaders));
// Return not authorized // Return not authorized
session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid"); session.HttpClient.Response = createAuthentication407Response("Proxy Authentication Invalid");
return false; return false;
} }
} }
...@@ -83,7 +83,7 @@ namespace Titanium.Web.Proxy ...@@ -83,7 +83,7 @@ namespace Titanium.Web.Proxy
if (!headerValueParts[0].EqualsIgnoreCase(KnownHeaders.ProxyAuthorizationBasic)) if (!headerValueParts[0].EqualsIgnoreCase(KnownHeaders.ProxyAuthorizationBasic))
{ {
// Return not authorized // Return not authorized
session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid"); session.HttpClient.Response = createAuthentication407Response("Proxy Authentication Invalid");
return false; return false;
} }
...@@ -92,7 +92,7 @@ namespace Titanium.Web.Proxy ...@@ -92,7 +92,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.HttpClient.Response = createAuthentication407Response("Proxy Authentication Invalid");
return false; return false;
} }
...@@ -101,7 +101,7 @@ namespace Titanium.Web.Proxy ...@@ -101,7 +101,7 @@ namespace Titanium.Web.Proxy
bool authenticated = await ProxyBasicAuthenticateFunc(session, username, password); bool authenticated = await ProxyBasicAuthenticateFunc(session, username, password);
if (!authenticated) if (!authenticated)
{ {
session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid"); session.HttpClient.Response = createAuthentication407Response("Proxy Authentication Invalid");
} }
return authenticated; return authenticated;
......
...@@ -679,7 +679,7 @@ namespace Titanium.Web.Proxy ...@@ -679,7 +679,7 @@ namespace Titanium.Web.Proxy
/// <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.HttpClient.Request.RequestUri);
return Task.FromResult(proxy); return Task.FromResult(proxy);
} }
......
...@@ -15,6 +15,7 @@ using Titanium.Web.Proxy.Extensions; ...@@ -15,6 +15,7 @@ using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Network.Tcp; using Titanium.Web.Proxy.Network.Tcp;
using Titanium.Web.Proxy.Shared; using Titanium.Web.Proxy.Shared;
...@@ -71,8 +72,8 @@ namespace Titanium.Web.Proxy ...@@ -71,8 +72,8 @@ namespace Titanium.Web.Proxy
var args = new SessionEventArgs(this, endPoint, cancellationTokenSource) var args = new SessionEventArgs(this, endPoint, cancellationTokenSource)
{ {
ProxyClient = { ClientConnection = clientConnection }, ProxyClient = { Connection = clientConnection },
WebSession = { ConnectRequest = connectRequest } HttpClient = { ConnectRequest = connectRequest }
}; };
try try
...@@ -83,7 +84,7 @@ namespace Titanium.Web.Proxy ...@@ -83,7 +84,7 @@ namespace Titanium.Web.Proxy
out var version); out var version);
// Read the request headers in to unique and non-unique header collections // Read the request headers in to unique and non-unique header collections
await HeaderParser.ReadHeaders(clientStream, args.WebSession.Request.Headers, await HeaderParser.ReadHeaders(clientStream, args.HttpClient.Request.Headers,
cancellationToken); cancellationToken);
Uri httpRemoteUri; Uri httpRemoteUri;
...@@ -100,7 +101,7 @@ namespace Titanium.Web.Proxy ...@@ -100,7 +101,7 @@ namespace Titanium.Web.Proxy
} }
else else
{ {
string host = args.WebSession.Request.Host ?? httpsConnectHostname; string host = args.HttpClient.Request.Host ?? httpsConnectHostname;
string hostAndPath = host; string hostAndPath = host;
if (httpUrl.StartsWith("/")) if (httpUrl.StartsWith("/"))
{ {
...@@ -119,7 +120,7 @@ namespace Titanium.Web.Proxy ...@@ -119,7 +120,7 @@ namespace Titanium.Web.Proxy
} }
} }
var request = args.WebSession.Request; var request = args.HttpClient.Request;
request.RequestUri = httpRemoteUri; request.RequestUri = httpRemoteUri;
request.OriginalUrl = httpUrl; request.OriginalUrl = httpUrl;
...@@ -136,7 +137,7 @@ namespace Titanium.Web.Proxy ...@@ -136,7 +137,7 @@ namespace Titanium.Web.Proxy
await invokeBeforeResponse(args); await invokeBeforeResponse(args);
// send the response // send the response
await clientStreamWriter.WriteResponseAsync(args.WebSession.Response, await clientStreamWriter.WriteResponseAsync(args.HttpClient.Response,
cancellationToken: cancellationToken); cancellationToken: cancellationToken);
return; return;
} }
...@@ -161,7 +162,7 @@ namespace Titanium.Web.Proxy ...@@ -161,7 +162,7 @@ namespace Titanium.Web.Proxy
// 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.HttpClient.Response;
if (request.CancelRequest) if (request.CancelRequest)
{ {
...@@ -197,49 +198,51 @@ namespace Titanium.Web.Proxy ...@@ -197,49 +198,51 @@ namespace Titanium.Web.Proxy
connection = null; connection = null;
} }
//a connection generator task with captured parameters via closure. RetryResult result;
Func<Task<TcpServerConnection>> generator = () => if (request.UpgradeToWebSocket)
tcpConnectionFactory.GetServerConnection(this, args, isConnect: false,
applicationProtocol:clientConnection.NegotiatedApplicationProtocol,
noCache: false, cancellationToken: cancellationToken);
//for connection pool, retry fails until cache is exhausted.
var result = await retryPolicy<ServerConnectionException>().ExecuteAsync(async (serverConnection) =>
{ {
args.TimeLine["Connection Ready"] = DateTime.Now; //a connection generator task with captured parameters via closure.
Func<Task<TcpServerConnection>> generator = () =>
// if upgrading to websocket then relay the request without reading the contents tcpConnectionFactory.GetServerConnection(this, args, isConnect: false,
if (request.UpgradeToWebSocket) applicationProtocol: clientConnection.NegotiatedApplicationProtocol,
noCache: false, cancellationToken: cancellationToken);
//for connection pool, retry fails until cache is exhausted.
result = await retryPolicy<ServerConnectionException>().ExecuteAsync(async (serverConnection) =>
{ {
args.TimeLine["Connection Ready"] = DateTime.Now;
// if upgrading to websocket then relay the request without reading the contents
await handleWebSocketUpgrade(httpCmd, args, request, await handleWebSocketUpgrade(httpCmd, args, request,
response, clientStream, clientStreamWriter, response, clientStream, clientStreamWriter,
serverConnection, cancellationTokenSource, cancellationToken); serverConnection, cancellationTokenSource, cancellationToken);
closeServerConnection = true; closeServerConnection = true;
return false; return false;
}
// construct the web request that we are going to issue on behalf of the client.
await handleHttpSessionRequest(serverConnection, args);
return true;
}, generator, connection); }, generator, connection);
}
else
{
result = await handleHttpSessionRequest(args, connection,
clientConnection.NegotiatedApplicationProtocol, cancellationToken);
}
//update connection to latest used //update connection to latest used
connection = result.LatestConnection; connection = result.LatestConnection;
//throw if exception happened //throw if exception happened
if(!result.IsSuccess) if (!result.IsSuccess)
{ {
throw result.Exception; throw result.Exception;
} }
if(!result.Continue) if (!result.Continue)
{ {
return; return;
} }
//user requested //user requested
if (args.WebSession.CloseServerConnection) if (args.HttpClient.CloseServerConnection)
{ {
closeServerConnection = true; closeServerConnection = true;
return; return;
...@@ -262,7 +265,7 @@ namespace Titanium.Web.Proxy ...@@ -262,7 +265,7 @@ namespace Titanium.Web.Proxy
//between sessions without using it. //between sessions without using it.
//Do not release authenticated connections for performance reasons. //Do not release authenticated connections for performance reasons.
//Otherwise it will keep authenticating per session. //Otherwise it will keep authenticating per session.
if (EnableConnectionPool && connection!=null if (EnableConnectionPool && connection != null
&& !connection.IsWinAuthenticated) && !connection.IsWinAuthenticated)
{ {
await tcpConnectionFactory.Release(connection); await tcpConnectionFactory.Release(connection);
...@@ -297,6 +300,38 @@ namespace Titanium.Web.Proxy ...@@ -297,6 +300,38 @@ namespace Titanium.Web.Proxy
} }
} }
private async Task<RetryResult> handleHttpSessionRequest(SessionEventArgs args,
TcpServerConnection connection,
SslApplicationProtocol protocol,
CancellationToken cancellationToken)
{
//host/scheme changed from ReRequest
if (args.ReRequest
&& (args.HttpClient.Request.IsHttps != connection.IsHttps
|| args.HttpClient.Request.Host != connection.HostName))
{
connection = null;
}
//a connection generator task with captured parameters via closure.
Func<Task<TcpServerConnection>> generator = () =>
tcpConnectionFactory.GetServerConnection(this, args, isConnect: false,
applicationProtocol: protocol,
noCache: false, cancellationToken: cancellationToken);
//for connection pool, retry fails until cache is exhausted.
return await retryPolicy<ServerConnectionException>().ExecuteAsync(async (serverConnection) =>
{
args.TimeLine["Connection Ready"] = DateTime.Now;
// construct the web request that we are going to issue on behalf of the client.
await handleHttpSessionRequest(serverConnection, args);
return true;
}, generator, connection);
}
/// <summary> /// <summary>
/// Handle a specific session (request/response sequence) /// Handle a specific session (request/response sequence)
/// </summary> /// </summary>
...@@ -306,7 +341,7 @@ namespace Titanium.Web.Proxy ...@@ -306,7 +341,7 @@ namespace Titanium.Web.Proxy
private async Task handleHttpSessionRequest(TcpServerConnection serverConnection, SessionEventArgs args) private async Task handleHttpSessionRequest(TcpServerConnection serverConnection, SessionEventArgs args)
{ {
var cancellationToken = args.CancellationTokenSource.Token; var cancellationToken = args.CancellationTokenSource.Token;
var request = args.WebSession.Request; var request = args.HttpClient.Request;
request.Locked = true; request.Locked = true;
var body = request.CompressBodyAndUpdateContentLength(); var body = request.CompressBodyAndUpdateContentLength();
...@@ -315,8 +350,8 @@ namespace Titanium.Web.Proxy ...@@ -315,8 +350,8 @@ namespace Titanium.Web.Proxy
// and see if server would return 100 conitinue // and see if server would return 100 conitinue
if (request.ExpectContinue) if (request.ExpectContinue)
{ {
args.WebSession.SetConnection(serverConnection); args.HttpClient.SetConnection(serverConnection);
await args.WebSession.SendRequest(Enable100ContinueBehaviour, args.IsTransparent, await args.HttpClient.SendRequest(Enable100ContinueBehaviour, args.IsTransparent,
cancellationToken); cancellationToken);
} }
...@@ -327,13 +362,13 @@ namespace Titanium.Web.Proxy ...@@ -327,13 +362,13 @@ namespace Titanium.Web.Proxy
if (request.Is100Continue) if (request.Is100Continue)
{ {
await clientStreamWriter.WriteResponseStatusAsync(args.WebSession.Response.HttpVersion, await clientStreamWriter.WriteResponseStatusAsync(args.HttpClient.Response.HttpVersion,
(int)HttpStatusCode.Continue, "Continue", cancellationToken); (int)HttpStatusCode.Continue, "Continue", cancellationToken);
await clientStreamWriter.WriteLineAsync(cancellationToken); await clientStreamWriter.WriteLineAsync(cancellationToken);
} }
else if (request.ExpectationFailed) else if (request.ExpectationFailed)
{ {
await clientStreamWriter.WriteResponseStatusAsync(args.WebSession.Response.HttpVersion, await clientStreamWriter.WriteResponseStatusAsync(args.HttpClient.Response.HttpVersion,
(int)HttpStatusCode.ExpectationFailed, "Expectation Failed", cancellationToken); (int)HttpStatusCode.ExpectationFailed, "Expectation Failed", cancellationToken);
await clientStreamWriter.WriteLineAsync(cancellationToken); await clientStreamWriter.WriteLineAsync(cancellationToken);
} }
...@@ -342,8 +377,8 @@ namespace Titanium.Web.Proxy ...@@ -342,8 +377,8 @@ namespace Titanium.Web.Proxy
// If expect continue is not enabled then set the connectio and send request headers // If expect continue is not enabled then set the connectio and send request headers
if (!request.ExpectContinue) if (!request.ExpectContinue)
{ {
args.WebSession.SetConnection(serverConnection); args.HttpClient.SetConnection(serverConnection);
await args.WebSession.SendRequest(Enable100ContinueBehaviour, args.IsTransparent, await args.HttpClient.SendRequest(Enable100ContinueBehaviour, args.IsTransparent,
cancellationToken); cancellationToken);
} }
...@@ -352,7 +387,7 @@ namespace Titanium.Web.Proxy ...@@ -352,7 +387,7 @@ namespace Titanium.Web.Proxy
{ {
if (request.IsBodyRead) if (request.IsBodyRead)
{ {
var writer = args.WebSession.ServerConnection.StreamWriter; var writer = args.HttpClient.Connection.StreamWriter;
await writer.WriteBodyAsync(body, request.IsChunked, cancellationToken); await writer.WriteBodyAsync(body, request.IsChunked, cancellationToken);
} }
else else
...@@ -361,7 +396,7 @@ namespace Titanium.Web.Proxy ...@@ -361,7 +396,7 @@ namespace Titanium.Web.Proxy
{ {
if (request.HasBody) if (request.HasBody)
{ {
HttpWriter writer = args.WebSession.ServerConnection.StreamWriter; HttpWriter writer = args.HttpClient.Connection.StreamWriter;
await args.CopyRequestBodyAsync(writer, TransformationMode.None, cancellationToken); await args.CopyRequestBodyAsync(writer, TransformationMode.None, cancellationToken);
} }
} }
......
...@@ -22,11 +22,11 @@ namespace Titanium.Web.Proxy ...@@ -22,11 +22,11 @@ namespace Titanium.Web.Proxy
var cancellationToken = args.CancellationTokenSource.Token; var cancellationToken = args.CancellationTokenSource.Token;
// read response & headers from server // read response & headers from server
await args.WebSession.ReceiveResponse(cancellationToken); await args.HttpClient.ReceiveResponse(cancellationToken);
args.TimeLine["Response Received"] = DateTime.Now; args.TimeLine["Response Received"] = DateTime.Now;
var response = args.WebSession.Response; var response = args.HttpClient.Response;
args.ReRequest = false; args.ReRequest = false;
// check for windows authentication // check for windows authentication
...@@ -38,7 +38,7 @@ namespace Titanium.Web.Proxy ...@@ -38,7 +38,7 @@ namespace Titanium.Web.Proxy
} }
else else
{ {
WinAuthEndPoint.AuthenticatedResponse(args.WebSession.Data); WinAuthEndPoint.AuthenticatedResponse(args.HttpClient.Data);
} }
} }
...@@ -53,7 +53,7 @@ namespace Titanium.Web.Proxy ...@@ -53,7 +53,7 @@ namespace Titanium.Web.Proxy
} }
// it may changed in the user event // it may changed in the user event
response = args.WebSession.Response; response = args.HttpClient.Response;
var clientStreamWriter = args.ProxyClient.ClientStreamWriter; var clientStreamWriter = args.ProxyClient.ClientStreamWriter;
...@@ -63,8 +63,8 @@ namespace Titanium.Web.Proxy ...@@ -63,8 +63,8 @@ namespace Titanium.Web.Proxy
//write custom user response with body and return. //write custom user response with body and return.
await clientStreamWriter.WriteResponseAsync(response, cancellationToken: cancellationToken); await clientStreamWriter.WriteResponseAsync(response, cancellationToken: cancellationToken);
if(args.WebSession.ServerConnection != null if(args.HttpClient.Connection != null
&& !args.WebSession.CloseServerConnection) && !args.HttpClient.CloseServerConnection)
{ {
// syphon out the original response body from server connection // syphon out the original response body from server connection
// so that connection will be good to be reused. // so that connection will be good to be reused.
...@@ -80,7 +80,8 @@ namespace Titanium.Web.Proxy ...@@ -80,7 +80,8 @@ namespace Titanium.Web.Proxy
{ {
// clear current response // clear current response
await args.ClearResponse(cancellationToken); await args.ClearResponse(cancellationToken);
await handleHttpSessionRequest(args.WebSession.ServerConnection, args); await handleHttpSessionRequest(args, args.HttpClient.Connection,
args.ClientConnection.NegotiatedApplicationProtocol, cancellationToken);
return; return;
} }
......
...@@ -58,7 +58,7 @@ namespace Titanium.Web.Proxy ...@@ -58,7 +58,7 @@ namespace Titanium.Web.Proxy
} }
// If user requested call back then do it // If user requested call back then do it
if (!args.WebSession.Response.Locked) if (!args.HttpClient.Response.Locked)
{ {
await invokeBeforeResponse(args); await invokeBeforeResponse(args);
} }
......
...@@ -50,7 +50,7 @@ namespace Titanium.Web.Proxy ...@@ -50,7 +50,7 @@ namespace Titanium.Web.Proxy
string headerName = null; string headerName = null;
HttpHeader authHeader = null; HttpHeader authHeader = null;
var response = args.WebSession.Response; var response = args.HttpClient.Response;
// check in non-unique headers first // check in non-unique headers first
var header = response.Headers.NonUniqueHeaders.FirstOrDefault(x => authHeaderNames.Contains(x.Key)); var header = response.Headers.NonUniqueHeaders.FirstOrDefault(x => authHeaderNames.Contains(x.Key));
...@@ -96,14 +96,14 @@ namespace Titanium.Web.Proxy ...@@ -96,14 +96,14 @@ namespace Titanium.Web.Proxy
var expectedAuthState = var expectedAuthState =
scheme == null ? State.WinAuthState.INITIAL_TOKEN : State.WinAuthState.UNAUTHORIZED; scheme == null ? State.WinAuthState.INITIAL_TOKEN : State.WinAuthState.UNAUTHORIZED;
if (!WinAuthEndPoint.ValidateWinAuthState(args.WebSession.Data, expectedAuthState)) if (!WinAuthEndPoint.ValidateWinAuthState(args.HttpClient.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;
} }
var request = args.WebSession.Request; var request = args.HttpClient.Request;
// clear any existing headers to avoid confusing bad servers // clear any existing headers to avoid confusing bad servers
request.Headers.RemoveHeader(KnownHeaders.Authorization); request.Headers.RemoveHeader(KnownHeaders.Authorization);
...@@ -111,7 +111,7 @@ namespace Titanium.Web.Proxy ...@@ -111,7 +111,7 @@ namespace Titanium.Web.Proxy
// initial value will match exactly any of the schemes // initial value will match exactly any of the schemes
if (scheme != null) if (scheme != null)
{ {
string clientToken = WinAuthHandler.GetInitialAuthToken(request.Host, scheme, args.WebSession.Data); string clientToken = WinAuthHandler.GetInitialAuthToken(request.Host, scheme, args.HttpClient.Data);
string auth = string.Concat(scheme, clientToken); string auth = string.Concat(scheme, clientToken);
...@@ -133,7 +133,7 @@ namespace Titanium.Web.Proxy ...@@ -133,7 +133,7 @@ namespace Titanium.Web.Proxy
authHeader.Value.Length > x.Length + 1); authHeader.Value.Length > x.Length + 1);
string serverToken = authHeader.Value.Substring(scheme.Length + 1); string serverToken = authHeader.Value.Substring(scheme.Length + 1);
string clientToken = WinAuthHandler.GetFinalAuthToken(request.Host, serverToken, args.WebSession.Data); string clientToken = WinAuthHandler.GetFinalAuthToken(request.Host, serverToken, args.HttpClient.Data);
string auth = string.Concat(scheme, clientToken); string auth = string.Concat(scheme, clientToken);
...@@ -146,7 +146,7 @@ namespace Titanium.Web.Proxy ...@@ -146,7 +146,7 @@ namespace Titanium.Web.Proxy
request.ContentLength = request.Body.Length; request.ContentLength = request.Body.Length;
} }
args.WebSession.ServerConnection.IsWinAuthenticated = true; args.HttpClient.Connection.IsWinAuthenticated = true;
} }
// Need to revisit this. // Need to revisit this.
...@@ -165,7 +165,7 @@ namespace Titanium.Web.Proxy ...@@ -165,7 +165,7 @@ namespace Titanium.Web.Proxy
/// <returns></returns> /// <returns></returns>
private async Task rewriteUnauthorizedResponse(SessionEventArgs args) private async Task rewriteUnauthorizedResponse(SessionEventArgs args)
{ {
var response = args.WebSession.Response; var response = args.HttpClient.Response;
// Strip authentication headers to avoid credentials prompt in client web browser // Strip authentication headers to avoid credentials prompt in client web browser
foreach (string authHeaderName in authHeaderNames) foreach (string authHeaderName in authHeaderNames)
...@@ -176,7 +176,7 @@ namespace Titanium.Web.Proxy ...@@ -176,7 +176,7 @@ namespace Titanium.Web.Proxy
// Add custom div to body to clarify that the proxy (not the client browser) failed authentication // Add custom div to body to clarify that the proxy (not the client browser) failed authentication
string authErrorMessage = string authErrorMessage =
"<div class=\"inserted-by-proxy\"><h2>NTLM authentication through Titanium.Web.Proxy (" + "<div class=\"inserted-by-proxy\"><h2>NTLM authentication through Titanium.Web.Proxy (" +
args.ProxyClient.ClientConnection.LocalEndPoint + args.ProxyClient.Connection.LocalEndPoint +
") failed. Please check credentials.</h2></div>"; ") failed. Please check credentials.</h2></div>";
string originalErrorMessage = string originalErrorMessage =
"<div class=\"inserted-by-proxy\"><h3>Response from remote web server below.</h3></div><br/>"; "<div class=\"inserted-by-proxy\"><h3>Response from remote web server below.</h3></div><br/>";
......
...@@ -46,9 +46,9 @@ namespace Titanium.Web.Proxy.IntegrationTests ...@@ -46,9 +46,9 @@ namespace Titanium.Web.Proxy.IntegrationTests
public async Task OnRequest(object sender, SessionEventArgs e) public async Task OnRequest(object sender, SessionEventArgs e)
{ {
if (e.WebSession.Request.Url.Contains("interceptthis.com")) if (e.HttpClient.Request.Url.Contains("interceptthis.com"))
{ {
if (e.WebSession.Request.HasBody) if (e.HttpClient.Request.HasBody)
{ {
var body = await e.GetRequestBodyAsString(); var body = await e.GetRequestBodyAsString();
} }
......
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