Commit d1e12c18 authored by titanium007's avatar titanium007

Fix web socket issues

parent c752bf0a
...@@ -60,22 +60,22 @@ namespace Titanium.Web.Proxy.Test ...@@ -60,22 +60,22 @@ namespace Titanium.Web.Proxy.Test
Console.WriteLine(e.RequestURL); Console.WriteLine(e.RequestURL);
if (e.RequestURL.Contains("somewebsite.com")) //if (e.RequestURL.Contains("somewebsite.com"))
if ((e.RequestMethod.ToUpper() == "POST" || e.RequestMethod.ToUpper() == "PUT") && e.RequestContentLength > 0) // if ((e.RequestMethod.ToUpper() == "POST" || e.RequestMethod.ToUpper() == "PUT") && e.RequestContentLength > 0)
{ // {
var m = e.GetRequestBody().Replace("a", "b"); // var m = e.GetRequestBody().Replace("a", "b");
e.SetRequestBody(m); // e.SetRequestBody(m);
} // }
//To cancel a request with a custom HTML content //To cancel a request with a custom HTML content
//Filter URL //Filter URL
if (e.RequestURL.Contains("somewebsite.com")) //if (e.RequestURL.Contains("somewebsite.com"))
{ //{
e.Ok("<!DOCTYPE html><html><body><h1>Blocked</h1><p>Website blocked.</p></body></html>"); // e.Ok("<!DOCTYPE html><html><body><h1>Blocked</h1><p>Website blocked.</p></body></html>");
} //}
} }
...@@ -85,22 +85,22 @@ namespace Titanium.Web.Proxy.Test ...@@ -85,22 +85,22 @@ namespace Titanium.Web.Proxy.Test
{ {
//To modify a response //To modify a response
if (e.RequestURL.Contains("somewebsite.com")) //if (e.RequestURL.Contains("somewebsite.com"))
if (e.ResponseStatusCode == HttpStatusCode.OK) //if (e.ResponseStatusCode == HttpStatusCode.OK)
{ //{
if (e.ResponseContentType.Trim().ToLower().Contains("text/html")) // if (e.ResponseContentType.Trim().ToLower().Contains("text/html"))
{ // {
//Get response body // //Get response body
string responseBody = e.GetResponseBody(); // string responseBody = e.GetResponseBody();
//Modify e.ServerResponse // //Modify e.ServerResponse
Regex rex = new Regex("</body>", RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.Multiline); // Regex rex = new Regex("</body>", RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.Multiline);
string modified = rex.Replace(responseBody, "<script type =\"text/javascript\">alert('Response was modified by this script!');</script></body>", 1); // string modified = rex.Replace(responseBody, "<script type =\"text/javascript\">alert('Response was modified by this script!');</script></body>", 1);
//Set modifed response Html Body // //Set modifed response Html Body
e.SetResponseBody(modified); // e.SetResponseBody(modified);
} // }
} //}
} }
......
...@@ -4,19 +4,20 @@ using System.Linq; ...@@ -4,19 +4,20 @@ using System.Linq;
using System.Text; using System.Text;
using System.IO; using System.IO;
namespace Titanium.Web.Proxy.Helpers namespace Titanium.Web.Proxy.Extensions
{ {
public static class StreamHelper public static class StreamHelper
{ {
private const int DEFAULT_BUFFER_SIZE = 8192; // +32767 private const int DEFAULT_BUFFER_SIZE = 8192; // +32767
public static void CopyTo(string initialData, Stream input, Stream output, int bufferSize) public static void CopyToAsync(this Stream input, string initialData, Stream output, int bufferSize)
{ {
var bytes = Encoding.ASCII.GetBytes(initialData); var bytes = Encoding.ASCII.GetBytes(initialData);
output.Write(bytes,0, bytes.Length); output.Write(bytes,0, bytes.Length);
CopyTo(input, output, bufferSize); CopyToAsync(input, output, bufferSize);
} }
public static void CopyTo(Stream input, Stream output, int bufferSize) //http://stackoverflow.com/questions/1540658/net-asynchronous-stream-read-write
public static void CopyToAsync(this Stream input, Stream output, int bufferSize)
{ {
try try
{ {
......
...@@ -7,16 +7,16 @@ using System.Diagnostics; ...@@ -7,16 +7,16 @@ using System.Diagnostics;
namespace Titanium.Web.Proxy.Helpers namespace Titanium.Web.Proxy.Helpers
{ {
public class CustomBinaryReader : BinaryReader internal class CustomBinaryReader : BinaryReader
{ {
public CustomBinaryReader(Stream stream, Encoding encoding) internal CustomBinaryReader(Stream stream, Encoding encoding)
: base(stream, encoding) : base(stream, encoding)
{ {
} }
public string ReadLine() internal string ReadLine()
{ {
char[] buf = new char[1]; char[] buf = new char[1];
StringBuilder readBuffer = new StringBuilder(); StringBuilder readBuffer = new StringBuilder();
...@@ -54,5 +54,16 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -54,5 +54,16 @@ namespace Titanium.Web.Proxy.Helpers
} }
internal List<string> ReadAllLines()
{
string tmpLine = null;
List<string> requestLines = new List<string>();
while (!String.IsNullOrEmpty(tmpLine = ReadLine()))
{
requestLines.Add(tmpLine);
}
return requestLines;
}
} }
} }
...@@ -7,6 +7,7 @@ using System.IO; ...@@ -7,6 +7,7 @@ using System.IO;
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Net.Sockets; using System.Net.Sockets;
using Titanium.Web.Proxy.Extensions;
namespace Titanium.Web.Proxy.Helpers namespace Titanium.Web.Proxy.Helpers
{ {
...@@ -14,85 +15,30 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -14,85 +15,30 @@ namespace Titanium.Web.Proxy.Helpers
{ {
private static readonly int BUFFER_SIZE = 8192; private static readonly int BUFFER_SIZE = 8192;
private static readonly String[] colonSpaceSplit = new string[] { ": " }; private static readonly String[] colonSpaceSplit = new string[] { ": " };
public static void SendRaw(string hostname, int tunnelPort, System.IO.Stream clientStream)
public static void SendRaw(Stream clientStream, string httpCmd, List<string> requestLines, string hostName, int tunnelPort, bool isHttps)
{ {
StringBuilder sb = new StringBuilder();
System.Net.Sockets.TcpClient tunnelClient = null; if (httpCmd != null)
NetworkStream tunnelStream = null;
try
{
tunnelClient = new System.Net.Sockets.TcpClient(hostname, tunnelPort);
tunnelStream = tunnelClient.GetStream();
var tunnelReadBuffer = new byte[BUFFER_SIZE];
Task sendRelay = Task.Factory.StartNew(() => StreamHelper.CopyTo(clientStream, tunnelStream, BUFFER_SIZE));
Task receiveRelay = Task.Factory.StartNew(() => StreamHelper.CopyTo(tunnelStream, clientStream, BUFFER_SIZE));
Task.WaitAll(sendRelay, receiveRelay);
}
catch
{ {
if (tunnelStream != null) sb.Append(httpCmd);
{ sb.Append(Environment.NewLine);
tunnelStream.Close();
tunnelStream.Dispose();
}
if (tunnelClient != null)
tunnelClient.Close();
throw;
} }
} for (int i = 0; i < requestLines.Count; i++)
public static void SendRaw(string httpCmd, string secureHostName, List<string> requestLines, bool isHttps, Stream clientStream)
{
StringBuilder sb = new StringBuilder();
sb.Append(httpCmd);
sb.Append(Environment.NewLine);
string hostname = secureHostName;
for (int i = 1; i < requestLines.Count; i++)
{ {
var header = requestLines[i]; var header = requestLines[i];
if (secureHostName == null)
{
String[] headerParsed = httpCmd.Split(colonSpaceSplit, 2, StringSplitOptions.None);
switch (headerParsed[0].ToLower())
{
case "host":
var hostdetail = headerParsed[1];
if (hostdetail.Contains(":"))
hostname = hostdetail.Split(':')[0].Trim();
else
hostname = hostdetail.Trim();
break;
default:
break;
}
}
sb.Append(header); sb.Append(header);
sb.Append(Environment.NewLine); sb.Append(Environment.NewLine);
} }
sb.Append(Environment.NewLine); sb.Append(Environment.NewLine);
int tunnelPort = 80;
if (isHttps)
{
tunnelPort = 443;
}
System.Net.Sockets.TcpClient tunnelClient = null; System.Net.Sockets.TcpClient tunnelClient = null;
Stream tunnelStream = null; Stream tunnelStream = null;
try try
{ {
tunnelClient = new System.Net.Sockets.TcpClient(hostname, tunnelPort); tunnelClient = new System.Net.Sockets.TcpClient(hostName, tunnelPort);
tunnelStream = tunnelClient.GetStream() as Stream; tunnelStream = tunnelClient.GetStream() as Stream;
if (isHttps) if (isHttps)
...@@ -101,7 +47,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -101,7 +47,7 @@ namespace Titanium.Web.Proxy.Helpers
try try
{ {
sslStream = new SslStream(tunnelStream); sslStream = new SslStream(tunnelStream);
sslStream.AuthenticateAsClient(hostname); sslStream.AuthenticateAsClient(hostName);
tunnelStream = sslStream; tunnelStream = sslStream;
} }
catch catch
...@@ -112,8 +58,8 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -112,8 +58,8 @@ namespace Titanium.Web.Proxy.Helpers
} }
var sendRelay = Task.Factory.StartNew(() => StreamHelper.CopyTo(sb.ToString(), clientStream, tunnelStream, BUFFER_SIZE)); var sendRelay = Task.Factory.StartNew(() => clientStream.CopyToAsync(sb.ToString(), tunnelStream, BUFFER_SIZE));
var receiveRelay = Task.Factory.StartNew(() => StreamHelper.CopyTo(tunnelStream, clientStream, BUFFER_SIZE)); var receiveRelay = Task.Factory.StartNew(() => tunnelStream.CopyToAsync(clientStream, BUFFER_SIZE));
Task.WaitAll(sendRelay, receiveRelay); Task.WaitAll(sendRelay, receiveRelay);
} }
...@@ -131,5 +77,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -131,5 +77,7 @@ namespace Titanium.Web.Proxy.Helpers
throw; throw;
} }
} }
} }
} }
\ No newline at end of file
...@@ -19,8 +19,7 @@ namespace Titanium.Web.Proxy.Models ...@@ -19,8 +19,7 @@ namespace Titanium.Web.Proxy.Models
internal CustomBinaryReader clientStreamReader { get; set; } internal CustomBinaryReader clientStreamReader { get; set; }
internal StreamWriter clientStreamWriter { get; set; } internal StreamWriter clientStreamWriter { get; set; }
internal string httpsHostName { get; set; }
internal string httpsDecoratedHostName { get; set; }
internal int requestContentLength { get; set; } internal int requestContentLength { get; set; }
internal Encoding requestEncoding { get; set; } internal Encoding requestEncoding { get; set; }
internal Version requestHttpVersion { get; set; } internal Version requestHttpVersion { get; set; }
......
...@@ -25,84 +25,48 @@ namespace Titanium.Web.Proxy ...@@ -25,84 +25,48 @@ namespace Titanium.Web.Proxy
private static void HandleClient(TcpClient client) private static void HandleClient(TcpClient client)
{ {
Stream clientStream = client.GetStream(); Stream clientStream = client.GetStream();
CustomBinaryReader clientStreamReader = new CustomBinaryReader(clientStream, Encoding.ASCII); CustomBinaryReader clientStreamReader = new CustomBinaryReader(clientStream, Encoding.ASCII);
StreamWriter clientStreamWriter = new StreamWriter(clientStream); StreamWriter clientStreamWriter = new StreamWriter(clientStream);
string HttpsHostName = null; Uri httpRemoteUri;
int httpsPort = 443;
try try
{ {
string httpsDecoratedHostName = null, tmpLine = null;
List<string> requestLines = new List<string>();
while (!String.IsNullOrEmpty(tmpLine = clientStreamReader.ReadLine()))
{
requestLines.Add(tmpLine);
}
//read the first line HTTP command //read the first line HTTP command
String httpCmd = requestLines.Count > 0 ? requestLines[0] : null; String httpCmd = clientStreamReader.ReadLine();
if (String.IsNullOrEmpty(httpCmd)) if (String.IsNullOrEmpty(httpCmd))
{ {
throw new EndOfStreamException(); throw new EndOfStreamException();
} }
//break up the line into three components (method, remote URL & Http Version) //break up the line into three components (method, remote URL & Http Version)
String[] splitBuffer = httpCmd.Split(spaceSplit, 3); String[] httpCmdSplit = httpCmd.Split(spaceSplit, 3);
String method = splitBuffer[0]; var httpVerb = httpCmdSplit[0];
String remoteUri = splitBuffer[1];
Version version; if (httpVerb.ToUpper() == "CONNECT")
string RequestVersion; httpRemoteUri = new Uri("http://" + httpCmdSplit[1]);
if (splitBuffer[2] == "HTTP/1.1")
{
version = new Version(1, 1);
RequestVersion = "HTTP/1.1";
}
else else
{ httpRemoteUri = new Uri(httpCmdSplit[1]);
version = new Version(1, 0);
RequestVersion = "HTTP/1.0";
}
var httpVersion = httpCmdSplit[2];
//Client wants to create a secure tcp tunnel (its a HTTPS request) //Client wants to create a secure tcp tunnel (its a HTTPS request)
if (splitBuffer[0].ToUpper() == "CONNECT") var excluded = ExcludedHttpsHostNameRegex.Any(x => Regex.IsMatch(httpRemoteUri.Host, x));
if (httpVerb.ToUpper() == "CONNECT" && !excluded && httpRemoteUri.Port == 443)
{ {
//Browser wants to create a secure tunnel
//instead = we are going to perform a man in the middle "attack"
//the user's browser should warn them of the certification errors,
//to avoid that we need to install our root certficate in users machine as Certificate Authority.
remoteUri = "https://" + splitBuffer[1]; httpRemoteUri = new Uri("https://" + httpCmdSplit[1]);
HttpsHostName = splitBuffer[1].Split(':')[0]; clientStreamReader.ReadAllLines();
int.TryParse(splitBuffer[1].Split(':')[1], out httpsPort); WriteConnectedResponse(clientStreamWriter, httpVersion);
requestLines.Clear();
clientStreamWriter.WriteLine(RequestVersion + " 200 Connection established");
clientStreamWriter.WriteLine(String.Format("Timestamp: {0}", DateTime.Now.ToString()));
clientStreamWriter.WriteLine(String.Format("connection:close"));
clientStreamWriter.WriteLine();
clientStreamWriter.Flush();
//If port is not 443 its not a HTTP request (may be tcp), so just relay
if (httpsPort != 443)
{
TcpHelper.SendRaw(HttpsHostName, httpsPort, clientStreamReader.BaseStream);
Dispose(client, clientStream, clientStreamReader, clientStreamWriter, null);
return;
}
//Create the fake certificate signed using our fake certificate authority //Create the fake certificate signed using our fake certificate authority
Monitor.Enter(certificateAccessLock); Monitor.Enter(certificateAccessLock);
var certificate = ProxyServer.CertManager.CreateCertificate(HttpsHostName); var certificate = ProxyServer.CertManager.CreateCertificate(httpRemoteUri.Host);
Monitor.Exit(certificateAccessLock); Monitor.Exit(certificateAccessLock);
SslStream sslStream = null; SslStream sslStream = null;
...@@ -110,54 +74,44 @@ namespace Titanium.Web.Proxy ...@@ -110,54 +74,44 @@ namespace Titanium.Web.Proxy
//Pinned certificate clients cannot be proxied //Pinned certificate clients cannot be proxied
//For example dropbox clients use certificate pinning //For example dropbox clients use certificate pinning
//So just relay the request //So just relay the request
if (!ExcludedHttpsHostNameRegex.Any(x => Regex.IsMatch(HttpsHostName, x)))
{
try
{
sslStream = new SslStream(clientStream, true);
//Successfully managed to authenticate the client using the fake certificate
sslStream.AuthenticateAsServer(certificate, false, SslProtocols.Tls | SslProtocols.Ssl3 | SslProtocols.Ssl2, false);
clientStreamReader = new CustomBinaryReader(sslStream, Encoding.ASCII);
clientStreamWriter = new StreamWriter(sslStream);
//HTTPS server created - we can now decrypt the client's traffic
clientStream = sslStream;
}
catch
{
if (sslStream != null)
sslStream.Dispose();
throw; try
}
}
else
{ {
//Hostname was a previously failed request due to certificate pinning, just relay (tunnel the request) sslStream = new SslStream(clientStream, true);
TcpHelper.SendRaw(HttpsHostName, httpsPort, clientStreamReader.BaseStream); //Successfully managed to authenticate the client using the fake certificate
Dispose(client, clientStream, clientStreamReader, clientStreamWriter, null); sslStream.AuthenticateAsServer(certificate, false, SslProtocols.Tls | SslProtocols.Ssl3 | SslProtocols.Ssl2, false);
return;
clientStreamReader = new CustomBinaryReader(sslStream, Encoding.ASCII);
clientStreamWriter = new StreamWriter(sslStream);
//HTTPS server created - we can now decrypt the client's traffic
clientStream = sslStream;
} }
while (!String.IsNullOrEmpty(tmpLine = clientStreamReader.ReadLine())) catch
{ {
requestLines.Add(tmpLine); if (sslStream != null)
} sslStream.Dispose();
//read the new http command. throw;
httpCmd = requestLines.Count > 0 ? requestLines[0] : null;
if (String.IsNullOrEmpty(httpCmd))
{
throw new EndOfStreamException();
} }
httpsDecoratedHostName = remoteUri;
httpCmd = clientStreamReader.ReadLine();
}
else if (httpVerb.ToUpper() == "CONNECT")
{
clientStreamReader.ReadAllLines();
WriteConnectedResponse(clientStreamWriter, httpVersion);
TcpHelper.SendRaw(clientStreamReader.BaseStream, null, new List<string>(), httpRemoteUri.Host, httpRemoteUri.Port, false);
Dispose(client, clientStream, clientStreamReader, clientStreamWriter, null);
return;
} }
//Now create the request //Now create the request
Task.Factory.StartNew(() => HandleHttpSessionRequest(client, httpCmd, clientStream, HttpsHostName, requestLines, clientStreamReader, clientStreamWriter, httpsDecoratedHostName)); Task.Factory.StartNew(() => HandleHttpSessionRequest(client, httpCmd, clientStream, clientStreamReader, clientStreamWriter, httpRemoteUri.Scheme == Uri.UriSchemeHttps ? httpRemoteUri.OriginalString : null));
} }
catch catch
...@@ -167,40 +121,45 @@ namespace Titanium.Web.Proxy ...@@ -167,40 +121,45 @@ namespace Titanium.Web.Proxy
} }
private static void HandleHttpSessionRequest(TcpClient client, string httpCmd, Stream clientStream, string httpsHostName, List<string> requestLines, CustomBinaryReader clientStreamReader, StreamWriter clientStreamWriter, string httpsDecoratedHostName)
{
private static void WriteConnectedResponse(StreamWriter clientStreamWriter, string httpVersion)
{
clientStreamWriter.WriteLine(httpVersion + " 200 Connection established");
clientStreamWriter.WriteLine(String.Format("Timestamp: {0}", DateTime.Now.ToString()));
clientStreamWriter.WriteLine(String.Format("connection:close"));
clientStreamWriter.WriteLine();
clientStreamWriter.Flush();
}
private static void HandleHttpSessionRequest(TcpClient client, string httpCmd, Stream clientStream, CustomBinaryReader clientStreamReader, StreamWriter clientStreamWriter, string secureTunnelHostName)
{
if (httpCmd == null) if (String.IsNullOrEmpty(httpCmd))
{ {
Dispose(client, clientStream, clientStreamReader, clientStreamWriter, null); Dispose(client, clientStream, clientStreamReader, clientStreamWriter, null);
return; return;
} }
string tmpLine = null;
List<string> requestLines = new List<string>();
while (!String.IsNullOrEmpty(tmpLine = clientStreamReader.ReadLine()))
{
requestLines.Add(tmpLine);
}
var args = new SessionEventArgs(BUFFER_SIZE); var args = new SessionEventArgs(BUFFER_SIZE);
args.client = client; args.client = client;
args.httpsHostName = httpsHostName;
args.httpsDecoratedHostName = httpsDecoratedHostName;
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)
var splitBuffer = httpCmd.Split(spaceSplit, 3); String[] httpCmdSplit = httpCmd.Split(spaceSplit, 3);
if (splitBuffer.Length != 3) var httpMethod = httpCmdSplit[0];
{ var httpRemoteUri = new Uri(secureTunnelHostName == null ? httpCmdSplit[1] : (secureTunnelHostName + httpCmdSplit[1]));
TcpHelper.SendRaw(httpCmd, httpsHostName, requestLines, args.isHttps, clientStreamReader.BaseStream); var httpVersion = httpCmdSplit[2];
Dispose(client, clientStream, clientStreamReader, clientStreamWriter, args);
return;
}
var method = splitBuffer[0];
var remoteUri = splitBuffer[1];
Version version; Version version;
if (splitBuffer[2] == "HTTP/1.1") if (httpVersion == "HTTP/1.1")
{ {
version = new Version(1, 1); version = new Version(1, 1);
} }
...@@ -209,23 +168,22 @@ namespace Titanium.Web.Proxy ...@@ -209,23 +168,22 @@ namespace Titanium.Web.Proxy
version = new Version(1, 0); version = new Version(1, 0);
} }
if (httpsDecoratedHostName != null) if (httpRemoteUri.Scheme == Uri.UriSchemeHttps)
{ {
remoteUri = httpsDecoratedHostName + remoteUri;
args.isHttps = true; args.isHttps = true;
} }
//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.
args.proxyRequest = (HttpWebRequest)HttpWebRequest.Create(remoteUri.Trim()); args.proxyRequest = (HttpWebRequest)HttpWebRequest.Create(httpRemoteUri);
args.proxyRequest.Proxy = null; args.proxyRequest.Proxy = null;
args.proxyRequest.UseDefaultCredentials = true; args.proxyRequest.UseDefaultCredentials = true;
args.proxyRequest.Method = method; args.proxyRequest.Method = httpMethod;
args.proxyRequest.ProtocolVersion = version; args.proxyRequest.ProtocolVersion = version;
args.clientStream = clientStream; args.clientStream = clientStream;
args.clientStreamReader = clientStreamReader; args.clientStreamReader = clientStreamReader;
args.clientStreamWriter = clientStreamWriter; args.clientStreamWriter = clientStreamWriter;
for (int i = 1; i < requestLines.Count; i++) for (int i = 0; i < requestLines.Count; i++)
{ {
var rawHeader = requestLines[i]; var rawHeader = requestLines[i];
String[] header = rawHeader.ToLower().Trim().Split(colonSpaceSplit, 2, StringSplitOptions.None); String[] header = rawHeader.ToLower().Trim().Split(colonSpaceSplit, 2, StringSplitOptions.None);
...@@ -233,11 +191,9 @@ namespace Titanium.Web.Proxy ...@@ -233,11 +191,9 @@ namespace Titanium.Web.Proxy
//if request was upgrade to web-socket protocol then relay the request without proxying //if request was upgrade to web-socket protocol then relay the request without proxying
if ((header[0] == "upgrade") && (header[1] == "websocket")) if ((header[0] == "upgrade") && (header[1] == "websocket"))
{ {
TcpHelper.SendRaw(httpCmd, httpsHostName, requestLines, args.isHttps, clientStreamReader.BaseStream);
TcpHelper.SendRaw(clientStreamReader.BaseStream, httpCmd, requestLines, httpRemoteUri.Host, httpRemoteUri.Port, httpRemoteUri.Scheme == Uri.UriSchemeHttps);
Dispose(client, clientStream, clientStreamReader, clientStreamWriter, args); Dispose(client, clientStream, clientStreamReader, clientStreamWriter, args);
return; return;
} }
} }
...@@ -262,11 +218,10 @@ namespace Titanium.Web.Proxy ...@@ -262,11 +218,10 @@ namespace Titanium.Web.Proxy
BeforeRequest(null, args); BeforeRequest(null, args);
} }
string tmpLine;
if (args.cancelRequest) if (args.cancelRequest)
{ {
Dispose(client, clientStream, clientStreamReader, clientStreamWriter, args); Dispose(client, clientStream, clientStreamReader, clientStreamWriter, args);
return; return;
} }
...@@ -287,12 +242,11 @@ namespace Titanium.Web.Proxy ...@@ -287,12 +242,11 @@ namespace Titanium.Web.Proxy
else else
{ {
//If its a post/put request, then read the client html body and send it to server //If its a post/put request, then read the client html body and send it to server
if (method.ToUpper() == "POST" || method.ToUpper() == "PUT") if (httpMethod.ToUpper() == "POST" || httpMethod.ToUpper() == "PUT")
{ {
SendClientRequestBody(args); SendClientRequestBody(args);
} }
//Http request body sent, now wait asynchronously for response //Http request body sent, now wait asynchronously for response
args.proxyRequest.BeginGetResponse(new AsyncCallback(HandleHttpSessionResponse), args); args.proxyRequest.BeginGetResponse(new AsyncCallback(HandleHttpSessionResponse), args);
...@@ -300,18 +254,9 @@ namespace Titanium.Web.Proxy ...@@ -300,18 +254,9 @@ namespace Titanium.Web.Proxy
//Now read the next request (if keep-Alive is enabled, otherwise exit this thread) //Now read the next request (if keep-Alive is enabled, otherwise exit this thread)
//If client is pipeling the request, this will be immediately hit before response for previous request was made //If client is pipeling the request, this will be immediately hit before response for previous request was made
httpCmd = clientStreamReader.ReadLine();
tmpLine = null;
requestLines.Clear();
while (!String.IsNullOrEmpty(tmpLine = args.clientStreamReader.ReadLine()))
{
requestLines.Add(tmpLine);
}
httpCmd = requestLines.Count() > 0 ? requestLines[0] : null;
TcpClient Client = args.client;
//Http request body sent, now wait for next request //Http request body sent, now wait for next request
Task.Factory.StartNew(() => HandleHttpSessionRequest(Client, httpCmd, args.clientStream, args.httpsHostName, requestLines, args.clientStreamReader, args.clientStreamWriter, args.httpsDecoratedHostName)); Task.Factory.StartNew(() => HandleHttpSessionRequest(args.client, httpCmd, args.clientStream, args.clientStreamReader, args.clientStreamWriter, secureTunnelHostName));
} }
catch catch
...@@ -564,5 +509,9 @@ namespace Titanium.Web.Proxy ...@@ -564,5 +509,9 @@ namespace Titanium.Web.Proxy
} }
public static bool isHttps { get; set; }
} }
} }
\ No newline at end of file
...@@ -90,7 +90,7 @@ ...@@ -90,7 +90,7 @@
<Compile Include="ProxyServer.cs" /> <Compile Include="ProxyServer.cs" />
<Compile Include="Models\SessionEventArgs.cs" /> <Compile Include="Models\SessionEventArgs.cs" />
<Compile Include="Helpers\Tcp.cs" /> <Compile Include="Helpers\Tcp.cs" />
<Compile Include="Helpers\Stream.cs" /> <Compile Include="Extensions\StreamExtensions.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup />
<ItemGroup> <ItemGroup>
......
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