如何在执行 HTTP 隧道时保持连接打开



我连接到代理并使用连接命令发送一些自定义标头。这是一个要求。我得到 200 的回复。然后我尝试使用相同的连接来执行 get 请求(搜索附加代码以查找"GET {0}"(,但我总是收到一个错误,最终导致"连接关闭"(无法立即回忆起确切的错误(。特别是,我需要隧道连接到像 https:\www.somesecuresite.com 这样的网站,这是代码。为了简洁起见,某些部分被排除在外。

using (TcpClient client = new TcpClient(proxy, proxyPort))
{
using (NetworkStream stream = client.GetStream())
{
string EncodedData = encodeUIDPWD(UserName, Password);
#region Establish Tcp tunnel
string reqString = "CONNECT {0}:{1} HTTP/1.1rnProxy-Authorization:Basic " + EncodedData + "rnHost: {2}:{3}rn";
reqString += "Proxy-Connection: keep-alivern";
reqString += "Connection: keep-alivern";
reqString += "Header1: " + header1 + "rn";
reqString += "Header2: " + header2 + "rn"; 
reqString += "None: " + None + "rnrn";
string rString = String.Format(reqString, myUri.Host, myUri.Port, myUri.Host, myUri.Port);
#endregion
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
string reqConnectResult = await DoRequest(myUri, stream, rString);
lines.AddRange(reqConnectResult.Split(new string[] { Environment.NewLine }, StringSplitOptions.None).ToList());
if (!lines[0].Contains("200"))
{
//Error code gets caterd for here e.g 503 etc
}
else
{
foreach (string line in lines)
{
if (line.Contains("X-ProxyMesh-IP: "))
{
ip = line.Replace("X-ProxyMesh-IP: ", string.Empty);
}
}
string reqString1 = "GET {0} HTTP/1.1rnHost: {1}:{2}rn";
reqString1 += "Proxy-Connection: keep-alivern";
reqString1 += "Connection: keep-alivernrn";
string rString1 = string.Format(reqString1, myUri.PathAndQuery, myUri.Host, myUri.Port);
string reqPageResult = await DoRequest(myUri, stream, rString1);

lines.AddRange(reqPageResult.Split(new string[] { Environment.NewLine }, StringSplitOptions.None).ToList());
response.Content = new StringContent(lines.ToString());
if (lines[0].Contains("200"))
{ 
return new Tuple<bool, HttpResponseMessage>(true, response);
}
else
{
return new Tuple<bool, HttpResponseMessage>(false, response);
}
}
}
}
private async Task<string> DoRequest(Uri myUri, NetworkStream stream, string reqString)
{
byte[] tunnelRequest = Encoding.UTF8.GetBytes(reqString);
await stream.WriteAsync(tunnelRequest, 0, tunnelRequest.Length);
await stream.FlushAsync();

using (var memory = new MemoryStream())
{
await stream.CopyToAsync(memory);
memory.Position = 0;
var data = memory.ToArray();
//Basically just gets the header part.
int bm = BinaryMatch(data, Encoding.ASCII.GetBytes("rnrn"));
var index = bm + 4;
if (bm == -1)
{
index = 0;
}
var headers = Encoding.ASCII.GetString(data, 0, index);
memory.Position = index;
Console.WriteLine(headers);
if (headers.IndexOf("Content-Encoding: gzip") > 0)
{
using (GZipStream decompressionStream = new GZipStream(memory, CompressionMode.Decompress))
using (var decompressedMemory = new MemoryStream())
{
decompressionStream.CopyTo(decompressedMemory);
decompressedMemory.Position = 0;
string s = (Encoding.UTF8.GetString(decompressedMemory.ToArray()));
Console.WriteLine(s);
return headers + s;
}
}
else
{
string s = (Encoding.UTF8.GetString(data, index, data.Length - index));
Console.WriteLine(s);
return headers + s;
}
}
}           

Http连接由于其在特定时间后自动关闭连接的性质而接近,除了增加连接的自动关闭持续时间外,您无能为力,这再次取决于服务器到服务器。 最终导致连接超时。

FTP连接,如果你想上传或下载需要地狱很多时间的数据,最好使用FTP连接,它的存在只是出于同样的原因。

根据标头的性质,您可以考虑使用 WebSocket,因为您可以发送自定义授权标头。

由于 WebSocket 旨在在同一连接应允许全双工通信(数据下载和上载(时使用,因此它比 HTTP 连接更合适。

相关内容

  • 没有找到相关文章

最新更新