Permalink
Browse files

Support tunneling HTTP Proxy(using CONNECT method)

  • Loading branch information...
walkure committed Sep 17, 2015
1 parent b07a9ef commit 66ee0daf1a963c0fe591a7dad97d94cfd689bc1f
@@ -106,7 +106,9 @@ class Handler
private byte[] connetionRecvBuffer = new byte[RecvSize];
// connection send buffer
private byte[] connetionSendBuffer = new byte[BufferSize];
// Received data string.
// Received HTTP proxy message string.
byte[] bytesHTTPReceived = new byte[1024];
StringBuilder sbHTTPReceived = new StringBuilder();
private bool connectionShutdown = false;
private bool remoteShutdown = false;
@@ -379,14 +381,15 @@ private void StartConnect()
CreateRemote();
// TODO async resolving
IPAddress ipAddress;
bool parsed = IPAddress.TryParse(server.server, out ipAddress);
IPAddress ipAddress = null;
string serverHost = server.proxy == "" ? server.server : server.proxy;
bool parsed = IPAddress.TryParse(serverHost, out ipAddress);
if (!parsed)
{
IPHostEntry ipHostInfo = Dns.GetHostEntry(server.server);
IPHostEntry ipHostInfo = Dns.GetHostEntry(serverHost);
ipAddress = ipHostInfo.AddressList[0];
}
IPEndPoint remoteEP = new IPEndPoint(ipAddress, server.server_port);
IPEndPoint remoteEP = new IPEndPoint(ipAddress, server.proxy == "" ? server.server_port : server.proxy_port);
remote = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
@@ -472,7 +475,10 @@ private void ConnectCallback(IAsyncResult ar)
strategy.UpdateLatency(server, latency);
}
if (server.proxy == "")
StartPipe();
else
StartProxyConnection();
}
catch (ArgumentException)
{
@@ -492,6 +498,70 @@ private void ConnectCallback(IAsyncResult ar)
}
}
private void StartProxyConnection()
{
Logging.Debug(string.Format("Starting HTTP CONNECT to {0}:{1}", server.server, server.server_port));
byte[] data = Encoding.ASCII.GetBytes(string.Format("CONNECT {0}:{1} HTTP/1.0 \r\n\r\n", server.server, server.server_port));
remote.BeginSend(data,0,data.Length, SocketFlags.None, HTTPConnectSendCallback, null);
}
private void HTTPConnectSendCallback(IAsyncResult ar)
{
if (closed)
{
return;
}
try
{
remote.EndSend(ar);
sbHTTPReceived.Clear();
remote.BeginReceive(bytesHTTPReceived, 0, bytesHTTPReceived.Length, SocketFlags.None, HTTPResponseCallback, null);
}
catch (Exception e)
{
Logging.LogUsefulException(e);
this.Close();
}
}
private void HTTPResponseCallback(IAsyncResult ar)
{
if (closed)
{
return;
}
try
{
int received = remote.EndReceive(ar);
sbHTTPReceived.Append(Encoding.ASCII.GetString(bytesHTTPReceived, 0, received));
string strResponse = sbHTTPReceived.ToString();
if (strResponse.IndexOf("\r\n\r\n") > 0)
{
if(strResponse.Length < 12)
{
throw new Exception("Proxy Reponse missing:" + strResponse);
}
//TODO check proxy response code.
string strRespCode = strResponse.Substring(9, 3);
Logging.Debug("Successfully create https tunnel");
StartPipe();
}
else
{
remote.BeginReceive(bytesHTTPReceived, 0, bytesHTTPReceived.Length, SocketFlags.None, HTTPResponseCallback, null);
}
}
catch (Exception e)
{
Logging.LogUsefulException(e);
this.Close();
}
}
private void StartPipe()
{
if (closed)
@@ -17,6 +17,8 @@ public class Server
public string password;
public string method;
public string remarks;
public string proxy;
public int proxy_port;
public override int GetHashCode()
{
@@ -52,6 +54,8 @@ public Server()
this.method = "aes-256-cfb";
this.password = "";
this.remarks = "";
this.proxy = "";
this.proxy_port = 8080;
}
public Server(string ssURL) : this()
Oops, something went wrong.

0 comments on commit 66ee0da

Please sign in to comment.