I connect to a proxy and with the connect command I send some custom headers. This is a requirement. I get a 200 response. Then I try to use the same connection to do a get request (search attached code for "GET {0}") but I always get a error that ends up "connection closed" (cant recall the exact error offhand). esssentially I need to tunnel to a websit like https:\www.somesecuresite.com Heres the code. Certain parts were excluded for breviaty.
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;
}
}
}
Http Connection get close due to its nature of auto closing connection after specific time ,there is not much you can do about apart from increasing autclosing duration for connection which is again depends on server to server. which ends up in connection time out at the end.
FTP Connection if you want to upload or download data which require hell lot of time better use FTP connection which exists for the very same reason only.
Depending on the nature of your headers you may consider using WebSockets as you can send custom authorization headers.
Because WebSocket is intended to be used when the same connection should allow full duplex communication (both data download and upload), it is more appropriate than an HTTP connection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With