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 |