Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |