From 21d179b334e59e9a3bfcaed4c4430bef1bc5759d Mon Sep 17 00:00:00 2001 From: Kristian Monsen Date: Wed, 11 May 2011 20:53:37 +0100 Subject: Merge Chromium at 10.0.621.0: Initial merge by git. Change-Id: I070cc91c608dfa4a968a5a54c173260765ac8097 --- net/http/http_network_transaction.cc | 104 ++++++++++++++++------------------- 1 file changed, 47 insertions(+), 57 deletions(-) (limited to 'net/http/http_network_transaction.cc') diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 7621e5a..64a4fa7 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -285,11 +285,13 @@ int HttpNetworkTransaction::Read(IOBuffer* buf, int buf_len, scoped_refptr headers(GetResponseHeaders()); if (headers_valid_ && headers.get() && stream_request_.get()) { // We're trying to read the body of the response but we're still trying - // to establish an SSL tunnel through the proxy. We can't read these + // to establish an SSL tunnel through an HTTP proxy. We can't read these // bytes when establishing a tunnel because they might be controlled by // an active network attacker. We don't worry about this for HTTP // because an active network attacker can already control HTTP sessions. - // We reach this case when the user cancels a 407 proxy auth prompt. + // We reach this case when the user cancels a 407 proxy auth prompt. We + // also don't worry about this for an HTTPS Proxy, because the + // communication with the proxy is secure. // See http://crbug.com/8473. DCHECK(proxy_info_.is_http() || proxy_info_.is_https()); DCHECK_EQ(headers->response_code(), 407); @@ -301,7 +303,6 @@ int HttpNetworkTransaction::Read(IOBuffer* buf, int buf_len, // Are we using SPDY or HTTP? next_state = STATE_READ_BODY; - DCHECK(stream_->GetResponseInfo()->headers); read_buf_ = buf; read_buf_len_ = buf_len; @@ -410,6 +411,18 @@ void HttpNetworkTransaction::OnNeedsClientAuth( OnIOComplete(ERR_SSL_CLIENT_AUTH_CERT_NEEDED); } +void HttpNetworkTransaction::OnHttpsProxyTunnelResponse( + const HttpResponseInfo& response_info, + HttpStream* stream) { + DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); + + headers_valid_ = true; + response_ = response_info; + stream_.reset(stream); + stream_request_.reset(); // we're done with the stream request + OnIOComplete(ERR_HTTPS_PROXY_TUNNEL_RESPONSE); +} + bool HttpNetworkTransaction::is_https_request() const { return request_->url.SchemeIs("https"); } @@ -535,12 +548,12 @@ int HttpNetworkTransaction::DoCreateStreamComplete(int result) { DCHECK(stream_.get()); } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { result = HandleCertificateRequest(result); + } else if (result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { + // Return OK and let the caller read the proxy's error page + next_state_ = STATE_NONE; + 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; @@ -683,6 +696,23 @@ 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) @@ -994,61 +1024,11 @@ 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/66424 -int HttpNetworkTransaction::HandleSSLHandshakeError(int error) { - DCHECK(request_); - if (ssl_config_.send_client_cert && - (error == ERR_SSL_PROTOCOL_ERROR || - error == ERR_BAD_SSL_CLIENT_AUTH_CERT)) { - 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 Read 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 @@ -1062,6 +1042,16 @@ 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; } -- cgit v1.1