bool CreateTunnel (HttpWebRequest request, Stream stream, out byte [] buffer)
{
StringBuilder sb = new StringBuilder ();
sb.Append ("CONNECT ");
sb.Append (request.Address.Host);
sb.Append (':');
sb.Append (request.Address.Port);
sb.Append (" HTTP/");
if (request.ServicePoint.ProtocolVersion == HttpVersion.Version11)
sb.Append ("1.1");
else
sb.Append ("1.0");
sb.Append ("\r\nHost: ");
sb.Append (request.Address.Authority);
string challenge = Data.Challenge;
Data.Challenge = null;
bool have_auth = (request.Headers ["Proxy-Authorization"] != null);
if (have_auth) {
sb.Append ("\r\nProxy-Authorization: ");
sb.Append (request.Headers ["Proxy-Authorization"]);
} else if (challenge != null && Data.StatusCode == 407) {
have_auth = true;
ICredentials creds = request.Proxy.Credentials;
Authorization auth = AuthenticationManager.Authenticate (challenge, request, creds);
if (auth != null) {
sb.Append ("\r\nProxy-Authorization: ");
sb.Append (auth.Message);
}
}
sb.Append ("\r\n\r\n");
Data.StatusCode = 0;
byte [] connectBytes = Encoding.Default.GetBytes (sb.ToString ());
stream.Write (connectBytes, 0, connectBytes.Length);
int status;
WebHeaderCollection result = ReadHeaders (request, stream, out buffer, out status);
if (!have_auth && result != null && status == 407) { // Needs proxy auth
Data.StatusCode = status;
Data.Challenge = result ["Proxy-Authenticate"];
return false;
} else if (status != 200) {
string msg = String.Format ("The remote server returned a {0} status code.", status);
HandleError (WebExceptionStatus.SecureChannelFailure, null, msg);
return false;
}
return (result != null);
}