Commit ffe306c2 authored by titanium007's avatar titanium007

Separate request & response

parent f69bed23
...@@ -43,7 +43,7 @@ namespace Titanium.Web.Proxy.Test ...@@ -43,7 +43,7 @@ namespace Titanium.Web.Proxy.Test
//Read browser URL send back to proxy by the injection script in OnResponse event //Read browser URL send back to proxy by the injection script in OnResponse event
public void OnRequest(object sender, SessionEventArgs e) public void OnRequest(object sender, SessionEventArgs e)
{ {
Console.WriteLine(e.RequestUrl); Console.WriteLine(e.ProxySession.Request.RequestUrl);
////read request headers ////read request headers
//var requestHeaders = e.RequestHeaders; //var requestHeaders = e.RequestHeaders;
......
...@@ -15,25 +15,29 @@ namespace Titanium.Web.Proxy.Http ...@@ -15,25 +15,29 @@ namespace Titanium.Web.Proxy.Http
public class Request public class Request
{ {
public string Method { get; set; } public string Method { get; set; }
public Uri RequestUri { get; set; } public Uri RequestUri { get; set; }
public string Version { get; set; } public string Version { get; set; }
public List<HttpHeader> RequestHeaders { get; set; }
public string RequestStatus { get; set; } public string RequestStatus { get; set; }
public int RequestContentLength { get; set; } public int RequestContentLength { get; set; }
public bool RequestSendChunked { get; set; } public bool RequestSendChunked { get; set; }
public string RequestContentType { get; set; } public string RequestContentType { get; set; }
public bool RequestKeepAlive { get; set; } public bool RequestKeepAlive { get; set; }
public string RequestHost { 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() public Request()
{ {
this.RequestHeaders = new List<HttpHeader>(); this.RequestHeaders = new List<HttpHeader>();
...@@ -43,28 +47,28 @@ namespace Titanium.Web.Proxy.Http ...@@ -43,28 +47,28 @@ namespace Titanium.Web.Proxy.Http
public class Response 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 ResponseCharacterSet { get; set; }
public string ResponseContentEncoding { get; set; } public string ResponseContentEncoding { get; set; }
public System.Version ResponseProtocolVersion { get; set; } public System.Version ResponseProtocolVersion { get; set; }
public string ResponseStatusCode { get; set; } public string ResponseStatusCode { get; set; }
public string ResponseStatusDescription { get; set; } public string ResponseStatusDescription { get; set; }
public bool ResponseKeepAlive { get; set; } public bool ResponseKeepAlive { get; set; }
public string ResponseContentType { get; set; } public string ResponseContentType { get; set; }
public int ContentLength { get; set; }
public Response() public Response()
{ {
this.ResponseHeaders = new List<HttpHeader>(); this.ResponseHeaders = new List<HttpHeader>();
} }
public int ContentLength { get; set; }
} }
public class HttpWebSession public class HttpWebSession
...@@ -81,12 +85,11 @@ namespace Titanium.Web.Proxy.Http ...@@ -81,12 +85,11 @@ namespace Titanium.Web.Proxy.Http
public Request Request { get; set; } public Request Request { get; set; }
public Response Response { get; set; } public Response Response { get; set; }
public TcpConnection Client { get; set; } public TcpConnection ProxyClient { get; set; }
public void SetConnection(TcpConnection Connection) public void SetConnection(TcpConnection Connection)
{ {
Client = Connection; ProxyClient = Connection;
ServerStreamReader = Client.ServerStreamReader;
} }
public HttpWebSession() public HttpWebSession()
...@@ -97,11 +100,11 @@ namespace Titanium.Web.Proxy.Http ...@@ -97,11 +100,11 @@ namespace Titanium.Web.Proxy.Http
} }
public CustomBinaryReader ServerStreamReader { get; set; }
public async Task SendRequest()
public void SendRequest()
{ {
Stream stream = Client.Stream; Stream stream = ProxyClient.Stream;
StringBuilder requestLines = new StringBuilder(); StringBuilder requestLines = new StringBuilder();
...@@ -122,13 +125,13 @@ namespace Titanium.Web.Proxy.Http ...@@ -122,13 +125,13 @@ namespace Titanium.Web.Proxy.Http
string request = requestLines.ToString(); string request = requestLines.ToString();
byte[] requestBytes = Encoding.ASCII.GetBytes(request); byte[] requestBytes = Encoding.ASCII.GetBytes(request);
await AsyncExtensions.WriteAsync((Stream)stream, requestBytes, 0, requestBytes.Length); stream.Write(requestBytes, 0, requestBytes.Length);
await AsyncExtensions.FlushAsync((Stream)stream); stream.Flush();
} }
public void ReceiveResponse() public void ReceiveResponse()
{ {
var httpResult = ServerStreamReader.ReadLine().Split(new char[] { ' ' }, 3); var httpResult = ProxyClient.ServerStreamReader.ReadLine().Split(new char[] { ' ' }, 3);
var httpVersion = httpResult[0]; var httpVersion = httpResult[0];
...@@ -148,7 +151,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -148,7 +151,7 @@ namespace Titanium.Web.Proxy.Http
this.Response.ResponseStatusDescription = status; this.Response.ResponseStatusDescription = status;
List<string> responseLines = ServerStreamReader.ReadAllLines(); List<string> responseLines = ProxyClient.ServerStreamReader.ReadAllLines();
for (int index = 0; index < responseLines.Count; ++index) for (int index = 0; index < responseLines.Count; ++index)
{ {
......
...@@ -22,25 +22,28 @@ namespace Titanium.Web.Proxy.Http ...@@ -22,25 +22,28 @@ namespace Titanium.Web.Proxy.Http
{ {
static ConcurrentDictionary<string, ConcurrentStack<TcpConnection>> ConnectionCache = new ConcurrentDictionary<string, ConcurrentStack<TcpConnection>>(); 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); var key = string.Concat(Hostname, ":", port, ":", IsSecure);
TcpConnection client;
lock (ConnectionCache)
{
ConcurrentStack<TcpConnection> connections; ConcurrentStack<TcpConnection> connections;
if (!ConnectionCache.TryGetValue(key, out connections)) if (!ConnectionCache.TryGetValue(key, out connections))
{ {
return await CreateClient(Hostname, port, IsSecure); return CreateClient(Hostname, port, IsSecure);
} }
TcpConnection client;
if (!connections.TryPop(out client)) if (!connections.TryPop(out client))
{ {
return await CreateClient(Hostname, port, IsSecure); return CreateClient(Hostname, port, IsSecure);
}
} }
return client; 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 client = new TcpClient(Hostname, port);
var stream = (Stream)client.GetStream(); var stream = (Stream)client.GetStream();
...@@ -51,7 +54,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -51,7 +54,7 @@ namespace Titanium.Web.Proxy.Http
try try
{ {
sslStream = new SslStream(stream); sslStream = new SslStream(stream);
await AsyncPlatformExtensions.AuthenticateAsClientAsync(sslStream, Hostname); sslStream.AuthenticateAsClient(Hostname);
stream = (Stream)sslStream; stream = (Stream)sslStream;
} }
catch catch
...@@ -68,6 +71,8 @@ namespace Titanium.Web.Proxy.Http ...@@ -68,6 +71,8 @@ namespace Titanium.Web.Proxy.Http
public static void AddClient(string Hostname, int port, bool IsSecure, TcpConnection Client) public static void AddClient(string Hostname, int port, bool IsSecure, TcpConnection Client)
{ {
var key = string.Concat(Hostname, ":", port, ":", IsSecure); var key = string.Concat(Hostname, ":", port, ":", IsSecure);
lock (ConnectionCache)
{
ConcurrentStack<TcpConnection> connections; ConcurrentStack<TcpConnection> connections;
if (!ConnectionCache.TryGetValue(key, out connections)) if (!ConnectionCache.TryGetValue(key, out connections))
...@@ -78,6 +83,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -78,6 +83,7 @@ namespace Titanium.Web.Proxy.Http
} }
connections.Push(Client); connections.Push(Client);
}
} }
......
This diff is collapsed.
...@@ -26,19 +26,19 @@ namespace Titanium.Web.Proxy ...@@ -26,19 +26,19 @@ namespace Titanium.Web.Proxy
try try
{ {
args.ResponseHeaders = ReadResponseHeaders(args.ProxySession); args.ProxySession.Response.ResponseHeaders = ReadResponseHeaders(args.ProxySession);
args.ResponseStream = args.ProxySession.ServerStreamReader.BaseStream; args.ProxySession.Response.ResponseStream = args.ProxySession.ProxyClient.ServerStreamReader.BaseStream;
if (BeforeResponse != null) if (BeforeResponse != null)
{ {
args.ResponseEncoding = args.ProxySession.GetResponseEncoding(); args.ProxySession.Response.ResponseEncoding = args.ProxySession.GetResponseEncoding();
BeforeResponse(null, args); 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 isChunked = args.ProxySession.Response.ResponseHeaders.Any(x => x.Name.ToLower() == "transfer-encoding" && x.Value.ToLower().Contains("chunked"));
var contentEncoding = args.ProxySession.Response.ResponseContentEncoding; var contentEncoding = args.ProxySession.Response.ResponseContentEncoding;
...@@ -46,40 +46,40 @@ namespace Titanium.Web.Proxy ...@@ -46,40 +46,40 @@ namespace Titanium.Web.Proxy
switch (contentEncoding.ToLower()) switch (contentEncoding.ToLower())
{ {
case "gzip": case "gzip":
args.ResponseBody = CompressionHelper.CompressGzip(args.ResponseBody); args.ProxySession.Response.ResponseBody = CompressionHelper.CompressGzip(args.ProxySession.Response.ResponseBody);
break; break;
case "deflate": case "deflate":
args.ResponseBody = CompressionHelper.CompressDeflate(args.ResponseBody); args.ProxySession.Response.ResponseBody = CompressionHelper.CompressDeflate(args.ProxySession.Response.ResponseBody);
break; break;
case "zlib": case "zlib":
args.ResponseBody = CompressionHelper.CompressZlib(args.ResponseBody); args.ProxySession.Response.ResponseBody = CompressionHelper.CompressZlib(args.ProxySession.Response.ResponseBody);
break; break;
} }
WriteResponseStatus(args.ProxySession.Response.ResponseProtocolVersion, args.ProxySession.Response.ResponseStatusCode, WriteResponseStatus(args.ProxySession.Response.ResponseProtocolVersion, args.ProxySession.Response.ResponseStatusCode,
args.ProxySession.Response.ResponseStatusDescription, args.ClientStreamWriter); args.ProxySession.Response.ResponseStatusDescription, args.Client.ClientStreamWriter);
WriteResponseHeaders(args.ClientStreamWriter, args.ResponseHeaders, args.ResponseBody.Length, WriteResponseHeaders(args.Client.ClientStreamWriter, args.ProxySession.Response.ResponseHeaders, args.ProxySession.Response.ResponseBody.Length,
isChunked); isChunked);
WriteResponseBody(args.ClientStream, args.ResponseBody, isChunked); WriteResponseBody(args.Client.ClientStream, args.ProxySession.Response.ResponseBody, isChunked);
} }
else else
{ {
var isChunked = args.ProxySession.Response.ResponseHeaders.Any(x => x.Name.ToLower() == "transfer-encoding" && x.Value.ToLower().Contains("chunked")); 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, WriteResponseStatus(args.ProxySession.Response.ResponseProtocolVersion, args.ProxySession.Response.ResponseStatusCode,
args.ProxySession.Response.ResponseStatusDescription, args.ClientStreamWriter); args.ProxySession.Response.ResponseStatusDescription, args.Client.ClientStreamWriter);
WriteResponseHeaders(args.ClientStreamWriter, args.ResponseHeaders); WriteResponseHeaders(args.Client.ClientStreamWriter, args.ProxySession.Response.ResponseHeaders);
if (isChunked || args.ProxySession.Response.ContentLength > 0) 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 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 finally
{ {
...@@ -199,7 +199,7 @@ namespace Titanium.Web.Proxy ...@@ -199,7 +199,7 @@ namespace Titanium.Web.Proxy
WriteResponseBodyChunked(data, clientStream); 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) if (!isChunked)
{ {
...@@ -213,7 +213,7 @@ namespace Titanium.Web.Proxy ...@@ -213,7 +213,7 @@ namespace Titanium.Web.Proxy
var bytesRead = 0; var bytesRead = 0;
var totalBytesRead = 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); outStream.Write(buffer, 0, bytesRead);
totalBytesRead += bytesRead; totalBytesRead += bytesRead;
...@@ -227,13 +227,12 @@ namespace Titanium.Web.Proxy ...@@ -227,13 +227,12 @@ namespace Titanium.Web.Proxy
} }
} }
else else
WriteResponseBodyChunked(inStream, outStream); WriteResponseBodyChunked(inStreamReader, outStream);
} }
//Send chunked response //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) while (true)
{ {
var chuchkHead = inStreamReader.ReadLine(); 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