Commit ffe306c2 authored by titanium007's avatar titanium007

Separate request & response

parent f69bed23
......@@ -43,7 +43,7 @@ namespace Titanium.Web.Proxy.Test
//Read browser URL send back to proxy by the injection script in OnResponse event
public void OnRequest(object sender, SessionEventArgs e)
{
Console.WriteLine(e.RequestUrl);
Console.WriteLine(e.ProxySession.Request.RequestUrl);
////read request headers
//var requestHeaders = e.RequestHeaders;
......
......@@ -13,6 +13,17 @@ using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.EventArguments
{
public class Client
{
internal TcpClient TcpClient { get; set; }
internal Stream ClientStream { get; set; }
internal CustomBinaryReader ClientStreamReader { get; set; }
internal StreamWriter ClientStreamWriter { get; set; }
public int ClientPort { get; internal set; }
public IPAddress ClientIpAddress { get; internal set; }
}
public class SessionEventArgs : EventArgs, IDisposable
{
readonly int _bufferSize;
......@@ -20,47 +31,25 @@ namespace Titanium.Web.Proxy.EventArguments
internal SessionEventArgs(int bufferSize)
{
_bufferSize = bufferSize;
Client = new Client();
ProxySession = new Http.HttpWebSession();
}
internal TcpClient Client { get; set; }
internal Stream ClientStream { get; set; }
internal CustomBinaryReader ClientStreamReader { get; set; }
internal StreamWriter ClientStreamWriter { get; set; }
public Client Client { get; set; }
public bool IsHttps { get; internal set; }
public string RequestUrl { get; internal set; }
public string RequestHostname { get; internal set; }
public int ClientPort { get; internal set; }
public IPAddress ClientIpAddress { get; internal set; }
public HttpWebSession ProxySession { get; set; }
internal Encoding RequestEncoding { get; set; }
internal Version RequestHttpVersion { get; set; }
internal bool RequestIsAlive { get; set; }
internal bool CancelRequest { get; set; }
internal byte[] RequestBody { get; set; }
internal string RequestBodyString { get; set; }
internal bool RequestBodyRead { get; set; }
public List<HttpHeader> RequestHeaders { get; internal set; }
internal bool RequestLocked { get; set; }
internal HttpWebSession ProxySession { get; set; }
internal Encoding ResponseEncoding { get; set; }
internal Stream ResponseStream { get; set; }
internal byte[] ResponseBody { get; set; }
internal string ResponseBodyString { get; set; }
internal bool ResponseBodyRead { get; set; }
public List<HttpHeader> ResponseHeaders { get; internal set; }
internal bool ResponseLocked { get; set; }
public int RequestContentLength
{
get
{
if (RequestHeaders.All(x => x.Name.ToLower() != "content-length")) return -1;
if (ProxySession.Request.RequestHeaders.All(x => x.Name.ToLower() != "content-length")) return -1;
int contentLen;
int.TryParse(RequestHeaders.First(x => x.Name.ToLower() == "content-length").Value, out contentLen);
int.TryParse(ProxySession.Request.RequestHeaders.First(x => x.Name.ToLower() == "content-length").Value, out contentLen);
if (contentLen != 0)
return contentLen;
return -1;
......@@ -75,15 +64,15 @@ namespace Titanium.Web.Proxy.EventArguments
public string ResponseStatusCode
{
get { return ProxySession.Response.ResponseStatusCode; }
get { return ProxySession.Response.ResponseStatusCode; }
}
public string ResponseContentType
{
get
{
return ResponseHeaders.Any(x => x.Name.ToLower() == "content-type")
? ResponseHeaders.First(x => x.Name.ToLower() == "content-type").Value
return ProxySession.Response.ResponseHeaders.Any(x => x.Name.ToLower() == "content-type")
? ProxySession.Response.ResponseHeaders.First(x => x.Name.ToLower() == "content-type").Value
: null;
}
}
......@@ -108,21 +97,21 @@ namespace Titanium.Web.Proxy.EventArguments
"Please verify that this request is a Http POST/PUT and request content length is greater than zero before accessing the body.");
}
if (RequestBody == null)
if (ProxySession.Request.RequestBody == null)
{
var isChunked = false;
string requestContentEncoding = null;
if (RequestHeaders.Any(x => x.Name.ToLower() == "content-encoding"))
if (ProxySession.Request.RequestHeaders.Any(x => x.Name.ToLower() == "content-encoding"))
{
requestContentEncoding = RequestHeaders.First(x => x.Name.ToLower() == "content-encoding").Value;
requestContentEncoding = ProxySession.Request.RequestHeaders.First(x => x.Name.ToLower() == "content-encoding").Value;
}
if (RequestHeaders.Any(x => x.Name.ToLower() == "transfer-encoding"))
if (ProxySession.Request.RequestHeaders.Any(x => x.Name.ToLower() == "transfer-encoding"))
{
var transferEncoding =
RequestHeaders.First(x => x.Name.ToLower() == "transfer-encoding").Value.ToLower();
ProxySession.Request.RequestHeaders.First(x => x.Name.ToLower() == "transfer-encoding").Value.ToLower();
if (transferEncoding.Contains("chunked"))
{
isChunked = true;
......@@ -131,7 +120,7 @@ namespace Titanium.Web.Proxy.EventArguments
if (requestContentEncoding == null && !isChunked)
RequestBody = ClientStreamReader.ReadBytes(RequestContentLength);
ProxySession.Request.RequestBody = this.Client.ClientStreamReader.ReadBytes(RequestContentLength);
else
{
using (var requestBodyStream = new MemoryStream())
......@@ -140,19 +129,19 @@ namespace Titanium.Web.Proxy.EventArguments
{
while (true)
{
var chuchkHead = ClientStreamReader.ReadLine();
var chuchkHead = this.Client.ClientStreamReader.ReadLine();
var chunkSize = int.Parse(chuchkHead, NumberStyles.HexNumber);
if (chunkSize != 0)
{
var buffer = ClientStreamReader.ReadBytes(chunkSize);
var buffer = this.Client.ClientStreamReader.ReadBytes(chunkSize);
requestBodyStream.Write(buffer, 0, buffer.Length);
//chunk trail
ClientStreamReader.ReadLine();
this.Client.ClientStreamReader.ReadLine();
}
else
{
ClientStreamReader.ReadLine();
this.Client.ClientStreamReader.ReadLine();
break;
}
}
......@@ -162,50 +151,50 @@ namespace Titanium.Web.Proxy.EventArguments
switch (requestContentEncoding)
{
case "gzip":
RequestBody = CompressionHelper.DecompressGzip(requestBodyStream);
ProxySession.Request.RequestBody = CompressionHelper.DecompressGzip(requestBodyStream);
break;
case "deflate":
RequestBody = CompressionHelper.DecompressDeflate(requestBodyStream);
ProxySession.Request.RequestBody = CompressionHelper.DecompressDeflate(requestBodyStream);
break;
case "zlib":
RequestBody = CompressionHelper.DecompressZlib(requestBodyStream);
ProxySession.Request.RequestBody = CompressionHelper.DecompressZlib(requestBodyStream);
break;
default:
RequestBody = requestBodyStream.ToArray();
ProxySession.Request.RequestBody = requestBodyStream.ToArray();
break;
}
}
catch
{
RequestBody = requestBodyStream.ToArray();
ProxySession.Request.RequestBody = requestBodyStream.ToArray();
}
}
}
}
RequestBodyRead = true;
ProxySession.Request.RequestBodyRead = true;
}
private void ReadResponseBody()
{
if (ResponseBody == null)
if (ProxySession.Response.ResponseBody == null)
{
switch ( ProxySession.Response.ResponseContentEncoding)
switch (ProxySession.Response.ResponseContentEncoding)
{
case "gzip":
ResponseBody = CompressionHelper.DecompressGzip(ResponseStream);
ProxySession.Response.ResponseBody = CompressionHelper.DecompressGzip(ProxySession.Response.ResponseStream);
break;
case "deflate":
ResponseBody = CompressionHelper.DecompressDeflate(ResponseStream);
ProxySession.Response.ResponseBody = CompressionHelper.DecompressDeflate(ProxySession.Response.ResponseStream);
break;
case "zlib":
ResponseBody = CompressionHelper.DecompressZlib(ResponseStream);
ProxySession.Response.ResponseBody = CompressionHelper.DecompressZlib(ProxySession.Response.ResponseStream);
break;
default:
ResponseBody = DecodeData(ResponseStream);
ProxySession.Response.ResponseBody = DecodeData(ProxySession.Response.ResponseStream);
break;
}
ResponseBodyRead = true;
ProxySession.Response.ResponseBodyRead = true;
}
}
......@@ -227,116 +216,116 @@ namespace Titanium.Web.Proxy.EventArguments
public Encoding GetRequestBodyEncoding()
{
if (RequestLocked) throw new Exception("You cannot call this function after request is made to server.");
if (ProxySession.Request.RequestLocked) throw new Exception("You cannot call this function after request is made to server.");
return RequestEncoding;
return ProxySession.Request.RequestEncoding;
}
public byte[] GetRequestBody()
{
if (RequestLocked) throw new Exception("You cannot call this function after request is made to server.");
if (ProxySession.Request.RequestLocked) throw new Exception("You cannot call this function after request is made to server.");
ReadRequestBody();
return RequestBody;
return ProxySession.Request.RequestBody;
}
public string GetRequestBodyAsString()
{
if (RequestLocked) throw new Exception("You cannot call this function after request is made to server.");
if (ProxySession.Request.RequestLocked) throw new Exception("You cannot call this function after request is made to server.");
ReadRequestBody();
return RequestBodyString ?? (RequestBodyString = RequestEncoding.GetString(RequestBody));
return ProxySession.Request.RequestBodyString ?? (ProxySession.Request.RequestBodyString = ProxySession.Request.RequestEncoding.GetString(ProxySession.Request.RequestBody));
}
public void SetRequestBody(byte[] body)
{
if (RequestLocked) throw new Exception("You cannot call this function after request is made to server.");
if (ProxySession.Request.RequestLocked) throw new Exception("You cannot call this function after request is made to server.");
if (!RequestBodyRead)
if (!ProxySession.Request.RequestBodyRead)
{
ReadRequestBody();
}
RequestBody = body;
RequestBodyRead = true;
ProxySession.Request.RequestBody = body;
ProxySession.Request.RequestBodyRead = true;
}
public void SetRequestBodyString(string body)
{
if (RequestLocked) throw new Exception("You cannot call this function after request is made to server.");
if (ProxySession.Request.RequestLocked) throw new Exception("You cannot call this function after request is made to server.");
if (!RequestBodyRead)
if (!ProxySession.Request.RequestBodyRead)
{
ReadRequestBody();
}
RequestBody = RequestEncoding.GetBytes(body);
RequestBodyRead = true;
ProxySession.Request.RequestBody = ProxySession.Request.RequestEncoding.GetBytes(body);
ProxySession.Request.RequestBodyRead = true;
}
public Encoding GetResponseBodyEncoding()
{
if (!RequestLocked) throw new Exception("You cannot call this function before request is made to server.");
if (!ProxySession.Request.RequestLocked) throw new Exception("You cannot call this function before request is made to server.");
return ResponseEncoding;
return ProxySession.Response.ResponseEncoding;
}
public byte[] GetResponseBody()
{
if (!RequestLocked) throw new Exception("You cannot call this function before request is made to server.");
if (!ProxySession.Request.RequestLocked) throw new Exception("You cannot call this function before request is made to server.");
ReadResponseBody();
return ResponseBody;
return ProxySession.Response.ResponseBody;
}
public string GetResponseBodyAsString()
{
if (!RequestLocked) throw new Exception("You cannot call this function before request is made to server.");
if (!ProxySession.Request.RequestLocked) throw new Exception("You cannot call this function before request is made to server.");
GetResponseBody();
return ResponseBodyString ?? (ResponseBodyString = ResponseEncoding.GetString(ResponseBody));
return ProxySession.Response.ResponseBodyString ?? (ProxySession.Response.ResponseBodyString = ProxySession.Response.ResponseEncoding.GetString(ProxySession.Response.ResponseBody));
}
public void SetResponseBody(byte[] body)
{
if (!RequestLocked) throw new Exception("You cannot call this function before request is made to server.");
if (!ProxySession.Request.RequestLocked) throw new Exception("You cannot call this function before request is made to server.");
if (ResponseBody == null)
if (ProxySession.Response.ResponseBody == null)
{
GetResponseBody();
}
ResponseBody = body;
ProxySession.Response.ResponseBody = body;
}
public void SetResponseBodyString(string body)
{
if (!RequestLocked) throw new Exception("You cannot call this function before request is made to server.");
if (!ProxySession.Request.RequestLocked) throw new Exception("You cannot call this function before request is made to server.");
if (ResponseBody == null)
if (ProxySession.Response.ResponseBody == null)
{
GetResponseBody();
}
var bodyBytes = ResponseEncoding.GetBytes(body);
var bodyBytes = ProxySession.Response.ResponseEncoding.GetBytes(body);
SetResponseBody(bodyBytes);
}
public void Ok(string html)
{
if (RequestLocked) throw new Exception("You cannot call this function after request is made to server.");
if (ProxySession.Request.RequestLocked) throw new Exception("You cannot call this function after request is made to server.");
if (html == null)
html = string.Empty;
var result = Encoding.Default.GetBytes(html);
var connectStreamWriter = new StreamWriter(ClientStream);
var s = string.Format("HTTP/{0}.{1} {2} {3}", RequestHttpVersion.Major, RequestHttpVersion.Minor, 200, "Ok");
var connectStreamWriter = new StreamWriter(this.Client.ClientStream);
var s = string.Format("HTTP/{0}.{1} {2} {3}", ProxySession.Request.RequestHttpVersion.Major, ProxySession.Request.RequestHttpVersion.Minor, 200, "Ok");
connectStreamWriter.WriteLine(s);
connectStreamWriter.WriteLine("Timestamp: {0}", DateTime.Now);
connectStreamWriter.WriteLine("content-length: " + result.Length);
......@@ -344,15 +333,15 @@ namespace Titanium.Web.Proxy.EventArguments
connectStreamWriter.WriteLine("Pragma: no-cache");
connectStreamWriter.WriteLine("Expires: 0");
connectStreamWriter.WriteLine(RequestIsAlive ? "Connection: Keep-Alive" : "Connection: close");
connectStreamWriter.WriteLine(ProxySession.Request.RequestIsAlive ? "Connection: Keep-Alive" : "Connection: close");
connectStreamWriter.WriteLine();
connectStreamWriter.Flush();
ClientStream.Write(result, 0, result.Length);
this.Client.ClientStream.Write(result, 0, result.Length);
CancelRequest = true;
ProxySession.Request.CancelRequest = true;
}
}
}
\ No newline at end of file
......@@ -15,25 +15,29 @@ namespace Titanium.Web.Proxy.Http
public class Request
{
public string Method { get; set; }
public Uri RequestUri { get; set; }
public string Version { get; set; }
public List<HttpHeader> RequestHeaders { get; set; }
public string RequestStatus { get; set; }
public int RequestContentLength { get; set; }
public bool RequestSendChunked { get; set; }
public string RequestContentType { get; set; }
public bool RequestKeepAlive { get; set; }
public string RequestHost { get; set; }
public string RequestUrl { get; internal set; }
public string RequestHostname { get; internal set; }
internal Encoding RequestEncoding { get; set; }
internal Version RequestHttpVersion { get; set; }
internal bool RequestIsAlive { get; set; }
internal bool CancelRequest { get; set; }
internal byte[] RequestBody { get; set; }
internal string RequestBodyString { get; set; }
internal bool RequestBodyRead { get; set; }
public List<HttpHeader> RequestHeaders { get; internal set; }
internal bool RequestLocked { get; set; }
public Request()
{
this.RequestHeaders = new List<HttpHeader>();
......@@ -43,28 +47,28 @@ namespace Titanium.Web.Proxy.Http
public class Response
{
public List<HttpHeader> ResponseHeaders { get; set; }
internal Encoding ResponseEncoding { get; set; }
internal Stream ResponseStream { get; set; }
internal byte[] ResponseBody { get; set; }
internal string ResponseBodyString { get; set; }
internal bool ResponseBodyRead { get; set; }
internal bool ResponseLocked { get; set; }
public List<HttpHeader> ResponseHeaders { get; internal set; }
public string ResponseCharacterSet { get; set; }
public string ResponseContentEncoding { get; set; }
public System.Version ResponseProtocolVersion { get; set; }
public string ResponseStatusCode { get; set; }
public string ResponseStatusDescription { get; set; }
public bool ResponseKeepAlive { get; set; }
public string ResponseContentType { get; set; }
public int ContentLength { get; set; }
public Response()
{
this.ResponseHeaders = new List<HttpHeader>();
}
public int ContentLength { get; set; }
}
public class HttpWebSession
......@@ -81,27 +85,26 @@ namespace Titanium.Web.Proxy.Http
public Request Request { get; set; }
public Response Response { get; set; }
public TcpConnection Client { get; set; }
public TcpConnection ProxyClient { get; set; }
public void SetConnection(TcpConnection Connection)
{
Client = Connection;
ServerStreamReader = Client.ServerStreamReader;
ProxyClient = Connection;
}
public HttpWebSession()
{
this.Request = new Request();
this.Response = new Response();
}
public CustomBinaryReader ServerStreamReader { get; set; }
public async Task SendRequest()
public void SendRequest()
{
Stream stream = Client.Stream;
Stream stream = ProxyClient.Stream;
StringBuilder requestLines = new StringBuilder();
......@@ -122,13 +125,13 @@ namespace Titanium.Web.Proxy.Http
string request = requestLines.ToString();
byte[] requestBytes = Encoding.ASCII.GetBytes(request);
await AsyncExtensions.WriteAsync((Stream)stream, requestBytes, 0, requestBytes.Length);
await AsyncExtensions.FlushAsync((Stream)stream);
stream.Write(requestBytes, 0, requestBytes.Length);
stream.Flush();
}
public void ReceiveResponse()
{
var httpResult = ServerStreamReader.ReadLine().Split(new char[] { ' ' }, 3);
{
var httpResult = ProxyClient.ServerStreamReader.ReadLine().Split(new char[] { ' ' }, 3);
var httpVersion = httpResult[0];
......@@ -148,7 +151,7 @@ namespace Titanium.Web.Proxy.Http
this.Response.ResponseStatusDescription = status;
List<string> responseLines = ServerStreamReader.ReadAllLines();
List<string> responseLines = ProxyClient.ServerStreamReader.ReadAllLines();
for (int index = 0; index < responseLines.Count; ++index)
{
......
......@@ -22,25 +22,28 @@ namespace Titanium.Web.Proxy.Http
{
static ConcurrentDictionary<string, ConcurrentStack<TcpConnection>> ConnectionCache = new ConcurrentDictionary<string, ConcurrentStack<TcpConnection>>();
public static async Task<TcpConnection> GetClient(string Hostname, int port, bool IsSecure)
public static TcpConnection GetClient(string Hostname, int port, bool IsSecure)
{
var key = string.Concat(Hostname, ":", port, ":", IsSecure);
ConcurrentStack<TcpConnection> connections;
if (!ConnectionCache.TryGetValue(key, out connections))
{
return await CreateClient(Hostname, port, IsSecure);
}
TcpConnection client;
if (!connections.TryPop(out client))
lock (ConnectionCache)
{
return await CreateClient(Hostname, port, IsSecure);
ConcurrentStack<TcpConnection> connections;
if (!ConnectionCache.TryGetValue(key, out connections))
{
return CreateClient(Hostname, port, IsSecure);
}
if (!connections.TryPop(out client))
{
return CreateClient(Hostname, port, IsSecure);
}
}
return client;
}
private static async Task<TcpConnection> CreateClient(string Hostname, int port, bool IsSecure)
private static TcpConnection CreateClient(string Hostname, int port, bool IsSecure)
{
var client = new TcpClient(Hostname, port);
var stream = (Stream)client.GetStream();
......@@ -51,7 +54,7 @@ namespace Titanium.Web.Proxy.Http
try
{
sslStream = new SslStream(stream);
await AsyncPlatformExtensions.AuthenticateAsClientAsync(sslStream, Hostname);
sslStream.AuthenticateAsClient(Hostname);
stream = (Stream)sslStream;
}
catch
......@@ -68,17 +71,20 @@ namespace Titanium.Web.Proxy.Http
public static void AddClient(string Hostname, int port, bool IsSecure, TcpConnection Client)
{
var key = string.Concat(Hostname, ":", port, ":", IsSecure);
ConcurrentStack<TcpConnection> connections;
if (!ConnectionCache.TryGetValue(key, out connections))
lock (ConnectionCache)
{
connections = new ConcurrentStack<TcpConnection>();
ConcurrentStack<TcpConnection> connections;
if (!ConnectionCache.TryGetValue(key, out connections))
{
connections = new ConcurrentStack<TcpConnection>();
connections.Push(Client);
ConnectionCache.TryAdd(key, connections);
}
connections.Push(Client);
ConnectionCache.TryAdd(key, connections);
}
connections.Push(Client);
}
......
......@@ -112,7 +112,7 @@ namespace Titanium.Web.Proxy
}
private static async void HandleHttpSessionRequest(TcpClient client, string httpCmd, Stream clientStream,
private static void HandleHttpSessionRequest(TcpClient client, string httpCmd, Stream clientStream,
CustomBinaryReader clientStreamReader, StreamWriter clientStreamWriter, string secureTunnelHostName)
{
while (true)
......@@ -124,7 +124,7 @@ namespace Titanium.Web.Proxy
}
var args = new SessionEventArgs(BUFFER_SIZE);
args.Client = client;
args.Client.TcpClient = client;
try
{
......@@ -151,33 +151,34 @@ namespace Titanium.Web.Proxy
args.IsHttps = true;
}
args.RequestHeaders = new List<HttpHeader>();
args.ProxySession.Request.RequestHeaders = new List<HttpHeader>();
string tmpLine;
while (!string.IsNullOrEmpty(tmpLine = clientStreamReader.ReadLine()))
{
var header = tmpLine.Split(new char[] { ':' }, 2);
args.RequestHeaders.Add(new HttpHeader(header[0], header[1]));
args.ProxySession.Request.RequestHeaders.Add(new HttpHeader(header[0], header[1]));
}
for (var i = 0; i < args.RequestHeaders.Count; i++)
for (var i = 0; i < args.ProxySession.Request.RequestHeaders.Count; i++)
{
var rawHeader = args.RequestHeaders[i];
var rawHeader = args.ProxySession.Request.RequestHeaders[i];
//if request was upgrade to web-socket protocol then relay the request without proxying
if ((rawHeader.Name.ToLower() == "upgrade") && (rawHeader.Value.ToLower() == "websocket"))
{
TcpHelper.SendRaw(clientStreamReader.BaseStream, httpCmd, args.RequestHeaders,
TcpHelper.SendRaw(clientStreamReader.BaseStream, httpCmd, args.ProxySession.Request.RequestHeaders,
httpRemoteUri.Host, httpRemoteUri.Port, httpRemoteUri.Scheme == Uri.UriSchemeHttps);
Dispose(client, clientStream, clientStreamReader, clientStreamWriter, args);
return;
}
}
args.ProxySession = new Http.HttpWebSession();
args.ProxySession.Request.RequestUri = httpRemoteUri;
......@@ -186,16 +187,16 @@ namespace Titanium.Web.Proxy
args.ProxySession.Request.Method = httpMethod;
args.ProxySession.Request.Version = httpVersion;
// args.ProxyRequest.ProtocolVersion = version;
args.ClientStream = clientStream;
args.ClientStreamReader = clientStreamReader;
args.ClientStreamWriter = clientStreamWriter;
args.Client.ClientStream = clientStream;
args.Client.ClientStreamReader = clientStreamReader;
args.Client.ClientStreamWriter = clientStreamWriter;
// args.ProxyRequest.AllowAutoRedirect = false;
// args.ProxyRequest.AutomaticDecompression = DecompressionMethods.None;
args.RequestHostname = args.ProxySession.Request.RequestUri.Host;
args.RequestUrl = args.ProxySession.Request.RequestUri.OriginalString;
args.ClientPort = ((IPEndPoint)client.Client.RemoteEndPoint).Port;
args.ClientIpAddress = ((IPEndPoint)client.Client.RemoteEndPoint).Address;
args.RequestHttpVersion = version;
args.ProxySession.Request.RequestHostname = args.ProxySession.Request.RequestUri.Host;
args.ProxySession.Request.RequestUrl = args.ProxySession.Request.RequestUri.OriginalString;
args.Client.ClientPort = ((IPEndPoint)client.Client.RemoteEndPoint).Port;
args.Client.ClientIpAddress = ((IPEndPoint)client.Client.RemoteEndPoint).Address;
args.ProxySession.Request.RequestHttpVersion = version;
//args.RequestIsAlive = args.ProxyRequest.KeepAlive;
//args.ProxyRequest.AllowWriteStreamBuffering = true;
......@@ -204,30 +205,30 @@ namespace Titanium.Web.Proxy
//If requested interception
if (BeforeRequest != null)
{
args.RequestEncoding = args.ProxySession.GetEncoding();
args.ProxySession.Request.RequestEncoding = args.ProxySession.GetEncoding();
BeforeRequest(null, args);
}
args.RequestLocked = true;
args.ProxySession.Request.RequestLocked = true;
if (args.CancelRequest)
if (args.ProxySession.Request.CancelRequest)
{
Dispose(client, clientStream, clientStreamReader, clientStreamWriter, args);
return;
}
SetRequestHeaders(args.RequestHeaders, args.ProxySession);
//construct the web request that we are going to issue on behalf of the client.
var connection = await TcpConnectionManager.GetClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps);
SetRequestHeaders(args.ProxySession.Request.RequestHeaders, args.ProxySession);
//construct the web request that we are going to issue on behalf of the client.
var connection = TcpConnectionManager.GetClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps);
args.ProxySession.SetConnection(connection);
await args.ProxySession.SendRequest();
args.ProxySession.SendRequest();
//If request was modified by user
if (args.RequestBodyRead)
if (args.ProxySession.Request.RequestBodyRead)
{
args.ProxySession.Request.RequestContentLength = args.RequestBody.Length;
var newStream = args.ProxySession.ServerStreamReader.BaseStream;
newStream.Write(args.RequestBody, 0, args.RequestBody.Length);
args.ProxySession.Request.RequestContentLength = args.ProxySession.Request.RequestBody.Length;
var newStream = args.ProxySession.ProxyClient.ServerStreamReader.BaseStream;
newStream.Write(args.ProxySession.Request.RequestBody, 0, args.ProxySession.Request.RequestBody.Length);
}
else
{
......@@ -241,14 +242,15 @@ namespace Titanium.Web.Proxy
HandleHttpSessionResponse(args);
//if connection is closing exit
if (args.ResponseHeaders.Any(x => x.Name.ToLower() == "connection" && x.Value.ToLower() == "close"))
if (args.ProxySession.Response.ResponseHeaders.Any(x => x.Name.ToLower() == "connection" && x.Value.ToLower() == "close"))
{
Dispose(client, clientStream, clientStreamReader, clientStreamWriter, args);
return;
}
TcpConnectionManager.AddClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps, args.ProxySession.Client);
// read the next request
//if (args.ProxySession.ProxyClient.Client.Connected)
// TcpConnectionManager.AddClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps, args.ProxySession.ProxyClient);
// // read the next request
httpCmd = clientStreamReader.ReadLine();
}
......@@ -380,7 +382,7 @@ namespace Titanium.Web.Proxy
private static void SendClientRequestBody(SessionEventArgs args)
{
// End the operation
var postStream = args.ProxySession.ServerStreamReader;
var postStream = args.ProxySession.ProxyClient.ServerStreamReader;
if (args.ProxySession.Request.RequestContentLength > 0)
......@@ -401,7 +403,7 @@ namespace Titanium.Web.Proxy
while (totalbytesRead < (int)args.ProxySession.Request.RequestContentLength)
{
var buffer = args.ClientStreamReader.ReadBytes(bytesToRead);
var buffer = args.Client.ClientStreamReader.ReadBytes(bytesToRead);
totalbytesRead += buffer.Length;
var remainingBytes = (int)args.ProxySession.Request.RequestContentLength - totalbytesRead;
......@@ -412,12 +414,12 @@ namespace Titanium.Web.Proxy
postStream.BaseStream.Write(buffer, 0, buffer.Length);
}
postStream.Close();
//postStream.Close();
}
catch
{
postStream.Close();
postStream.Dispose();
// postStream.Close();
// postStream.Dispose();
throw;
}
}
......@@ -430,30 +432,30 @@ namespace Titanium.Web.Proxy
{
while (true)
{
var chuchkHead = args.ClientStreamReader.ReadLine();
var chuchkHead = args.Client.ClientStreamReader.ReadLine();
var chunkSize = int.Parse(chuchkHead, NumberStyles.HexNumber);
if (chunkSize != 0)
{
var buffer = args.ClientStreamReader.ReadBytes(chunkSize);
var buffer = args.Client.ClientStreamReader.ReadBytes(chunkSize);
postStream.BaseStream.Write(buffer, 0, buffer.Length);
//chunk trail
args.ClientStreamReader.ReadLine();
args.Client.ClientStreamReader.ReadLine();
}
else
{
args.ClientStreamReader.ReadLine();
args.Client.ClientStreamReader.ReadLine();
break;
}
}
postStream.Close();
//postStream.Close();
}
catch
{
postStream.Close();
postStream.Dispose();
// postStream.Close();
// postStream.Dispose();
throw;
}
......
......@@ -26,19 +26,19 @@ namespace Titanium.Web.Proxy
try
{
args.ResponseHeaders = ReadResponseHeaders(args.ProxySession);
args.ResponseStream = args.ProxySession.ServerStreamReader.BaseStream;
args.ProxySession.Response.ResponseHeaders = ReadResponseHeaders(args.ProxySession);
args.ProxySession.Response.ResponseStream = args.ProxySession.ProxyClient.ServerStreamReader.BaseStream;
if (BeforeResponse != null)
{
args.ResponseEncoding = args.ProxySession.GetResponseEncoding();
args.ProxySession.Response.ResponseEncoding = args.ProxySession.GetResponseEncoding();
BeforeResponse(null, args);
}
args.ResponseLocked = true;
args.ProxySession.Response.ResponseLocked = true;
if (args.ResponseBodyRead)
if (args.ProxySession.Response.ResponseBodyRead)
{
var isChunked = args.ProxySession.Response.ResponseHeaders.Any(x => x.Name.ToLower() == "transfer-encoding" && x.Value.ToLower().Contains("chunked"));
var contentEncoding = args.ProxySession.Response.ResponseContentEncoding;
......@@ -46,40 +46,40 @@ namespace Titanium.Web.Proxy
switch (contentEncoding.ToLower())
{
case "gzip":
args.ResponseBody = CompressionHelper.CompressGzip(args.ResponseBody);
args.ProxySession.Response.ResponseBody = CompressionHelper.CompressGzip(args.ProxySession.Response.ResponseBody);
break;
case "deflate":
args.ResponseBody = CompressionHelper.CompressDeflate(args.ResponseBody);
args.ProxySession.Response.ResponseBody = CompressionHelper.CompressDeflate(args.ProxySession.Response.ResponseBody);
break;
case "zlib":
args.ResponseBody = CompressionHelper.CompressZlib(args.ResponseBody);
args.ProxySession.Response.ResponseBody = CompressionHelper.CompressZlib(args.ProxySession.Response.ResponseBody);
break;
}
WriteResponseStatus(args.ProxySession.Response.ResponseProtocolVersion, args.ProxySession.Response.ResponseStatusCode,
args.ProxySession.Response.ResponseStatusDescription, args.ClientStreamWriter);
WriteResponseHeaders(args.ClientStreamWriter, args.ResponseHeaders, args.ResponseBody.Length,
args.ProxySession.Response.ResponseStatusDescription, args.Client.ClientStreamWriter);
WriteResponseHeaders(args.Client.ClientStreamWriter, args.ProxySession.Response.ResponseHeaders, args.ProxySession.Response.ResponseBody.Length,
isChunked);
WriteResponseBody(args.ClientStream, args.ResponseBody, isChunked);
WriteResponseBody(args.Client.ClientStream, args.ProxySession.Response.ResponseBody, isChunked);
}
else
{
var isChunked = args.ProxySession.Response.ResponseHeaders.Any(x => x.Name.ToLower() == "transfer-encoding" && x.Value.ToLower().Contains("chunked"));
WriteResponseStatus(args.ProxySession.Response.ResponseProtocolVersion, args.ProxySession.Response.ResponseStatusCode,
args.ProxySession.Response.ResponseStatusDescription, args.ClientStreamWriter);
WriteResponseHeaders(args.ClientStreamWriter, args.ResponseHeaders);
args.ProxySession.Response.ResponseStatusDescription, args.Client.ClientStreamWriter);
WriteResponseHeaders(args.Client.ClientStreamWriter, args.ProxySession.Response.ResponseHeaders);
if (isChunked || args.ProxySession.Response.ContentLength > 0)
WriteResponseBody(args.ResponseStream, args.ClientStream, isChunked, args.ProxySession.Response.ContentLength);
WriteResponseBody(args.ProxySession.ProxyClient.ServerStreamReader, args.Client.ClientStream, isChunked, args.ProxySession.Response.ContentLength);
}
args.ClientStream.Flush();
args.Client.ClientStream.Flush();
}
catch
{
Dispose(args.Client, args.ClientStream, args.ClientStreamReader, args.ClientStreamWriter, args);
Dispose(args.Client.TcpClient, args.Client.ClientStream, args.Client.ClientStreamReader, args.Client.ClientStreamWriter, args);
}
finally
{
......@@ -199,7 +199,7 @@ namespace Titanium.Web.Proxy
WriteResponseBodyChunked(data, clientStream);
}
private static void WriteResponseBody(Stream inStream, Stream outStream, bool isChunked, int BodyLength)
private static void WriteResponseBody(CustomBinaryReader inStreamReader, Stream outStream, bool isChunked, int BodyLength)
{
if (!isChunked)
{
......@@ -213,7 +213,7 @@ namespace Titanium.Web.Proxy
var bytesRead = 0;
var totalBytesRead = 0;
while ((bytesRead += inStream.Read(buffer, 0, bytesToRead)) > 0)
while ((bytesRead += inStreamReader.BaseStream.Read(buffer, 0, bytesToRead)) > 0)
{
outStream.Write(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
......@@ -227,13 +227,12 @@ namespace Titanium.Web.Proxy
}
}
else
WriteResponseBodyChunked(inStream, outStream);
WriteResponseBodyChunked(inStreamReader, outStream);
}
//Send chunked response
private static void WriteResponseBodyChunked(Stream inStream, Stream outStream)
private static void WriteResponseBodyChunked(CustomBinaryReader inStreamReader, Stream outStream)
{
var inStreamReader = new CustomBinaryReader(inStream, Encoding.ASCII);
while (true)
{
var chuchkHead = inStreamReader.ReadLine();
......
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