| Index: net/http/http_network_transaction.cc
|
| ===================================================================
|
| --- net/http/http_network_transaction.cc (revision 19002)
|
| +++ net/http/http_network_transaction.cc (working copy)
|
| @@ -26,6 +26,7 @@
|
| #include "net/http/http_response_headers.h"
|
| #include "net/http/http_util.h"
|
| #include "net/socket/client_socket_factory.h"
|
| +#include "net/socket/socks_client_socket.h"
|
| #include "net/socket/ssl_client_socket.h"
|
|
|
| using base::Time;
|
| @@ -141,6 +142,7 @@
|
| using_ssl_(false),
|
| using_proxy_(false),
|
| using_tunnel_(false),
|
| + using_socks_proxy_(false),
|
| establishing_tunnel_(false),
|
| reading_body_from_socket_(false),
|
| request_headers_(new RequestHeaders()),
|
| @@ -448,6 +450,15 @@
|
| rv = DoInitConnectionComplete(rv);
|
| TRACE_EVENT_END("http.init_conn", request_, request_->url.spec());
|
| break;
|
| + case STATE_SOCKS_CONNECT:
|
| + DCHECK_EQ(OK, rv);
|
| + TRACE_EVENT_BEGIN("http.socks_connect", request_, request_->url.spec());
|
| + rv = DoSOCKSConnect();
|
| + break;
|
| + case STATE_SOCKS_CONNECT_COMPLETE:
|
| + rv = DoSOCKSConnectComplete(rv);
|
| + TRACE_EVENT_END("http.socks_connect", request_, request_->url.spec());
|
| + break;
|
| case STATE_SSL_CONNECT:
|
| DCHECK_EQ(OK, rv);
|
| TRACE_EVENT_BEGIN("http.ssl_connect", request_, request_->url.spec());
|
| @@ -531,11 +542,10 @@
|
| int HttpNetworkTransaction::DoResolveProxyComplete(int result) {
|
| next_state_ = STATE_INIT_CONNECTION;
|
|
|
| - // Since we only support HTTP proxies or DIRECT connections, remove
|
| - // any other type of proxy from the list (i.e. SOCKS).
|
| - // Supporting SOCKS is issue http://crbug.com/469.
|
| + // Remove unsupported proxies (like SOCKS5) from the list.
|
| proxy_info_.RemoveProxiesWithoutScheme(
|
| - ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_HTTP);
|
| + ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_HTTP |
|
| + ProxyServer::SCHEME_SOCKS4);
|
|
|
| pac_request_ = NULL;
|
|
|
| @@ -552,15 +562,17 @@
|
| next_state_ = STATE_INIT_CONNECTION_COMPLETE;
|
|
|
| using_ssl_ = request_->url.SchemeIs("https");
|
| - using_proxy_ = !proxy_info_.is_direct() && !using_ssl_;
|
| - using_tunnel_ = !proxy_info_.is_direct() && using_ssl_;
|
| + using_socks_proxy_ = !proxy_info_.is_direct() &&
|
| + proxy_info_.proxy_server().is_socks();
|
| + using_proxy_ = !proxy_info_.is_direct() && !using_ssl_ && !using_socks_proxy_;
|
| + using_tunnel_ = !proxy_info_.is_direct() && using_ssl_ && !using_socks_proxy_;
|
|
|
| // Build the string used to uniquely identify connections of this type.
|
| // Determine the host and port to connect to.
|
| std::string connection_group;
|
| std::string host;
|
| int port;
|
| - if (using_proxy_ || using_tunnel_) {
|
| + if (using_proxy_ || using_tunnel_ || using_socks_proxy_) {
|
| ProxyServer proxy_server = proxy_info_.proxy_server();
|
| connection_group = "proxy/" + proxy_server.ToURI() + "/";
|
| host = proxy_server.HostNoBrackets();
|
| @@ -569,7 +581,7 @@
|
| host = request_->url.HostNoBrackets();
|
| port = request_->url.EffectiveIntPort();
|
| }
|
| - if (!using_proxy_)
|
| + if (!using_proxy_ && !using_socks_proxy_)
|
| connection_group.append(request_->url.GetOrigin().spec());
|
|
|
| DCHECK(!connection_group.empty());
|
| @@ -608,7 +620,9 @@
|
| // Now we have a TCP connected socket. Perform other connection setup as
|
| // needed.
|
| LogTCPConnectedMetrics();
|
| - if (using_ssl_ && !using_tunnel_) {
|
| + if (using_socks_proxy_)
|
| + next_state_ = STATE_SOCKS_CONNECT;
|
| + else if (using_ssl_ && !using_tunnel_) {
|
| next_state_ = STATE_SSL_CONNECT;
|
| } else {
|
| next_state_ = STATE_WRITE_HEADERS;
|
| @@ -620,6 +634,41 @@
|
| return OK;
|
| }
|
|
|
| +int HttpNetworkTransaction::DoSOCKSConnect() {
|
| + DCHECK(using_socks_proxy_);
|
| + DCHECK(!using_proxy_);
|
| + DCHECK(!using_tunnel_);
|
| +
|
| + next_state_ = STATE_SOCKS_CONNECT_COMPLETE;
|
| +
|
| + // Add a SOCKS connection on top of our existing transport socket.
|
| + ClientSocket* s = connection_.release_socket();
|
| + HostResolver::RequestInfo req_info(request_->url.HostNoBrackets(),
|
| + request_->url.EffectiveIntPort());
|
| + req_info.set_referrer(request_->referrer);
|
| +
|
| + s = new SOCKSClientSocket(s, req_info, session_->host_resolver());
|
| + connection_.set_socket(s);
|
| + return connection_.socket()->Connect(&io_callback_);
|
| +}
|
| +
|
| +int HttpNetworkTransaction::DoSOCKSConnectComplete(int result) {
|
| + DCHECK(using_socks_proxy_);
|
| + DCHECK(!using_proxy_);
|
| + DCHECK(!using_tunnel_);
|
| +
|
| + if (result == OK) {
|
| + if (using_ssl_) {
|
| + next_state_ = STATE_SSL_CONNECT;
|
| + } else {
|
| + next_state_ = STATE_WRITE_HEADERS;
|
| + }
|
| + } else {
|
| + result = ReconsiderProxyAfterError(result);
|
| + }
|
| + return result;
|
| +}
|
| +
|
| int HttpNetworkTransaction::DoSSLConnect() {
|
| next_state_ = STATE_SSL_CONNECT_COMPLETE;
|
|
|
|
|