Commit 743038ef authored by ilushka85's avatar ilushka85

Support for causing a rerequest

parent 82d35f00
...@@ -38,6 +38,13 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -38,6 +38,13 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary> /// </summary>
internal ProxyClient ProxyClient { get; set; } internal ProxyClient ProxyClient { get; set; }
//Should we send a rerequest
public bool ReRequest
{
get;
set;
}
/// <summary> /// <summary>
/// Does this session uses SSL /// Does this session uses SSL
/// </summary> /// </summary>
......
...@@ -296,6 +296,134 @@ namespace Titanium.Web.Proxy ...@@ -296,6 +296,134 @@ namespace Titanium.Web.Proxy
await HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter, await HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter,
endPoint.EnableSsl ? endPoint.GenericCertificateName : null, null); endPoint.EnableSsl ? endPoint.GenericCertificateName : null, null);
} }
private async Task HandleHttpSessionRequestInternal(TcpConnection connection, SessionEventArgs args, ExternalProxy customUpStreamHttpProxy, ExternalProxy customUpStreamHttpsProxy, bool CloseConnection)
{
try
{
if (connection == null)
{
if (args.WebSession.Request.RequestUri.Scheme == "http")
{
if (GetCustomUpStreamHttpProxyFunc != null)
{
customUpStreamHttpProxy = await GetCustomUpStreamHttpProxyFunc(args).ConfigureAwait(false);
}
}
else
{
if (GetCustomUpStreamHttpsProxyFunc != null)
{
customUpStreamHttpsProxy = await GetCustomUpStreamHttpsProxyFunc(args).ConfigureAwait(false);
}
}
args.CustomUpStreamHttpProxyUsed = customUpStreamHttpProxy;
args.CustomUpStreamHttpsProxyUsed = customUpStreamHttpsProxy;
connection = await tcpConnectionFactory.CreateClient(BUFFER_SIZE, ConnectionTimeOutSeconds,
args.WebSession.Request.RequestUri.Host, args.WebSession.Request.RequestUri.Port, args.WebSession.Request.HttpVersion,
args.IsHttps, SupportedSslProtocols,
new RemoteCertificateValidationCallback(ValidateServerCertificate),
new LocalCertificateSelectionCallback(SelectClientCertificate),
customUpStreamHttpProxy ?? UpStreamHttpProxy, customUpStreamHttpsProxy ?? UpStreamHttpsProxy, args.ProxyClient.ClientStream);
}
args.WebSession.Request.RequestLocked = true;
//If request was cancelled by user then dispose the client
if (args.WebSession.Request.CancelRequest)
{
Dispose(args.ProxyClient.ClientStream, args.ProxyClient.ClientStreamReader, args.ProxyClient.ClientStreamWriter, args);
return;
}
//if expect continue is enabled then send the headers first
//and see if server would return 100 conitinue
if (args.WebSession.Request.ExpectContinue)
{
args.WebSession.SetConnection(connection);
await args.WebSession.SendRequest(Enable100ContinueBehaviour);
}
//If 100 continue was the response inform that to the client
if (Enable100ContinueBehaviour)
{
if (args.WebSession.Request.Is100Continue)
{
await WriteResponseStatus(args.WebSession.Response.HttpVersion, "100",
"Continue", args.ProxyClient.ClientStreamWriter);
await args.ProxyClient.ClientStreamWriter.WriteLineAsync();
}
else if (args.WebSession.Request.ExpectationFailed)
{
await WriteResponseStatus(args.WebSession.Response.HttpVersion, "417",
"Expectation Failed", args.ProxyClient.ClientStreamWriter);
await args.ProxyClient.ClientStreamWriter.WriteLineAsync();
}
}
//If expect continue is not enabled then set the connectio and send request headers
if (!args.WebSession.Request.ExpectContinue)
{
args.WebSession.SetConnection(connection);
await args.WebSession.SendRequest(Enable100ContinueBehaviour);
}
//If request was modified by user
if (args.WebSession.Request.RequestBodyRead)
{
if (args.WebSession.Request.ContentEncoding != null)
{
args.WebSession.Request.RequestBody = await GetCompressedResponseBody(args.WebSession.Request.ContentEncoding, args.WebSession.Request.RequestBody);
}
//chunked send is not supported as of now
args.WebSession.Request.ContentLength = args.WebSession.Request.RequestBody.Length;
var newStream = args.WebSession.ServerConnection.Stream;
await newStream.WriteAsync(args.WebSession.Request.RequestBody, 0, args.WebSession.Request.RequestBody.Length);
}
else
{
if (!args.WebSession.Request.ExpectationFailed)
{
//If its a post/put request, then read the client html body and send it to server
if (args.WebSession.Request.Method.ToUpper() == "POST" || args.WebSession.Request.Method.ToUpper() == "PUT")
{
await SendClientRequestBody(args);
}
}
}
//If not expectation failed response was returned by server then parse response
if (!args.WebSession.Request.ExpectationFailed)
{
await HandleHttpSessionResponse(args);
}
//if connection is closing exit
if (args.WebSession.Response.ResponseKeepAlive == false)
{
Dispose(args.ProxyClient.ClientStream, args.ProxyClient.ClientStreamReader, args.ProxyClient.ClientStreamWriter, args);
return;
}
}
catch (Exception e)
{
ProxyServer.ExceptionFunc(e);
Dispose(args.ProxyClient.ClientStream, args.ProxyClient.ClientStreamReader, args.ProxyClient.ClientStreamWriter, args);
return;
}
if (CloseConnection && connection != null)
{
//dispose
connection.Dispose();
}
}
/// <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
/// </summary> /// </summary>
...@@ -323,7 +451,7 @@ namespace Titanium.Web.Proxy ...@@ -323,7 +451,7 @@ namespace Titanium.Web.Proxy
var args = new SessionEventArgs(BUFFER_SIZE, HandleHttpSessionResponse); var args = new SessionEventArgs(BUFFER_SIZE, HandleHttpSessionResponse);
args.ProxyClient.TcpClient = client; args.ProxyClient.TcpClient = client;
args.WebSession.ConnectHeaders = connectHeaders;
try try
{ {
//break up the line into three components (method, remote URL & Http Version) //break up the line into three components (method, remote URL & Http Version)
...@@ -429,125 +557,17 @@ namespace Titanium.Web.Proxy ...@@ -429,125 +557,17 @@ namespace Titanium.Web.Proxy
} }
//construct the web request that we are going to issue on behalf of the client. //construct the web request that we are going to issue on behalf of the client.
if (connection == null) await HandleHttpSessionRequestInternal(connection, args, customUpStreamHttpProxy, customUpStreamHttpsProxy, false).ConfigureAwait(false);
{
if (httpsHostName == null)
{
if (GetCustomUpStreamHttpProxyFunc != null)
{
customUpStreamHttpProxy = await GetCustomUpStreamHttpProxyFunc(args).ConfigureAwait(false);
}
}
else
{
if (GetCustomUpStreamHttpsProxyFunc != null)
{
args.WebSession.ConnectHeaders = connectHeaders;
customUpStreamHttpsProxy = await GetCustomUpStreamHttpsProxyFunc(args).ConfigureAwait(false);
}
}
args.CustomUpStreamHttpProxyUsed = customUpStreamHttpProxy;
args.CustomUpStreamHttpsProxyUsed = customUpStreamHttpsProxy;
connection = await tcpConnectionFactory.CreateClient(BUFFER_SIZE, ConnectionTimeOutSeconds,
args.WebSession.Request.RequestUri.Host, args.WebSession.Request.RequestUri.Port, httpVersion,
args.IsHttps, SupportedSslProtocols,
new RemoteCertificateValidationCallback(ValidateServerCertificate),
new LocalCertificateSelectionCallback(SelectClientCertificate),
customUpStreamHttpProxy ?? UpStreamHttpProxy, customUpStreamHttpsProxy ?? UpStreamHttpsProxy, clientStream);
}
else
{
if (connection.IsHttps)
{
args.CustomUpStreamHttpsProxyUsed = connection.UpStreamHttpsProxy;
}
else
{
args.CustomUpStreamHttpProxyUsed = connection.UpStreamHttpProxy;
}
}
args.WebSession.Request.RequestLocked = true;
//If request was cancelled by user then dispose the client
if (args.WebSession.Request.CancelRequest) if (args.WebSession.Request.CancelRequest)
{ {
Dispose(clientStream, clientStreamReader, clientStreamWriter, args);
break; break;
} }
//if expect continue is enabled then send the headers first
//and see if server would return 100 conitinue
if (args.WebSession.Request.ExpectContinue)
{
args.WebSession.SetConnection(connection);
await args.WebSession.SendRequest(Enable100ContinueBehaviour);
}
//If 100 continue was the response inform that to the client
if (Enable100ContinueBehaviour)
{
if (args.WebSession.Request.Is100Continue)
{
await WriteResponseStatus(args.WebSession.Response.HttpVersion, "100",
"Continue", args.ProxyClient.ClientStreamWriter);
await args.ProxyClient.ClientStreamWriter.WriteLineAsync();
}
else if (args.WebSession.Request.ExpectationFailed)
{
await WriteResponseStatus(args.WebSession.Response.HttpVersion, "417",
"Expectation Failed", args.ProxyClient.ClientStreamWriter);
await args.ProxyClient.ClientStreamWriter.WriteLineAsync();
}
}
//If expect continue is not enabled then set the connectio and send request headers
if (!args.WebSession.Request.ExpectContinue)
{
args.WebSession.SetConnection(connection);
await args.WebSession.SendRequest(Enable100ContinueBehaviour);
}
//If request was modified by user
if (args.WebSession.Request.RequestBodyRead)
{
if (args.WebSession.Request.ContentEncoding != null)
{
args.WebSession.Request.RequestBody = await GetCompressedResponseBody(args.WebSession.Request.ContentEncoding, args.WebSession.Request.RequestBody);
}
//chunked send is not supported as of now
args.WebSession.Request.ContentLength = args.WebSession.Request.RequestBody.Length;
var newStream = args.WebSession.ServerConnection.Stream;
await newStream.WriteAsync(args.WebSession.Request.RequestBody, 0, args.WebSession.Request.RequestBody.Length);
}
else
{
if (!args.WebSession.Request.ExpectationFailed)
{
//If its a post/put request, then read the client html body and send it to server
if (httpMethod.ToUpper() == "POST" || httpMethod.ToUpper() == "PUT")
{
await SendClientRequestBody(args);
}
}
}
//If not expectation failed response was returned by server then parse response
if (!args.WebSession.Request.ExpectationFailed)
{
await HandleHttpSessionResponse(args);
}
//if connection is closing exit //if connection is closing exit
if (args.WebSession.Response.ResponseKeepAlive == false) if (args.WebSession.Response.ResponseKeepAlive == false)
{ {
Dispose(clientStream, clientStreamReader, clientStreamWriter, args);
break; break;
} }
...@@ -557,6 +577,7 @@ namespace Titanium.Web.Proxy ...@@ -557,6 +577,7 @@ namespace Titanium.Web.Proxy
} }
catch (Exception e) catch (Exception e)
{ {
ProxyServer.ExceptionFunc(e);
Dispose(clientStream, clientStreamReader, clientStreamWriter, args); Dispose(clientStream, clientStreamReader, clientStreamWriter, args);
break; break;
} }
......
...@@ -29,6 +29,7 @@ namespace Titanium.Web.Proxy ...@@ -29,6 +29,7 @@ namespace Titanium.Web.Proxy
args.WebSession.Response.ResponseStream = args.WebSession.ServerConnection.Stream; args.WebSession.Response.ResponseStream = args.WebSession.ServerConnection.Stream;
} }
args.ReRequest = false;
//If user requested call back then do it //If user requested call back then do it
if (BeforeResponse != null && !args.WebSession.Response.ResponseLocked) if (BeforeResponse != null && !args.WebSession.Response.ResponseLocked)
{ {
...@@ -37,12 +38,16 @@ namespace Titanium.Web.Proxy ...@@ -37,12 +38,16 @@ namespace Titanium.Web.Proxy
for (int i = 0; i < invocationList.Length; i++) for (int i = 0; i < invocationList.Length; i++)
{ {
handlerTasks[i] = ((Func<object, SessionEventArgs, Task>)invocationList[i])(null, args); handlerTasks[i] = ((Func<object, SessionEventArgs, Task>)invocationList[i])(this, args);
} }
await Task.WhenAll(handlerTasks); await Task.WhenAll(handlerTasks);
} }
if(args.ReRequest)
{
await HandleHttpSessionRequestInternal(null, args, null, null, true).ConfigureAwait(false);
return;
}
args.WebSession.Response.ResponseLocked = true; args.WebSession.Response.ResponseLocked = true;
//Write back to client 100-conitinue response if that's what server returned //Write back to client 100-conitinue response if that's what server returned
......
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