Ich verbinde mich mit einem Proxy und mit dem Befehl connect sende ich einige benutzerdefinierte Header. Dies ist eine Voraussetzung. Ich bekomme eine 200 Antwort. Dann versuche ich, die gleiche Verbindung zu verwenden, um eine get-Anfrage zu machen (Suche angehängt Code für "GET {0}"), aber ich bekomme immer einen Fehler, der endet "Verbindung geschlossen" (kann nicht den genauen Fehler von Hand aufrufen). ESSENTIELL Ich muss tunnel zu einem websit wie https: \ www.omesecuresite.com Heres der Code. Bestimmte Teile wurden für Breviaty ausgeschlossen.So halten Sie die Verbindung beim HTTP-Tunneling offen
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.1\r\nProxy-Authorization:Basic " + EncodedData + "\r\nHost: {2}:{3}\r\n";
reqString += "Proxy-Connection: keep-alive\r\n";
reqString += "Connection: keep-alive\r\n";
reqString += "Header1: " + header1 + "\r\n";
reqString += "Header2: " + header2 + "\r\n";
reqString += "None: " + None + "\r\n\r\n";
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.1\r\nHost: {1}:{2}\r\n";
reqString1 += "Proxy-Connection: keep-alive\r\n";
reqString1 += "Connection: keep-alive\r\n\r\n";
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("\r\n\r\n"));
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;
}
}
}
Reagiert der Server mit einem Header von 'Connection: keep-alive'? Wenn nicht, dann wird es wahrscheinlich nicht unterstützt. –
Gibt es auch einen Grund, warum Sie das manuell tun und 'System.Net.WebRequest' nicht verwenden? –
[This] (https://stackoverflow.com/questions/19155201/http-keep-alive-timeout) könnte hilfreich sein. – Shanky