Sat*_*ert 2 .net c# https proxy
我正在尝试使用 C# 实现 HTTPS 代理。代理应仅支持 HTTPS,而不支持 HTTP。据我所知,HTTPListener 不是一个好的选择,因为您需要 SSL 证书才能支持 HTTPS,而代理通常不提供该证书。
\n\n我正在使用 TcpListener 和 TcpClients。这是我到目前为止得到的代码:
\n\n protected void HandleTCPRequest(object clientObject)\n {\n TcpClient inClient = clientObject as TcpClient;\n TcpClient outClient = null;\n\n try\n {\n NetworkStream clientStream = inClient.GetStream();\n StreamReader clientReader = new StreamReader(clientStream);\n StreamWriter clientWriter = new StreamWriter(clientStream);\n\n // Read initial request.\n List<String> connectRequest = new List<string>();\n string line;\n while (!String.IsNullOrEmpty(line = clientReader.ReadLine()))\n {\n connectRequest.Add(line);\n }\n if (connectRequest.Count == 0)\n {\n return;\n }\n\n string[] requestLine0Split = connectRequest[0].Split(\' \');\n if (requestLine0Split.Length < 3)\n {\n return;\n }\n // Check if it is CONNECT\n string method = requestLine0Split[0];\n if (!method.Equals("CONNECT"))\n {\n return;\n }\n // Get host and port\n string requestUri = requestLine0Split[1];\n string[] uriSplit = requestUri.Split(new char[] { \':\' }, StringSplitOptions.RemoveEmptyEntries);\n if (uriSplit.Length < 2)\n {\n return;\n }\n string host = uriSplit[0];\n int port = Int32.Parse(uriSplit[1]);\n\n // Connect to server\n outClient = new TcpClient(host, port);\n NetworkStream serverStream = outClient.GetStream();\n StreamWriter serverWriter = new StreamWriter(serverStream);\n StreamReader serverReader = new StreamReader(serverStream);\n\n // Send 200 Connection Established to Client\n clientWriter.WriteLine("HTTP/1.0 200 Connection established\\r\\n\\r\\n");\n clientWriter.Flush();\n\n Logger.Debug("Established TCP connection for " + host);\n\n while (true)\n {\n line = clientReader.ReadLine();\n if (line != null)\n {\n Logger.Debug("->Server: " + line);\n serverWriter.WriteLine(line);\n }\n line = serverReader.ReadLine();\n if (line != null)\n {\n Logger.Debug("->Client: " + line);\n clientWriter.WriteLine(line);\n }\n }\n }\n catch(Exception)\n {\n // Disconnent if connections still alive\n try\n {\n if (inClient.Connected)\n {\n inClient.Close();\n }\n if (outClient != null && outClient.Connected)\n {\n outClient.Close();\n }\n }\n catch (Exception e)\n {\n Logger.Warn("Could not close the tcp connection: ", e);\n }\n }\n }\nRun Code Online (Sandbox Code Playgroud)\n\n传入的连接以另一种方法接受。
\n\n编辑:我做了一些更改。现在,客户端开始发送 SSL 数据,但服务器从未响应。一段时间后,客户端打开一个新连接并重试。我得到的输出:
\n\nEstablished TCP connection for www.google.de\n->Server: \xe2\x96\xac\xe2\x99\xa5\xe2\x98\xba ?\xe2\x98\xba ?\xe2\x99\xa5\xe2\x98\xbaR\'"??????#\xe2\x98\xbc}~??\xe2\x99\xa3|]?\n->Server: ??_5OL(?? H ??\n->Server: ?\xc2\xb6 ? ? 9 8?\xe2\x98\xbc?\xe2\x99\xa3 ? 5?? ?\xe2\x97\x84?\xe2\x80\xbc E D 3 2?\xe2\x99\x80?\xe2\x99\xab?\xe2\x98\xbb?\xe2\x99\xa6 ? A \xe2\x99\xa3 \xe2\x99\xa6 /?\xe2\x86\x95 \xe2\x96\xac \xe2\x80\xbc?\n->Server: ?\xe2\x99\xa5??\n->Server: \xe2\x98\xba 0 \xe2\x86\x95 \xe2\x96\xba\n->Server: www.google.de\n->Server: \xe2\x99\xa0 \xe2\x86\xa8 \xe2\x86\x91 \xe2\x86\x93 \xe2\x99\x82 \xe2\x98\xbb\xe2\x98\xba # 3t\nRun Code Online (Sandbox Code Playgroud)\n\n除了 TCP 侦听器之外,我愿意接受其他建议。谢谢!
\n成功了。使用 StreamReader/StreamWriter 处理 SSL 数据是错误的。数据被转换为字符串,从而出现错误(我假设)。使用NetworkStream.Read和NetworkStream.Write方法就byte[]做到了。
这是代码:
/// <summary>
/// Handles a TCP request.
/// </summary>
/// <param name="clientObject">The tcp client from the accepted connection.</param>
protected void HandleTCPRequest(object clientObject)
{
TcpClient inClient = clientObject as TcpClient;
TcpClient outClient = null;
try
{
NetworkStream clientStream = inClient.GetStream();
StreamReader clientReader = new StreamReader(clientStream);
StreamWriter clientWriter = new StreamWriter(clientStream);
// Read initial request.
List<String> connectRequest = new List<string>();
string line;
while (!String.IsNullOrEmpty(line = clientReader.ReadLine()))
{
connectRequest.Add(line);
}
if (connectRequest.Count == 0)
{
throw new Exception();
}
string[] requestLine0Split = connectRequest[0].Split(' ');
if (requestLine0Split.Length < 3)
{
throw new Exception();
}
// Check if it is CONNECT
string method = requestLine0Split[0];
if (!method.Equals("CONNECT"))
{
throw new Exception();
}
// Get host and port
string requestUri = requestLine0Split[1];
string[] uriSplit = requestUri.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
if (uriSplit.Length < 2)
{
throw new Exception();
}
string host = uriSplit[0];
int port = Int32.Parse(uriSplit[1]);
// Connect to server
outClient = new TcpClient(host, port);
// Send 200 Connection Established to Client
clientWriter.WriteLine("HTTP/1.0 200 Connection established\r\n\r\n");
clientWriter.Flush();
Logger.Debug("Established TCP connection for " + host + ":" + port);
Thread clientThread = new Thread(() => TunnelTCP(inClient, outClient));
Thread serverThread = new Thread(() => TunnelTCP(outClient, inClient));
clientThread.Start();
serverThread.Start();
}
catch(Exception)
{
// Disconnent if connections still alive
Logger.Debug("Closing TCP connection.");
try
{
if (inClient.Connected)
{
inClient.Close();
}
if (outClient != null && outClient.Connected)
{
outClient.Close();
}
}
catch (Exception e)
{
Logger.Warn("Could not close the tcp connection: ", e);
}
}
}
/// <summary>
/// Tunnels a TCP connection.
/// </summary>
/// <param name="inClient">The client to read from.</param>
/// <param name="outClient">The client to write to.</param>
public void TunnelTCP(TcpClient inClient, TcpClient outClient)
{
NetworkStream inStream = inClient.GetStream();
NetworkStream outStream = outClient.GetStream();
byte[] buffer = new byte[1024];
int read;
try
{
while (inClient.Connected && outClient.Connected)
{
if (inStream.DataAvailable && (read = inStream.Read(buffer, 0, buffer.Length)) != 0)
{
outStream.Write(buffer, 0, read);
}
}
}
catch (Exception e)
{
Logger.Debug("TCP connection error: ", e);
}
finally
{
Logger.Debug("Closing TCP connection.");
// Disconnent if connections still alive
try
{
if (inClient.Connected)
{
inClient.Close();
}
if (outClient.Connected)
{
outClient.Close();
}
}
catch (Exception e1)
{
Logger.Warn("Could not close the tcp connection: ", e1);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7763 次 |
| 最近记录: |