Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: net/http/http_network_transaction.cc

Issue 43115: Change the bad-certificate handler for SSL (using NSS) to return an... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/http_network_transaction.h" 5 #include "net/http/http_network_transaction.h"
6 6
7 #include "base/scoped_ptr.h" 7 #include "base/scoped_ptr.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/field_trial.h" 9 #include "base/field_trial.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 73
74 next_state_ = STATE_RESOLVE_PROXY; 74 next_state_ = STATE_RESOLVE_PROXY;
75 int rv = DoLoop(OK); 75 int rv = DoLoop(OK);
76 if (rv == ERR_IO_PENDING) 76 if (rv == ERR_IO_PENDING)
77 user_callback_ = callback; 77 user_callback_ = callback;
78 return rv; 78 return rv;
79 } 79 }
80 80
81 int HttpNetworkTransaction::RestartIgnoringLastError( 81 int HttpNetworkTransaction::RestartIgnoringLastError(
82 CompletionCallback* callback) { 82 CompletionCallback* callback) {
83 // TODO(wtc): If the connection is no longer alive, call 83 if (connection_.socket()->IsConnected()) {
84 // connection_.socket()->ReconnectIgnoringLastError(). 84 next_state_ = STATE_WRITE_HEADERS;
85 next_state_ = STATE_WRITE_HEADERS; 85 } else {
86 connection_.set_socket(NULL);
87 connection_.Reset();
88 next_state_ = STATE_INIT_CONNECTION;
89 }
86 int rv = DoLoop(OK); 90 int rv = DoLoop(OK);
87 if (rv == ERR_IO_PENDING) 91 if (rv == ERR_IO_PENDING)
88 user_callback_ = callback; 92 user_callback_ = callback;
89 return rv; 93 return rv;
90 } 94 }
91 95
92 int HttpNetworkTransaction::RestartWithAuth( 96 int HttpNetworkTransaction::RestartWithAuth(
93 const std::wstring& username, 97 const std::wstring& username,
94 const std::wstring& password, 98 const std::wstring& password,
95 CompletionCallback* callback) { 99 CompletionCallback* callback) {
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 } 246 }
243 247
244 LoadState HttpNetworkTransaction::GetLoadState() const { 248 LoadState HttpNetworkTransaction::GetLoadState() const {
245 // TODO(wtc): Define a new LoadState value for the 249 // TODO(wtc): Define a new LoadState value for the
246 // STATE_INIT_CONNECTION_COMPLETE state, which delays the HTTP request. 250 // STATE_INIT_CONNECTION_COMPLETE state, which delays the HTTP request.
247 switch (next_state_) { 251 switch (next_state_) {
248 case STATE_RESOLVE_PROXY_COMPLETE: 252 case STATE_RESOLVE_PROXY_COMPLETE:
249 return LOAD_STATE_RESOLVING_PROXY_FOR_URL; 253 return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
250 case STATE_RESOLVE_HOST_COMPLETE: 254 case STATE_RESOLVE_HOST_COMPLETE:
251 return LOAD_STATE_RESOLVING_HOST; 255 return LOAD_STATE_RESOLVING_HOST;
252 case STATE_CONNECT_COMPLETE: 256 case STATE_TCP_CONNECT_COMPLETE:
253 return LOAD_STATE_CONNECTING; 257 return LOAD_STATE_CONNECTING;
254 case STATE_WRITE_HEADERS_COMPLETE: 258 case STATE_WRITE_HEADERS_COMPLETE:
255 case STATE_WRITE_BODY_COMPLETE: 259 case STATE_WRITE_BODY_COMPLETE:
256 return LOAD_STATE_SENDING_REQUEST; 260 return LOAD_STATE_SENDING_REQUEST;
257 case STATE_READ_HEADERS_COMPLETE: 261 case STATE_READ_HEADERS_COMPLETE:
258 return LOAD_STATE_WAITING_FOR_RESPONSE; 262 return LOAD_STATE_WAITING_FOR_RESPONSE;
259 case STATE_READ_BODY_COMPLETE: 263 case STATE_READ_BODY_COMPLETE:
260 return LOAD_STATE_READING_RESPONSE; 264 return LOAD_STATE_READING_RESPONSE;
261 default: 265 default:
262 return LOAD_STATE_IDLE; 266 return LOAD_STATE_IDLE;
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 break; 405 break;
402 case STATE_RESOLVE_HOST: 406 case STATE_RESOLVE_HOST:
403 DCHECK_EQ(OK, rv); 407 DCHECK_EQ(OK, rv);
404 TRACE_EVENT_BEGIN("http.resolve_host", request_, request_->url.spec()); 408 TRACE_EVENT_BEGIN("http.resolve_host", request_, request_->url.spec());
405 rv = DoResolveHost(); 409 rv = DoResolveHost();
406 break; 410 break;
407 case STATE_RESOLVE_HOST_COMPLETE: 411 case STATE_RESOLVE_HOST_COMPLETE:
408 rv = DoResolveHostComplete(rv); 412 rv = DoResolveHostComplete(rv);
409 TRACE_EVENT_END("http.resolve_host", request_, request_->url.spec()); 413 TRACE_EVENT_END("http.resolve_host", request_, request_->url.spec());
410 break; 414 break;
411 case STATE_CONNECT: 415 case STATE_TCP_CONNECT:
412 DCHECK_EQ(OK, rv); 416 DCHECK_EQ(OK, rv);
413 TRACE_EVENT_BEGIN("http.connect", request_, request_->url.spec()); 417 TRACE_EVENT_BEGIN("http.connect", request_, request_->url.spec());
wtc 2009/03/30 18:18:57 Nit: Should we rename this event "http.tcp_connect
414 rv = DoConnect(); 418 rv = DoTCPConnect();
415 break; 419 break;
416 case STATE_CONNECT_COMPLETE: 420 case STATE_TCP_CONNECT_COMPLETE:
417 rv = DoConnectComplete(rv); 421 rv = DoTCPConnectComplete(rv);
418 TRACE_EVENT_END("http.connect", request_, request_->url.spec()); 422 TRACE_EVENT_END("http.connect", request_, request_->url.spec());
wtc 2009/03/30 18:18:57 Nit: Should we rename this event "http.tcp_connect
419 break; 423 break;
420 case STATE_SSL_CONNECT_OVER_TUNNEL: 424 case STATE_SSL_CONNECT:
421 DCHECK_EQ(OK, rv); 425 DCHECK_EQ(OK, rv);
422 TRACE_EVENT_BEGIN("http.ssl_tunnel", request_, request_->url.spec()); 426 TRACE_EVENT_BEGIN("http.ssl_connect", request_, request_->url.spec());
423 rv = DoSSLConnectOverTunnel(); 427 rv = DoSSLConnect();
424 break; 428 break;
425 case STATE_SSL_CONNECT_OVER_TUNNEL_COMPLETE: 429 case STATE_SSL_CONNECT_COMPLETE:
426 rv = DoSSLConnectOverTunnelComplete(rv); 430 rv = DoSSLConnectComplete(rv);
427 TRACE_EVENT_END("http.ssl_tunnel", request_, request_->url.spec()); 431 TRACE_EVENT_END("http.ssl_connect", request_, request_->url.spec());
428 break; 432 break;
429 case STATE_WRITE_HEADERS: 433 case STATE_WRITE_HEADERS:
430 DCHECK_EQ(OK, rv); 434 DCHECK_EQ(OK, rv);
431 TRACE_EVENT_BEGIN("http.write_headers", request_, request_->url.spec()); 435 TRACE_EVENT_BEGIN("http.write_headers", request_, request_->url.spec());
432 rv = DoWriteHeaders(); 436 rv = DoWriteHeaders();
433 break; 437 break;
434 case STATE_WRITE_HEADERS_COMPLETE: 438 case STATE_WRITE_HEADERS_COMPLETE:
435 rv = DoWriteHeadersComplete(rv); 439 rv = DoWriteHeadersComplete(rv);
436 TRACE_EVENT_END("http.write_headers", request_, request_->url.spec()); 440 TRACE_EVENT_END("http.write_headers", request_, request_->url.spec());
437 break; 441 break;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 } 575 }
572 576
573 DidStartDnsResolution(host, this); 577 DidStartDnsResolution(host, this);
574 return resolver_.Resolve(host, port, &addresses_, &io_callback_); 578 return resolver_.Resolve(host, port, &addresses_, &io_callback_);
575 } 579 }
576 580
577 int HttpNetworkTransaction::DoResolveHostComplete(int result) { 581 int HttpNetworkTransaction::DoResolveHostComplete(int result) {
578 bool ok = (result == OK); 582 bool ok = (result == OK);
579 DidFinishDnsResolutionWithStatus(ok, request_->referrer, this); 583 DidFinishDnsResolutionWithStatus(ok, request_->referrer, this);
580 if (ok) { 584 if (ok) {
581 next_state_ = STATE_CONNECT; 585 next_state_ = STATE_TCP_CONNECT;
582 } else { 586 } else {
583 result = ReconsiderProxyAfterError(result); 587 result = ReconsiderProxyAfterError(result);
584 } 588 }
585 return result; 589 return result;
586 } 590 }
587 591
588 int HttpNetworkTransaction::DoConnect() { 592 int HttpNetworkTransaction::DoTCPConnect() {
589 next_state_ = STATE_CONNECT_COMPLETE; 593 next_state_ = STATE_TCP_CONNECT_COMPLETE;
590 594
591 DCHECK(!connection_.socket()); 595 DCHECK(!connection_.socket());
592 596
593 ClientSocket* s = socket_factory_->CreateTCPClientSocket(addresses_); 597 ClientSocket* s = socket_factory_->CreateTCPClientSocket(addresses_);
594
595 // If we are using a direct SSL connection, then go ahead and create the SSL
596 // wrapper socket now. Otherwise, we need to first issue a CONNECT request.
597 if (using_ssl_ && !using_tunnel_)
598 s = socket_factory_->CreateSSLClientSocket(s, request_->url.host(),
599 ssl_config_);
600
601 connection_.set_socket(s); 598 connection_.set_socket(s);
602 return connection_.socket()->Connect(&io_callback_); 599 return connection_.socket()->Connect(&io_callback_);
603 } 600 }
604 601
605 int HttpNetworkTransaction::DoConnectComplete(int result) { 602 int HttpNetworkTransaction::DoTCPConnectComplete(int result) {
606 if (IsCertificateError(result)) 603 // If we are using a direct SSL connection, then go ahead and establish the
607 result = HandleCertificateError(result); 604 // SSL connection, now. Otherwise, we need to first issue a CONNECT request.
wtc 2009/03/30 18:18:57 Nit: remove the comma (,) before "now".
608
609 if (result == OK) { 605 if (result == OK) {
610 next_state_ = STATE_WRITE_HEADERS; 606 if (using_ssl_ && !using_tunnel_) {
611 if (using_tunnel_) 607 next_state_ = STATE_SSL_CONNECT;
612 establishing_tunnel_ = true; 608 } else {
609 next_state_ = STATE_WRITE_HEADERS;
610 if (using_tunnel_)
611 establishing_tunnel_ = true;
612 }
613 } else { 613 } else {
614 result = HandleSSLHandshakeError(result); 614 result = ReconsiderProxyAfterError(result);
615 if (result != OK)
616 result = ReconsiderProxyAfterError(result);
617 } 615 }
618 return result; 616 return result;
619 } 617 }
620 618
621 int HttpNetworkTransaction::DoSSLConnectOverTunnel() { 619 int HttpNetworkTransaction::DoSSLConnect() {
622 next_state_ = STATE_SSL_CONNECT_OVER_TUNNEL_COMPLETE; 620 next_state_ = STATE_SSL_CONNECT_COMPLETE;
623 621
624 // Add a SSL socket on top of our existing transport socket. 622 // Add a SSL socket on top of our existing transport socket.
625 ClientSocket* s = connection_.release_socket(); 623 ClientSocket* s = connection_.release_socket();
626 s = socket_factory_->CreateSSLClientSocket(s, request_->url.host(), 624 s = socket_factory_->CreateSSLClientSocket(s, request_->url.host(),
627 ssl_config_); 625 ssl_config_);
628 connection_.set_socket(s); 626 connection_.set_socket(s);
629 return connection_.socket()->Connect(&io_callback_); 627 return connection_.socket()->Connect(&io_callback_);
630 } 628 }
631 629
632 int HttpNetworkTransaction::DoSSLConnectOverTunnelComplete(int result) { 630 int HttpNetworkTransaction::DoSSLConnectComplete(int result) {
633 if (IsCertificateError(result)) 631 if (IsCertificateError(result))
634 result = HandleCertificateError(result); 632 result = HandleCertificateError(result);
635 633
636 if (result == OK) { 634 if (result == OK) {
637 next_state_ = STATE_WRITE_HEADERS; 635 next_state_ = STATE_WRITE_HEADERS;
638 } else { 636 } else {
639 result = HandleSSLHandshakeError(result); 637 result = HandleSSLHandshakeError(result);
640 } 638 }
641 return result; 639 return result;
642 } 640 }
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 return ERR_METHOD_NOT_SUPPORTED; 1003 return ERR_METHOD_NOT_SUPPORTED;
1006 } 1004 }
1007 1005
1008 if (establishing_tunnel_) { 1006 if (establishing_tunnel_) {
1009 switch (headers->response_code()) { 1007 switch (headers->response_code()) {
1010 case 200: // OK 1008 case 200: // OK
1011 if (header_buf_body_offset_ != header_buf_len_) { 1009 if (header_buf_body_offset_ != header_buf_len_) {
1012 // The proxy sent extraneous data after the headers. 1010 // The proxy sent extraneous data after the headers.
1013 return ERR_TUNNEL_CONNECTION_FAILED; 1011 return ERR_TUNNEL_CONNECTION_FAILED;
1014 } 1012 }
1015 next_state_ = STATE_SSL_CONNECT_OVER_TUNNEL; 1013 next_state_ = STATE_SSL_CONNECT;
1016 // Reset for the real request and response headers. 1014 // Reset for the real request and response headers.
1017 request_headers_.clear(); 1015 request_headers_.clear();
1018 request_headers_bytes_sent_ = 0; 1016 request_headers_bytes_sent_ = 0;
1019 header_buf_len_ = 0; 1017 header_buf_len_ = 0;
1020 header_buf_body_offset_ = 0; 1018 header_buf_body_offset_ = 0;
1021 establishing_tunnel_ = false; 1019 establishing_tunnel_ = false;
1022 return OK; 1020 return OK;
1023 1021
1024 // We aren't able to CONNECT to the remote host through the proxy. We 1022 // We aren't able to CONNECT to the remote host through the proxy. We
1025 // need to be very suspicious about the response because an active network 1023 // need to be very suspicious about the response because an active network
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 if (request_->load_flags & LOAD_IGNORE_CERT_AUTHORITY_INVALID) 1134 if (request_->load_flags & LOAD_IGNORE_CERT_AUTHORITY_INVALID)
1137 error = OK; 1135 error = OK;
1138 break; 1136 break;
1139 } 1137 }
1140 } 1138 }
1141 1139
1142 if (error != OK) { 1140 if (error != OK) {
1143 SSLClientSocket* ssl_socket = 1141 SSLClientSocket* ssl_socket =
1144 reinterpret_cast<SSLClientSocket*>(connection_.socket()); 1142 reinterpret_cast<SSLClientSocket*>(connection_.socket());
1145 ssl_socket->GetSSLInfo(&response_.ssl_info); 1143 ssl_socket->GetSSLInfo(&response_.ssl_info);
1144
1145 // Add the bad certificate to the set of allowed certificates in the
1146 // SSL info object. This data structure will be consulted after calling
1147 // RestartIgnoringLastError(). And the user will be asked interactively
1148 // before RestartIgnoringLastError() is ever called.
1149 ssl_config_.allowed_bad_certs_.insert(response_.ssl_info.cert);
1146 } 1150 }
1147 return error; 1151 return error;
1148 } 1152 }
1149 1153
1150 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) { 1154 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) {
1151 switch (error) { 1155 switch (error) {
1152 case ERR_SSL_PROTOCOL_ERROR: 1156 case ERR_SSL_PROTOCOL_ERROR:
1153 case ERR_SSL_VERSION_OR_CIPHER_MISMATCH: 1157 case ERR_SSL_VERSION_OR_CIPHER_MISMATCH:
1154 if (ssl_config_.tls1_enabled) { 1158 if (ssl_config_.tls1_enabled) {
1155 // This could be a TLS-intolerant server or an SSL 3.0 server that 1159 // This could be a TLS-intolerant server or an SSL 3.0 server that
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
1517 if (target == HttpAuth::AUTH_PROXY) { 1521 if (target == HttpAuth::AUTH_PROXY) {
1518 auth_info->host = ASCIIToWide(proxy_info_.proxy_server().host_and_port()); 1522 auth_info->host = ASCIIToWide(proxy_info_.proxy_server().host_and_port());
1519 } else { 1523 } else {
1520 DCHECK(target == HttpAuth::AUTH_SERVER); 1524 DCHECK(target == HttpAuth::AUTH_SERVER);
1521 auth_info->host = ASCIIToWide(request_->url.host()); 1525 auth_info->host = ASCIIToWide(request_->url.host());
1522 } 1526 }
1523 response_.auth_challenge = auth_info; 1527 response_.auth_challenge = auth_info;
1524 } 1528 }
1525 1529
1526 } // namespace net 1530 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698