///<summary>Processes a specified query and connects to the requested HTTP web server.</summary> ///<param name="Query">A string containing the query to process.</param> ///<remarks>If there's an error while processing the HTTP request or when connecting to the remote server, the Proxy sends a "400 - Bad Request" error to the client.</remarks> private void ProcessQuery(string Query) { HeaderFields = ParseQuery(Query); if (HeaderFields == null || !HeaderFields.ContainsKey("Host")) { SendBadRequest(); return; } #region Parse destination address and port int Port; string Host; int Ret; if (HttpRequestType.ToUpper().Equals("CONNECT")) //HTTPS { isThisSSL = true; this.isPayloadSecure = true; Ret = RequestedPath.IndexOf(":"); if (Ret >= 0) { Host = RequestedPath.Substring(0, Ret); if (RequestedPath.Length > Ret + 1) { Port = int.Parse(RequestedPath.Substring(Ret + 1)); CurrentHTTPSport = Port; } else { Port = 443; CurrentHTTPSport = 443; } } else { Host = RequestedPath; Port = 443; CurrentHTTPSport = 443; } } else { isThisSSL = false; Ret = ((string)HeaderFields["Host"]).IndexOf(":"); if (Ret > 0) { Host = ((string)HeaderFields["Host"]).Substring(0, Ret); Port = int.Parse(((string)HeaderFields["Host"]).Substring(Ret + 1)); CurrentHTTPSport = Port; } else { Host = (string)HeaderFields["Host"]; Port = 80; CurrentHTTPSport = 80; } if (HttpRequestType.ToUpper().Equals("GET") == false) { int index = Query.IndexOf("\r\n\r\n"); m_HttpPost = Query.Substring(index + 4); } } #endregion #region Create destination socket try { IPEndPoint DestinationEndPoint = new IPEndPoint(Dns.Resolve(Host).AddressList[0], Port); if (this.isPayloadSecure) { SecurityOptions options = new SecurityOptions( SecureProtocol.Ssl3 | SecureProtocol.Tls1, // use SSL3 or TLS1 null, // not required for SSL client ConnectionEnd.Client, // this is the client side CredentialVerification.None, // do not check the certificate -- this should not be used in a real-life application :-) null, // not used with automatic certificate verification "www.bogus.com", // this is the common name of the Microsoft web server SecurityFlags.Default, // use the default security flags SslAlgorithms.SECURE_CIPHERS, // only use secure ciphers null); // do not process certificate requests. // This line for intercept proxy DestinationSocket = new SecureSocket(DestinationEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp, options); // This line for pass-through proxy //DestinationSocket = new SecureSocket(DestinationEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); } else { DestinationSocket = new SecureSocket(DestinationEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); } if (HeaderFields.ContainsKey("Proxy-Connection") && HeaderFields["Proxy-Connection"].ToLower().Equals("keep-alive")) { DestinationSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, 1); } DestinationSocket.BeginConnect(DestinationEndPoint, new AsyncCallback(this.OnConnected), DestinationSocket); } catch { SendBadRequest(); return; } #endregion }