Enable to connect through the HTTP Proxy server

This commit is contained in:
sta 2014-07-19 21:23:31 +09:00
parent 0c9179be03
commit 1ef05fe0c3
4 changed files with 87 additions and 11 deletions

View File

@ -63,6 +63,9 @@ namespace Example
// For HTTP Authentication (Basic/Digest)
//ws.SetCredentials ("nobita", "password", false);
// For HTTP Proxy
//ws.SetHttpProxy ("http://localhost:3128", "nobita", "password");
// Setting Origin header
//ws.Origin = "http://echo.websocket.org";
//ws.Origin = "http://localhost:4649";

View File

@ -116,9 +116,11 @@ namespace WebSocketSharp
internal static HttpRequest CreateConnectRequest (Uri uri)
{
var authority = uri.Authority;
var host = uri.DnsSafeHost;
var port = uri.Port;
var authority = String.Format ("{0}:{1}", host, port);
var req = new HttpRequest ("CONNECT", authority);
req.Headers["Host"] = uri.Port == 80 ? uri.DnsSafeHost : authority;
req.Headers["Host"] = port == 80 ? host : authority;
return req;
}

View File

@ -1250,13 +1250,8 @@ namespace WebSocketSharp
// As client
private void setClientStream ()
{
var proxy = _proxyUri != null;
_tcpClient = proxy
? new TcpClient (_proxyUri.DnsSafeHost, _proxyUri.Port)
: new TcpClient (_uri.DnsSafeHost, _uri.Port);
_stream = WebSocketStream.CreateClientStream (
_tcpClient, proxy, _uri, _proxyCredentials, _secure, _certValidationCallback);
_uri, _proxyUri, _proxyCredentials, _secure, _certValidationCallback, out _tcpClient);
}
private void startReceiving ()
@ -2139,6 +2134,69 @@ namespace WebSocketSharp
}
}
/// <summary>
/// Sets the HTTP Proxy server URL to connect through, and a pair of <paramref name="username"/>
/// and <paramref name="password"/> for the proxy server authentication (Basic/Digest).
/// </summary>
/// <param name="url">
/// A <see cref="string"/> that represents the HTTP Proxy server URL to connect through.
/// </param>
/// <param name="username">
/// A <see cref="string"/> that represents the user name used to authenticate.
/// </param>
/// <param name="password">
/// A <see cref="string"/> that represents the password for <paramref name="username"/>
/// used to authenticate.
/// </param>
public void SetHttpProxy (string url, string username, string password)
{
lock (_forConn) {
var msg = checkIfAvailable ("SetHttpProxy", false, false);
if (msg == null) {
if (url.IsNullOrEmpty ()) {
_proxyUri = null;
_proxyCredentials = null;
_logger.Warn ("Proxy url and credentials were set back to the default.");
return;
}
Uri uri;
if (!Uri.TryCreate (url, UriKind.Absolute, out uri) ||
uri.Scheme != "http" ||
uri.Segments.Length > 1) {
msg = "The syntax of proxy url must be 'http://<host>[:<port>]'.";
}
else {
_proxyUri = uri;
if (username.IsNullOrEmpty ()) {
_proxyCredentials = null;
_logger.Warn ("Proxy credentials was set back to the default.");
return;
}
msg = username.Contains (':') || !username.IsText ()
? "'username' contains an invalid character."
: !password.IsNullOrEmpty () && !password.IsText ()
? "'password' contains an invalid character."
: null;
}
}
if (msg != null) {
_logger.Error (msg);
error (msg);
return;
}
_proxyCredentials = new NetworkCredential (
username, password, String.Format ("{0}:{1}", _uri.DnsSafeHost, _uri.Port));
}
}
#endregion
#region Explicit Interface Implementation

View File

@ -198,13 +198,18 @@ namespace WebSocketSharp
#region Internal Methods
internal static WebSocketStream CreateClientStream (
TcpClient tcpClient,
bool proxy,
Uri targetUri,
Uri proxyUri,
NetworkCredential proxyCredentials,
bool secure,
System.Net.Security.RemoteCertificateValidationCallback validationCallback)
System.Net.Security.RemoteCertificateValidationCallback validationCallback,
out TcpClient tcpClient)
{
var proxy = proxyUri != null;
tcpClient = proxy
? new TcpClient (proxyUri.DnsSafeHost, proxyUri.Port)
: new TcpClient (targetUri.DnsSafeHost, targetUri.Port);
var netStream = tcpClient.GetStream ();
if (proxy) {
var req = HttpRequest.CreateConnectRequest (targetUri);
@ -212,6 +217,14 @@ namespace WebSocketSharp
if (res.IsProxyAuthenticationRequired) {
var authChal = res.ProxyAuthenticationChallenge;
if (authChal != null && proxyCredentials != null) {
if (res.Headers.Contains ("Connection", "close")) {
netStream.Dispose ();
tcpClient.Close ();
tcpClient = new TcpClient (proxyUri.DnsSafeHost, proxyUri.Port);
netStream = tcpClient.GetStream ();
}
var authRes = new AuthenticationResponse (authChal, proxyCredentials, 0);
req.Headers["Proxy-Authorization"] = authRes.ToString ();
res = sendHttpRequest (netStream, req, 15000);