OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <set> | 7 #include <set> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 } else { | 150 } else { |
151 if (stream_->IsResponseBodyComplete()) { | 151 if (stream_->IsResponseBodyComplete()) { |
152 // If the response body is complete, we can just reuse the socket. | 152 // If the response body is complete, we can just reuse the socket. |
153 stream_->Close(false /* reusable */); | 153 stream_->Close(false /* reusable */); |
154 } else if (stream_->IsSpdyHttpStream()) { | 154 } else if (stream_->IsSpdyHttpStream()) { |
155 // Doesn't really matter for SpdyHttpStream. Just close it. | 155 // Doesn't really matter for SpdyHttpStream. Just close it. |
156 stream_->Close(true /* not reusable */); | 156 stream_->Close(true /* not reusable */); |
157 } else { | 157 } else { |
158 // Otherwise, we try to drain the response body. | 158 // Otherwise, we try to drain the response body. |
159 HttpStreamBase* stream = stream_.release(); | 159 HttpStreamBase* stream = stream_.release(); |
160 stream->Drain(session_); | 160 stream->Drain(session_.get()); |
161 } | 161 } |
162 } | 162 } |
163 } | 163 } |
164 } | 164 } |
165 | 165 |
166 int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info, | 166 int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info, |
167 const CompletionCallback& callback, | 167 const CompletionCallback& callback, |
168 const BoundNetLog& net_log) { | 168 const BoundNetLog& net_log) { |
169 SIMPLE_STATS_COUNTER("HttpNetworkTransaction.Count"); | 169 SIMPLE_STATS_COUNTER("HttpNetworkTransaction.Count"); |
170 | 170 |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 read_buf_len_ = buf_len; | 355 read_buf_len_ = buf_len; |
356 | 356 |
357 next_state_ = next_state; | 357 next_state_ = next_state; |
358 int rv = DoLoop(OK); | 358 int rv = DoLoop(OK); |
359 if (rv == ERR_IO_PENDING) | 359 if (rv == ERR_IO_PENDING) |
360 callback_ = callback; | 360 callback_ = callback; |
361 return rv; | 361 return rv; |
362 } | 362 } |
363 | 363 |
364 const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const { | 364 const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const { |
365 return ((headers_valid_ && response_.headers) || response_.ssl_info.cert || | 365 return ((headers_valid_ && response_.headers.get()) || |
366 response_.cert_request_info) ? &response_ : NULL; | 366 response_.ssl_info.cert.get() || response_.cert_request_info.get()) |
| 367 ? &response_ |
| 368 : NULL; |
367 } | 369 } |
368 | 370 |
369 LoadState HttpNetworkTransaction::GetLoadState() const { | 371 LoadState HttpNetworkTransaction::GetLoadState() const { |
370 // TODO(wtc): Define a new LoadState value for the | 372 // TODO(wtc): Define a new LoadState value for the |
371 // STATE_INIT_CONNECTION_COMPLETE state, which delays the HTTP request. | 373 // STATE_INIT_CONNECTION_COMPLETE state, which delays the HTTP request. |
372 switch (next_state_) { | 374 switch (next_state_) { |
373 case STATE_CREATE_STREAM_COMPLETE: | 375 case STATE_CREATE_STREAM_COMPLETE: |
374 return stream_request_->GetLoadState(); | 376 return stream_request_->GetLoadState(); |
375 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE: | 377 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE: |
376 case STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE: | 378 case STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE: |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 next_state_ = STATE_READ_HEADERS; | 836 next_state_ = STATE_READ_HEADERS; |
835 return OK; | 837 return OK; |
836 } | 838 } |
837 | 839 |
838 int HttpNetworkTransaction::DoReadHeaders() { | 840 int HttpNetworkTransaction::DoReadHeaders() { |
839 next_state_ = STATE_READ_HEADERS_COMPLETE; | 841 next_state_ = STATE_READ_HEADERS_COMPLETE; |
840 return stream_->ReadResponseHeaders(io_callback_); | 842 return stream_->ReadResponseHeaders(io_callback_); |
841 } | 843 } |
842 | 844 |
843 int HttpNetworkTransaction::HandleConnectionClosedBeforeEndOfHeaders() { | 845 int HttpNetworkTransaction::HandleConnectionClosedBeforeEndOfHeaders() { |
844 if (!response_.headers && !stream_->IsConnectionReused()) { | 846 if (!response_.headers.get() && !stream_->IsConnectionReused()) { |
845 // The connection was closed before any data was sent. Likely an error | 847 // The connection was closed before any data was sent. Likely an error |
846 // rather than empty HTTP/0.9 response. | 848 // rather than empty HTTP/0.9 response. |
847 return ERR_EMPTY_RESPONSE; | 849 return ERR_EMPTY_RESPONSE; |
848 } | 850 } |
849 | 851 |
850 return OK; | 852 return OK; |
851 } | 853 } |
852 | 854 |
853 int HttpNetworkTransaction::DoReadHeadersComplete(int result) { | 855 int HttpNetworkTransaction::DoReadHeadersComplete(int result) { |
854 // We can get a certificate error or ERR_SSL_CLIENT_AUTH_CERT_NEEDED here | 856 // We can get a certificate error or ERR_SSL_CLIENT_AUTH_CERT_NEEDED here |
855 // due to SSL renegotiation. | 857 // due to SSL renegotiation. |
856 if (IsCertificateError(result)) { | 858 if (IsCertificateError(result)) { |
857 // We don't handle a certificate error during SSL renegotiation, so we | 859 // We don't handle a certificate error during SSL renegotiation, so we |
858 // have to return an error that's not in the certificate error range | 860 // have to return an error that's not in the certificate error range |
859 // (-2xx). | 861 // (-2xx). |
860 LOG(ERROR) << "Got a server certificate with error " << result | 862 LOG(ERROR) << "Got a server certificate with error " << result |
861 << " during SSL renegotiation"; | 863 << " during SSL renegotiation"; |
862 result = ERR_CERT_ERROR_IN_SSL_RENEGOTIATION; | 864 result = ERR_CERT_ERROR_IN_SSL_RENEGOTIATION; |
863 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 865 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
864 // TODO(wtc): Need a test case for this code path! | 866 // TODO(wtc): Need a test case for this code path! |
865 DCHECK(stream_.get()); | 867 DCHECK(stream_.get()); |
866 DCHECK(is_https_request()); | 868 DCHECK(is_https_request()); |
867 response_.cert_request_info = new SSLCertRequestInfo; | 869 response_.cert_request_info = new SSLCertRequestInfo; |
868 stream_->GetSSLCertRequestInfo(response_.cert_request_info); | 870 stream_->GetSSLCertRequestInfo(response_.cert_request_info.get()); |
869 result = HandleCertificateRequest(result); | 871 result = HandleCertificateRequest(result); |
870 if (result == OK) | 872 if (result == OK) |
871 return result; | 873 return result; |
872 } | 874 } |
873 | 875 |
874 if (result < 0 && result != ERR_CONNECTION_CLOSED) | 876 if (result < 0 && result != ERR_CONNECTION_CLOSED) |
875 return HandleIOError(result); | 877 return HandleIOError(result); |
876 | 878 |
877 if (result == ERR_CONNECTION_CLOSED && ShouldResendRequest(result)) { | 879 if (result == ERR_CONNECTION_CLOSED && ShouldResendRequest(result)) { |
878 ResetConnectionAndRequestForResend(); | 880 ResetConnectionAndRequestForResend(); |
879 return OK; | 881 return OK; |
880 } | 882 } |
881 | 883 |
882 // After we call RestartWithAuth a new response_time will be recorded, and | 884 // After we call RestartWithAuth a new response_time will be recorded, and |
883 // we need to be cautious about incorrectly logging the duration across the | 885 // we need to be cautious about incorrectly logging the duration across the |
884 // authentication activity. | 886 // authentication activity. |
885 if (result == OK) | 887 if (result == OK) |
886 LogTransactionConnectedMetrics(); | 888 LogTransactionConnectedMetrics(); |
887 | 889 |
888 if (result == ERR_CONNECTION_CLOSED) { | 890 if (result == ERR_CONNECTION_CLOSED) { |
889 // For now, if we get at least some data, we do the best we can to make | 891 // For now, if we get at least some data, we do the best we can to make |
890 // sense of it and send it back up the stack. | 892 // sense of it and send it back up the stack. |
891 int rv = HandleConnectionClosedBeforeEndOfHeaders(); | 893 int rv = HandleConnectionClosedBeforeEndOfHeaders(); |
892 if (rv != OK) | 894 if (rv != OK) |
893 return rv; | 895 return rv; |
894 } | 896 } |
895 DCHECK(response_.headers); | 897 DCHECK(response_.headers.get()); |
896 | 898 |
897 // Server-induced fallback is supported only if this is a PAC configured | 899 // Server-induced fallback is supported only if this is a PAC configured |
898 // proxy. See: http://crbug.com/143712 | 900 // proxy. See: http://crbug.com/143712 |
899 if (response_.was_fetched_via_proxy && proxy_info_.did_use_pac_script() && | 901 if (response_.was_fetched_via_proxy && proxy_info_.did_use_pac_script() && |
900 response_.headers != NULL) { | 902 response_.headers.get() != NULL) { |
901 bool should_fallback = | 903 bool should_fallback = |
902 response_.headers->HasHeaderValue("connection", "proxy-bypass"); | 904 response_.headers->HasHeaderValue("connection", "proxy-bypass"); |
903 // Additionally, fallback if a 500 is returned via the data reduction proxy. | 905 // Additionally, fallback if a 500 is returned via the data reduction proxy. |
904 // This is conservative, as the 500 might have been generated by the origin, | 906 // This is conservative, as the 500 might have been generated by the origin, |
905 // and not the proxy. | 907 // and not the proxy. |
906 #if defined(SPDY_PROXY_AUTH_ORIGIN) | 908 #if defined(SPDY_PROXY_AUTH_ORIGIN) |
907 if (!should_fallback) { | 909 if (!should_fallback) { |
908 should_fallback = | 910 should_fallback = |
909 response_.headers->response_code() == HTTP_INTERNAL_SERVER_ERROR && | 911 response_.headers->response_code() == HTTP_INTERNAL_SERVER_ERROR && |
910 proxy_info_.proxy_server().host_port_pair().Equals( | 912 proxy_info_.proxy_server().host_port_pair().Equals( |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 if (response_.headers->response_code() / 100 == 1) { | 953 if (response_.headers->response_code() / 100 == 1) { |
952 response_.headers = new HttpResponseHeaders(std::string()); | 954 response_.headers = new HttpResponseHeaders(std::string()); |
953 next_state_ = STATE_READ_HEADERS; | 955 next_state_ = STATE_READ_HEADERS; |
954 return OK; | 956 return OK; |
955 } | 957 } |
956 | 958 |
957 HostPortPair endpoint = HostPortPair(request_->url.HostNoBrackets(), | 959 HostPortPair endpoint = HostPortPair(request_->url.HostNoBrackets(), |
958 request_->url.EffectiveIntPort()); | 960 request_->url.EffectiveIntPort()); |
959 ProcessAlternateProtocol(session_->http_stream_factory(), | 961 ProcessAlternateProtocol(session_->http_stream_factory(), |
960 session_->http_server_properties(), | 962 session_->http_server_properties(), |
961 *response_.headers, | 963 *response_.headers.get(), |
962 endpoint); | 964 endpoint); |
963 | 965 |
964 int rv = HandleAuthChallenge(); | 966 int rv = HandleAuthChallenge(); |
965 if (rv != OK) | 967 if (rv != OK) |
966 return rv; | 968 return rv; |
967 | 969 |
968 if (is_https_request()) | 970 if (is_https_request()) |
969 stream_->GetSSLInfo(&response_.ssl_info); | 971 stream_->GetSSLInfo(&response_.ssl_info); |
970 | 972 |
971 headers_valid_ = true; | 973 headers_valid_ = true; |
972 return OK; | 974 return OK; |
973 } | 975 } |
974 | 976 |
975 int HttpNetworkTransaction::DoReadBody() { | 977 int HttpNetworkTransaction::DoReadBody() { |
976 DCHECK(read_buf_); | 978 DCHECK(read_buf_.get()); |
977 DCHECK_GT(read_buf_len_, 0); | 979 DCHECK_GT(read_buf_len_, 0); |
978 DCHECK(stream_ != NULL); | 980 DCHECK(stream_ != NULL); |
979 | 981 |
980 next_state_ = STATE_READ_BODY_COMPLETE; | 982 next_state_ = STATE_READ_BODY_COMPLETE; |
981 return stream_->ReadResponseBody(read_buf_, read_buf_len_, io_callback_); | 983 return stream_->ReadResponseBody( |
| 984 read_buf_.get(), read_buf_len_, io_callback_); |
982 } | 985 } |
983 | 986 |
984 int HttpNetworkTransaction::DoReadBodyComplete(int result) { | 987 int HttpNetworkTransaction::DoReadBodyComplete(int result) { |
985 // We are done with the Read call. | 988 // We are done with the Read call. |
986 bool done = false; | 989 bool done = false; |
987 if (result <= 0) { | 990 if (result <= 0) { |
988 DCHECK_NE(ERR_IO_PENDING, result); | 991 DCHECK_NE(ERR_IO_PENDING, result); |
989 done = true; | 992 done = true; |
990 } | 993 } |
991 | 994 |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1157 // automatically. | 1160 // automatically. |
1158 scoped_refptr<X509Certificate> client_cert; | 1161 scoped_refptr<X509Certificate> client_cert; |
1159 bool found_cached_cert = session_->ssl_client_auth_cache()->Lookup( | 1162 bool found_cached_cert = session_->ssl_client_auth_cache()->Lookup( |
1160 response_.cert_request_info->host_and_port, &client_cert); | 1163 response_.cert_request_info->host_and_port, &client_cert); |
1161 if (!found_cached_cert) | 1164 if (!found_cached_cert) |
1162 return error; | 1165 return error; |
1163 | 1166 |
1164 // Check that the certificate selected is still a certificate the server | 1167 // Check that the certificate selected is still a certificate the server |
1165 // is likely to accept, based on the criteria supplied in the | 1168 // is likely to accept, based on the criteria supplied in the |
1166 // CertificateRequest message. | 1169 // CertificateRequest message. |
1167 if (client_cert) { | 1170 if (client_cert.get()) { |
1168 const std::vector<std::string>& cert_authorities = | 1171 const std::vector<std::string>& cert_authorities = |
1169 response_.cert_request_info->cert_authorities; | 1172 response_.cert_request_info->cert_authorities; |
1170 | 1173 |
1171 bool cert_still_valid = cert_authorities.empty() || | 1174 bool cert_still_valid = cert_authorities.empty() || |
1172 client_cert->IsIssuedByEncoded(cert_authorities); | 1175 client_cert->IsIssuedByEncoded(cert_authorities); |
1173 if (!cert_still_valid) | 1176 if (!cert_still_valid) |
1174 return error; | 1177 return error; |
1175 } | 1178 } |
1176 | 1179 |
1177 // TODO(davidben): Add a unit test which covers this path; we need to be | 1180 // TODO(davidben): Add a unit test which covers this path; we need to be |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1315 pending_auth_target_ = HttpAuth::AUTH_NONE; | 1318 pending_auth_target_ = HttpAuth::AUTH_NONE; |
1316 read_buf_ = NULL; | 1319 read_buf_ = NULL; |
1317 read_buf_len_ = 0; | 1320 read_buf_len_ = 0; |
1318 headers_valid_ = false; | 1321 headers_valid_ = false; |
1319 request_headers_.Clear(); | 1322 request_headers_.Clear(); |
1320 response_ = HttpResponseInfo(); | 1323 response_ = HttpResponseInfo(); |
1321 establishing_tunnel_ = false; | 1324 establishing_tunnel_ = false; |
1322 } | 1325 } |
1323 | 1326 |
1324 HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const { | 1327 HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const { |
1325 return response_.headers; | 1328 return response_.headers.get(); |
1326 } | 1329 } |
1327 | 1330 |
1328 bool HttpNetworkTransaction::ShouldResendRequest(int error) const { | 1331 bool HttpNetworkTransaction::ShouldResendRequest(int error) const { |
1329 bool connection_is_proven = stream_->IsConnectionReused(); | 1332 bool connection_is_proven = stream_->IsConnectionReused(); |
1330 bool has_received_headers = GetResponseHeaders() != NULL; | 1333 bool has_received_headers = GetResponseHeaders() != NULL; |
1331 | 1334 |
1332 // NOTE: we resend a request only if we reused a keep-alive connection. | 1335 // NOTE: we resend a request only if we reused a keep-alive connection. |
1333 // This automatically prevents an infinite resend loop because we'll run | 1336 // This automatically prevents an infinite resend loop because we'll run |
1334 // out of the cached keep-alive connections eventually. | 1337 // out of the cached keep-alive connections eventually. |
1335 if (connection_is_proven && !has_received_headers) | 1338 if (connection_is_proven && !has_received_headers) |
(...skipping 18 matching lines...) Expand all Loading... |
1354 return !is_https_request() && | 1357 return !is_https_request() && |
1355 (proxy_info_.is_https() || proxy_info_.is_http()); | 1358 (proxy_info_.is_https() || proxy_info_.is_http()); |
1356 } | 1359 } |
1357 | 1360 |
1358 bool HttpNetworkTransaction::ShouldApplyServerAuth() const { | 1361 bool HttpNetworkTransaction::ShouldApplyServerAuth() const { |
1359 return !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA); | 1362 return !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA); |
1360 } | 1363 } |
1361 | 1364 |
1362 int HttpNetworkTransaction::HandleAuthChallenge() { | 1365 int HttpNetworkTransaction::HandleAuthChallenge() { |
1363 scoped_refptr<HttpResponseHeaders> headers(GetResponseHeaders()); | 1366 scoped_refptr<HttpResponseHeaders> headers(GetResponseHeaders()); |
1364 DCHECK(headers); | 1367 DCHECK(headers.get()); |
1365 | 1368 |
1366 int status = headers->response_code(); | 1369 int status = headers->response_code(); |
1367 if (status != HTTP_UNAUTHORIZED && | 1370 if (status != HTTP_UNAUTHORIZED && |
1368 status != HTTP_PROXY_AUTHENTICATION_REQUIRED) | 1371 status != HTTP_PROXY_AUTHENTICATION_REQUIRED) |
1369 return OK; | 1372 return OK; |
1370 HttpAuth::Target target = status == HTTP_PROXY_AUTHENTICATION_REQUIRED ? | 1373 HttpAuth::Target target = status == HTTP_PROXY_AUTHENTICATION_REQUIRED ? |
1371 HttpAuth::AUTH_PROXY : HttpAuth::AUTH_SERVER; | 1374 HttpAuth::AUTH_PROXY : HttpAuth::AUTH_SERVER; |
1372 if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct()) | 1375 if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct()) |
1373 return ERR_UNEXPECTED_PROXY_AUTH; | 1376 return ERR_UNEXPECTED_PROXY_AUTH; |
1374 | 1377 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1442 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, | 1445 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, |
1443 state); | 1446 state); |
1444 break; | 1447 break; |
1445 } | 1448 } |
1446 return description; | 1449 return description; |
1447 } | 1450 } |
1448 | 1451 |
1449 #undef STATE_CASE | 1452 #undef STATE_CASE |
1450 | 1453 |
1451 } // namespace net | 1454 } // namespace net |
OLD | NEW |