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;
......
......@@ -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,12 +85,11 @@ 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()
......@@ -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();
......@@ -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);
TcpConnection client;
lock (ConnectionCache)
{
ConcurrentStack<TcpConnection> 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))
{
return await CreateClient(Hostname, port, IsSecure);
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,6 +71,8 @@ namespace Titanium.Web.Proxy.Http
public static void AddClient(string Hostname, int port, bool IsSecure, TcpConnection Client)
{
var key = string.Concat(Hostname, ":", port, ":", IsSecure);
lock (ConnectionCache)
{
ConcurrentStack<TcpConnection> connections;
if (!ConnectionCache.TryGetValue(key, out connections))
......@@ -78,6 +83,7 @@ namespace Titanium.Web.Proxy.Http
}
connections.Push(Client);
}
}
......
This diff is collapsed.
......@@ -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