summaryrefslogtreecommitdiffstats
path: root/net/http
diff options
context:
space:
mode:
authorwtc@google.com <wtc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-08 17:28:23 +0000
committerwtc@google.com <wtc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-08 17:28:23 +0000
commitc5949a3000ca3d6a7bd3a400ebd89206835a740a (patch)
tree19e5d48d1eab7fdeff3a9f443eead80bd17edb00 /net/http
parentdb8d02d65496004718bcd0416fcb35326eb08cd5 (diff)
downloadchromium_src-c5949a3000ca3d6a7bd3a400ebd89206835a740a.zip
chromium_src-c5949a3000ca3d6a7bd3a400ebd89206835a740a.tar.gz
chromium_src-c5949a3000ca3d6a7bd3a400ebd89206835a740a.tar.bz2
Handle TLS-intolerant servers by retrying with TLS 1.0
turned off. R=darin BUG=3001 Review URL: http://codereview.chromium.org/5617 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3017 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http')
-rw-r--r--net/http/http_network_transaction.cc33
-rw-r--r--net/http/http_network_transaction.h7
-rw-r--r--net/http/http_network_transaction_unittest.cc3
3 files changed, 39 insertions, 4 deletions
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index c391dae..de3539317 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -58,6 +58,12 @@ HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session,
read_buf_(NULL),
read_buf_len_(0),
next_state_(STATE_NONE) {
+#if defined(OS_WIN)
+ // TODO(wtc): Use SSL settings (bug 3003).
+ ssl_version_mask_ = SSLClientSocket::SSL3 | SSLClientSocket::TLS1;
+#else
+ ssl_version_mask_ = 0; // A dummy value so that the code compiles.
+#endif
}
void HttpNetworkTransaction::Destroy() {
@@ -483,7 +489,8 @@ int HttpNetworkTransaction::DoConnect() {
// If we are using a direct SSL connection, then go ahead and create the SSL
// wrapper socket now. Otherwise, we need to first issue a CONNECT request.
if (using_ssl_ && !using_tunnel_)
- s = socket_factory_->CreateSSLClientSocket(s, request_->url.host());
+ s = socket_factory_->CreateSSLClientSocket(s, request_->url.host(),
+ ssl_version_mask_);
connection_.set_socket(s);
return connection_.socket()->Connect(&io_callback_);
@@ -497,6 +504,8 @@ int HttpNetworkTransaction::DoConnectComplete(int result) {
next_state_ = STATE_WRITE_HEADERS;
if (using_tunnel_)
establishing_tunnel_ = true;
+ } else if (result == ERR_SSL_PROTOCOL_ERROR) {
+ result = HandleSSLHandshakeError(result);
} else {
result = ReconsiderProxyAfterError(result);
}
@@ -508,7 +517,8 @@ int HttpNetworkTransaction::DoSSLConnectOverTunnel() {
// Add a SSL socket on top of our existing transport socket.
ClientSocket* s = connection_.release_socket();
- s = socket_factory_->CreateSSLClientSocket(s, request_->url.host());
+ s = socket_factory_->CreateSSLClientSocket(s, request_->url.host(),
+ ssl_version_mask_);
connection_.set_socket(s);
return connection_.socket()->Connect(&io_callback_);
}
@@ -517,8 +527,11 @@ int HttpNetworkTransaction::DoSSLConnectOverTunnelComplete(int result) {
if (IsCertificateError(result))
result = HandleCertificateError(result);
- if (result == OK)
+ if (result == OK) {
next_state_ = STATE_WRITE_HEADERS;
+ } else if (result == ERR_SSL_PROTOCOL_ERROR) {
+ result = HandleSSLHandshakeError(result);
+ }
return result;
}
@@ -874,6 +887,20 @@ int HttpNetworkTransaction::HandleCertificateError(int error) {
return error;
}
+int HttpNetworkTransaction::HandleSSLHandshakeError(int error) {
+#if defined(OS_WIN)
+ if (ssl_version_mask_ & SSLClientSocket::TLS1) {
+ // This could be a TLS-intolerant server. Turn off TLS 1.0 and retry.
+ ssl_version_mask_ &= ~SSLClientSocket::TLS1;
+ connection_.set_socket(NULL);
+ connection_.Reset();
+ next_state_ = STATE_INIT_CONNECTION;
+ error = OK;
+ }
+#endif
+ return error;
+}
+
// This method determines whether it is safe to resend the request after an
// IO error. It can only be called in response to request header or body
// write errors or response header read errors. It should not be used in
diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h
index 2414050..bbbfb74 100644
--- a/net/http/http_network_transaction.h
+++ b/net/http/http_network_transaction.h
@@ -84,6 +84,11 @@ class HttpNetworkTransaction : public HttpTransaction {
// returns the same error code.
int HandleCertificateError(int error);
+ // Called to possibly recover from an SSL handshake error. Sets next_state_
+ // and returns OK if recovering from the error. Otherwise, the same error
+ // code is returned.
+ int HandleSSLHandshakeError(int error);
+
// Called to possibly recover from the given error. Sets next_state_ and
// returns OK if recovering from the error. Otherwise, the same error code
// is returned.
@@ -181,6 +186,8 @@ class HttpNetworkTransaction : public HttpTransaction {
// the real request/response of the transaction.
bool establishing_tunnel_;
+ int ssl_version_mask_;
+
std::string request_headers_;
size_t request_headers_bytes_sent_;
scoped_ptr<UploadDataStream> request_body_stream_;
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 8cfe348..b0d1964 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -158,7 +158,8 @@ class MockClientSocketFactory : public net::ClientSocketFactory {
}
virtual net::ClientSocket* CreateSSLClientSocket(
net::ClientSocket* transport_socket,
- const std::string& hostname) {
+ const std::string& hostname,
+ int protocol_version_mask) {
return NULL;
}
};