summaryrefslogtreecommitdiffstats
path: root/net/http/http_network_transaction.cc
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2011-05-31 20:30:28 +0100
committerKristian Monsen <kristianm@google.com>2011-06-14 20:31:41 -0700
commit72a454cd3513ac24fbdd0e0cb9ad70b86a99b801 (patch)
tree382278a54ce7a744d62fa510a9a80688cc12434b /net/http/http_network_transaction.cc
parentc4becdd46e31d261b930e4b5a539cbc1d45c23a6 (diff)
downloadexternal_chromium-72a454cd3513ac24fbdd0e0cb9ad70b86a99b801.zip
external_chromium-72a454cd3513ac24fbdd0e0cb9ad70b86a99b801.tar.gz
external_chromium-72a454cd3513ac24fbdd0e0cb9ad70b86a99b801.tar.bz2
Merge Chromium.org at r11.0.672.0: Initial merge by git.
Change-Id: I8b4aaf611a2a405fe3fe10e8a94ea7658645c192
Diffstat (limited to 'net/http/http_network_transaction.cc')
-rw-r--r--net/http/http_network_transaction.cc124
1 files changed, 76 insertions, 48 deletions
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 64a4fa7..128497f 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -33,6 +33,7 @@
#include "net/http/http_basic_stream.h"
#include "net/http/http_chunked_decoder.h"
#include "net/http/http_net_log_params.h"
+#include "net/http/http_network_delegate.h"
#include "net/http/http_network_session.h"
#include "net/http/http_proxy_client_socket.h"
#include "net/http/http_proxy_client_socket_pool.h"
@@ -76,6 +77,19 @@ void ProcessAlternateProtocol(HttpStreamFactory* factory,
http_host_port_pair);
}
+// Returns true if |error| is a client certificate authentication error.
+bool IsClientCertificateError(int error) {
+ switch (error) {
+ case ERR_BAD_SSL_CLIENT_AUTH_CERT:
+ case ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED:
+ case ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY:
+ case ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED:
+ return true;
+ default:
+ return false;
+ }
+}
+
} // namespace
//-----------------------------------------------------------------------------
@@ -486,7 +500,8 @@ int HttpNetworkTransaction::DoLoop(int result) {
break;
case STATE_SEND_REQUEST_COMPLETE:
rv = DoSendRequestComplete(rv);
- net_log_.EndEvent(NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST, NULL);
+ net_log_.EndEventWithNetErrorCode(
+ NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST, rv);
break;
case STATE_READ_HEADERS:
DCHECK_EQ(OK, rv);
@@ -495,7 +510,8 @@ int HttpNetworkTransaction::DoLoop(int result) {
break;
case STATE_READ_HEADERS_COMPLETE:
rv = DoReadHeadersComplete(rv);
- net_log_.EndEvent(NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS, NULL);
+ net_log_.EndEventWithNetErrorCode(
+ NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS, rv);
break;
case STATE_READ_BODY:
DCHECK_EQ(OK, rv);
@@ -504,7 +520,8 @@ int HttpNetworkTransaction::DoLoop(int result) {
break;
case STATE_READ_BODY_COMPLETE:
rv = DoReadBodyComplete(rv);
- net_log_.EndEvent(NetLog::TYPE_HTTP_TRANSACTION_READ_BODY, NULL);
+ net_log_.EndEventWithNetErrorCode(
+ NetLog::TYPE_HTTP_TRANSACTION_READ_BODY, rv);
break;
case STATE_DRAIN_BODY_FOR_AUTH_RESTART:
DCHECK_EQ(OK, rv);
@@ -514,8 +531,8 @@ int HttpNetworkTransaction::DoLoop(int result) {
break;
case STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE:
rv = DoDrainBodyForAuthRestartComplete(rv);
- net_log_.EndEvent(
- NetLog::TYPE_HTTP_TRANSACTION_DRAIN_BODY_FOR_AUTH_RESTART, NULL);
+ net_log_.EndEventWithNetErrorCode(
+ NetLog::TYPE_HTTP_TRANSACTION_DRAIN_BODY_FOR_AUTH_RESTART, rv);
break;
default:
NOTREACHED() << "bad state";
@@ -554,6 +571,10 @@ int HttpNetworkTransaction::DoCreateStreamComplete(int result) {
return OK;
}
+ // Handle possible handshake errors that may have occurred if the stream
+ // used SSL for one or more of the layers.
+ result = HandleSSLHandshakeError(result);
+
// At this point we are done with the stream_request_.
stream_request_.reset();
return result;
@@ -696,23 +717,6 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
result = HandleCertificateRequest(result);
if (result == OK)
return result;
- } else if ((result == ERR_SSL_DECOMPRESSION_FAILURE_ALERT ||
- result == ERR_SSL_BAD_RECORD_MAC_ALERT) &&
- ssl_config_.tls1_enabled &&
- !SSLConfigService::IsKnownStrictTLSServer(request_->url.host())) {
- // Some buggy servers select DEFLATE compression when offered and then
- // fail to ever decompress anything. They will send a fatal alert telling
- // us this. Normally we would pick this up during the handshake because
- // our Finished message is compressed and we'll never get the server's
- // Finished if it fails to process ours.
- //
- // However, with False Start, we'll believe that the handshake is
- // complete as soon as we've /sent/ our Finished message. In this case,
- // we only find out that the server is buggy here, when we try to read
- // the initial reply.
- session_->http_stream_factory()->AddTLSIntolerantServer(request_->url);
- ResetConnectionAndRequestForResend();
- return OK;
}
if (result < 0 && result != ERR_CONNECTION_CLOSED)
@@ -1024,11 +1028,61 @@ int HttpNetworkTransaction::HandleCertificateRequest(int error) {
return OK;
}
+// TODO(rch): This does not correctly handle errors when an SSL proxy is
+// being used, as all of the errors are handled as if they were generated
+// by the endpoint host, request_->url, rather than considering if they were
+// generated by the SSL proxy. http://crbug.com/69329
+int HttpNetworkTransaction::HandleSSLHandshakeError(int error) {
+ DCHECK(request_);
+ if (ssl_config_.send_client_cert &&
+ (error == ERR_SSL_PROTOCOL_ERROR || IsClientCertificateError(error))) {
+ session_->ssl_client_auth_cache()->Remove(
+ GetHostAndPort(request_->url));
+ }
+
+ switch (error) {
+ case ERR_SSL_PROTOCOL_ERROR:
+ case ERR_SSL_VERSION_OR_CIPHER_MISMATCH:
+ case ERR_SSL_DECOMPRESSION_FAILURE_ALERT:
+ case ERR_SSL_BAD_RECORD_MAC_ALERT:
+ if (ssl_config_.tls1_enabled &&
+ !SSLConfigService::IsKnownStrictTLSServer(request_->url.host())) {
+ // This could be a TLS-intolerant server, an SSL 3.0 server that
+ // chose a TLS-only cipher suite or a server with buggy DEFLATE
+ // support. Turn off TLS 1.0, DEFLATE support and retry.
+ session_->http_stream_factory()->AddTLSIntolerantServer(request_->url);
+ ResetConnectionAndRequestForResend();
+ error = OK;
+ }
+ break;
+ case ERR_SSL_SNAP_START_NPN_MISPREDICTION:
+ // This means that we tried to Snap Start a connection, but we
+ // mispredicted the NPN result. This isn't a problem from the point of
+ // view of the SSL layer because the server will ignore the application
+ // data in the Snap Start extension. However, at the HTTP layer, we have
+ // already decided that it's a HTTP or SPDY connection and it's easier to
+ // abort and start again.
+ ResetConnectionAndRequestForResend();
+ error = OK;
+ break;
+ }
+ 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
// other cases, such as a Connect error.
int HttpNetworkTransaction::HandleIOError(int error) {
+ // SSL errors may happen at any time during the stream and indicate issues
+ // with the underlying connection. Because the peer may request
+ // renegotiation at any time, check and handle any possible SSL handshake
+ // related errors. In addition to renegotiation, TLS False/Snap Start may
+ // cause SSL handshake errors to be delayed until the first or second Write
+ // (Snap Start) or the first Read (False & Snap Start) on the underlying
+ // connection.
+ error = HandleSSLHandshakeError(error);
+
switch (error) {
// If we try to reuse a connection that the server is in the process of
// closing, we may end up successfully writing out our request (or a
@@ -1042,16 +1096,6 @@ int HttpNetworkTransaction::HandleIOError(int error) {
error = OK;
}
break;
- case ERR_SSL_SNAP_START_NPN_MISPREDICTION:
- // This means that we tried to Snap Start a connection, but we
- // mispredicted the NPN result. This isn't a problem from the point of
- // view of the SSL layer because the server will ignore the application
- // data in the Snap Start extension. However, at the HTTP layer, we have
- // already decided that it's a HTTP or SPDY connection and it's easier to
- // abort and start again.
- ResetConnectionAndRequestForResend();
- error = OK;
- break;
}
return error;
}
@@ -1191,22 +1235,6 @@ std::string HttpNetworkTransaction::DescribeState(State state) {
return description;
}
-// TODO(gavinp): re-adjust this once SPDY v3 has three priority bits,
-// eliminating the need for this folding.
-int ConvertRequestPriorityToSpdyPriority(const RequestPriority priority) {
- DCHECK(HIGHEST <= priority && priority < NUM_PRIORITIES);
- switch (priority) {
- case LOWEST:
- return SPDY_PRIORITY_LOWEST-1;
- case IDLE:
- return SPDY_PRIORITY_LOWEST;
- default:
- return priority;
- }
-}
-
-
-
#undef STATE_CASE
} // namespace net