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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 #include "net/spdy/spdy_session_pool.h" | 60 #include "net/spdy/spdy_session_pool.h" |
61 #include "net/ssl/ssl_cert_request_info.h" | 61 #include "net/ssl/ssl_cert_request_info.h" |
62 #include "net/ssl/ssl_connection_status_flags.h" | 62 #include "net/ssl/ssl_connection_status_flags.h" |
63 #include "url/gurl.h" | 63 #include "url/gurl.h" |
64 | 64 |
65 #if defined(SPDY_PROXY_AUTH_ORIGIN) | 65 #if defined(SPDY_PROXY_AUTH_ORIGIN) |
66 #include <algorithm> | 66 #include <algorithm> |
67 #include "net/proxy/proxy_server.h" | 67 #include "net/proxy/proxy_server.h" |
68 #endif | 68 #endif |
69 | 69 |
70 | |
71 using base::Time; | 70 using base::Time; |
72 using base::TimeDelta; | 71 using base::TimeDelta; |
73 | 72 |
74 namespace net { | 73 namespace net { |
75 | 74 |
76 namespace { | 75 namespace { |
77 | 76 |
78 void ProcessAlternateProtocol( | 77 void ProcessAlternateProtocol( |
79 HttpStreamFactory* factory, | 78 HttpStreamFactory* factory, |
80 const base::WeakPtr<HttpServerProperties>& http_server_properties, | 79 const base::WeakPtr<HttpServerProperties>& http_server_properties, |
81 const HttpResponseHeaders& headers, | 80 const HttpResponseHeaders& headers, |
82 const HostPortPair& http_host_port_pair) { | 81 const HostPortPair& http_host_port_pair) { |
83 std::string alternate_protocol_str; | 82 std::string alternate_protocol_str; |
84 | 83 |
85 if (!headers.EnumerateHeader(NULL, kAlternateProtocolHeader, | 84 if (!headers.EnumerateHeader( |
86 &alternate_protocol_str)) { | 85 NULL, kAlternateProtocolHeader, &alternate_protocol_str)) { |
87 // Header is not present. | 86 // Header is not present. |
88 return; | 87 return; |
89 } | 88 } |
90 | 89 |
91 factory->ProcessAlternateProtocol(http_server_properties, | 90 factory->ProcessAlternateProtocol( |
92 alternate_protocol_str, | 91 http_server_properties, alternate_protocol_str, http_host_port_pair); |
93 http_host_port_pair); | |
94 } | 92 } |
95 | 93 |
96 // Returns true if |error| is a client certificate authentication error. | 94 // Returns true if |error| is a client certificate authentication error. |
97 bool IsClientCertificateError(int error) { | 95 bool IsClientCertificateError(int error) { |
98 switch (error) { | 96 switch (error) { |
99 case ERR_BAD_SSL_CLIENT_AUTH_CERT: | 97 case ERR_BAD_SSL_CLIENT_AUTH_CERT: |
100 case ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED: | 98 case ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED: |
101 case ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY: | 99 case ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY: |
102 case ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED: | 100 case ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED: |
103 return true; | 101 return true; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 } | 146 } |
149 proxy_ssl_config_ = server_ssl_config_; | 147 proxy_ssl_config_ = server_ssl_config_; |
150 } | 148 } |
151 | 149 |
152 HttpNetworkTransaction::~HttpNetworkTransaction() { | 150 HttpNetworkTransaction::~HttpNetworkTransaction() { |
153 if (stream_.get()) { | 151 if (stream_.get()) { |
154 HttpResponseHeaders* headers = GetResponseHeaders(); | 152 HttpResponseHeaders* headers = GetResponseHeaders(); |
155 // TODO(mbelshe): The stream_ should be able to compute whether or not the | 153 // TODO(mbelshe): The stream_ should be able to compute whether or not the |
156 // stream should be kept alive. No reason to compute here | 154 // stream should be kept alive. No reason to compute here |
157 // and pass it in. | 155 // and pass it in. |
158 bool try_to_keep_alive = | 156 bool try_to_keep_alive = next_state_ == STATE_NONE && |
159 next_state_ == STATE_NONE && | 157 stream_->CanFindEndOfResponse() && |
160 stream_->CanFindEndOfResponse() && | 158 (!headers || headers->IsKeepAlive()); |
161 (!headers || headers->IsKeepAlive()); | |
162 if (!try_to_keep_alive) { | 159 if (!try_to_keep_alive) { |
163 stream_->Close(true /* not reusable */); | 160 stream_->Close(true /* not reusable */); |
164 } else { | 161 } else { |
165 if (stream_->IsResponseBodyComplete()) { | 162 if (stream_->IsResponseBodyComplete()) { |
166 // If the response body is complete, we can just reuse the socket. | 163 // If the response body is complete, we can just reuse the socket. |
167 stream_->Close(false /* reusable */); | 164 stream_->Close(false /* reusable */); |
168 } else if (stream_->IsSpdyHttpStream()) { | 165 } else if (stream_->IsSpdyHttpStream()) { |
169 // Doesn't really matter for SpdyHttpStream. Just close it. | 166 // Doesn't really matter for SpdyHttpStream. Just close it. |
170 stream_->Close(true /* not reusable */); | 167 stream_->Close(true /* not reusable */); |
171 } else { | 168 } else { |
(...skipping 17 matching lines...) Expand all Loading... |
189 request_ = request_info; | 186 request_ = request_info; |
190 start_time_ = base::Time::Now(); | 187 start_time_ = base::Time::Now(); |
191 | 188 |
192 if (request_->load_flags & LOAD_DISABLE_CERT_REVOCATION_CHECKING) { | 189 if (request_->load_flags & LOAD_DISABLE_CERT_REVOCATION_CHECKING) { |
193 server_ssl_config_.rev_checking_enabled = false; | 190 server_ssl_config_.rev_checking_enabled = false; |
194 proxy_ssl_config_.rev_checking_enabled = false; | 191 proxy_ssl_config_.rev_checking_enabled = false; |
195 } | 192 } |
196 | 193 |
197 // Channel ID is disabled if privacy mode is enabled for this request. | 194 // Channel ID is disabled if privacy mode is enabled for this request. |
198 bool channel_id_enabled = server_ssl_config_.channel_id_enabled && | 195 bool channel_id_enabled = server_ssl_config_.channel_id_enabled && |
199 (request_->privacy_mode == PRIVACY_MODE_DISABLED); | 196 (request_->privacy_mode == PRIVACY_MODE_DISABLED); |
200 server_ssl_config_.channel_id_enabled = channel_id_enabled; | 197 server_ssl_config_.channel_id_enabled = channel_id_enabled; |
201 | 198 |
202 next_state_ = STATE_NOTIFY_BEFORE_CREATE_STREAM; | 199 next_state_ = STATE_NOTIFY_BEFORE_CREATE_STREAM; |
203 int rv = DoLoop(OK); | 200 int rv = DoLoop(OK); |
204 if (rv == ERR_IO_PENDING) | 201 if (rv == ERR_IO_PENDING) |
205 callback_ = callback; | 202 callback_ = callback; |
206 return rv; | 203 return rv; |
207 } | 204 } |
208 | 205 |
209 int HttpNetworkTransaction::RestartIgnoringLastError( | 206 int HttpNetworkTransaction::RestartIgnoringLastError( |
210 const CompletionCallback& callback) { | 207 const CompletionCallback& callback) { |
211 DCHECK(!stream_.get()); | 208 DCHECK(!stream_.get()); |
212 DCHECK(!stream_request_.get()); | 209 DCHECK(!stream_request_.get()); |
213 DCHECK_EQ(STATE_NONE, next_state_); | 210 DCHECK_EQ(STATE_NONE, next_state_); |
214 | 211 |
215 next_state_ = STATE_CREATE_STREAM; | 212 next_state_ = STATE_CREATE_STREAM; |
216 | 213 |
217 int rv = DoLoop(OK); | 214 int rv = DoLoop(OK); |
218 if (rv == ERR_IO_PENDING) | 215 if (rv == ERR_IO_PENDING) |
219 callback_ = callback; | 216 callback_ = callback; |
220 return rv; | 217 return rv; |
221 } | 218 } |
222 | 219 |
223 int HttpNetworkTransaction::RestartWithCertificate( | 220 int HttpNetworkTransaction::RestartWithCertificate( |
224 X509Certificate* client_cert, const CompletionCallback& callback) { | 221 X509Certificate* client_cert, |
| 222 const CompletionCallback& callback) { |
225 // In HandleCertificateRequest(), we always tear down existing stream | 223 // In HandleCertificateRequest(), we always tear down existing stream |
226 // requests to force a new connection. So we shouldn't have one here. | 224 // requests to force a new connection. So we shouldn't have one here. |
227 DCHECK(!stream_request_.get()); | 225 DCHECK(!stream_request_.get()); |
228 DCHECK(!stream_.get()); | 226 DCHECK(!stream_.get()); |
229 DCHECK_EQ(STATE_NONE, next_state_); | 227 DCHECK_EQ(STATE_NONE, next_state_); |
230 | 228 |
231 SSLConfig* ssl_config = response_.cert_request_info->is_proxy ? | 229 SSLConfig* ssl_config = response_.cert_request_info->is_proxy |
232 &proxy_ssl_config_ : &server_ssl_config_; | 230 ? &proxy_ssl_config_ |
| 231 : &server_ssl_config_; |
233 ssl_config->send_client_cert = true; | 232 ssl_config->send_client_cert = true; |
234 ssl_config->client_cert = client_cert; | 233 ssl_config->client_cert = client_cert; |
235 session_->ssl_client_auth_cache()->Add( | 234 session_->ssl_client_auth_cache()->Add( |
236 response_.cert_request_info->host_and_port, client_cert); | 235 response_.cert_request_info->host_and_port, client_cert); |
237 // Reset the other member variables. | 236 // Reset the other member variables. |
238 // Note: this is necessary only with SSL renegotiation. | 237 // Note: this is necessary only with SSL renegotiation. |
239 ResetStateForRestart(); | 238 ResetStateForRestart(); |
240 next_state_ = STATE_CREATE_STREAM; | 239 next_state_ = STATE_CREATE_STREAM; |
241 int rv = DoLoop(OK); | 240 int rv = DoLoop(OK); |
242 if (rv == ERR_IO_PENDING) | 241 if (rv == ERR_IO_PENDING) |
243 callback_ = callback; | 242 callback_ = callback; |
244 return rv; | 243 return rv; |
245 } | 244 } |
246 | 245 |
247 int HttpNetworkTransaction::RestartWithAuth( | 246 int HttpNetworkTransaction::RestartWithAuth( |
248 const AuthCredentials& credentials, const CompletionCallback& callback) { | 247 const AuthCredentials& credentials, |
| 248 const CompletionCallback& callback) { |
249 HttpAuth::Target target = pending_auth_target_; | 249 HttpAuth::Target target = pending_auth_target_; |
250 if (target == HttpAuth::AUTH_NONE) { | 250 if (target == HttpAuth::AUTH_NONE) { |
251 NOTREACHED(); | 251 NOTREACHED(); |
252 return ERR_UNEXPECTED; | 252 return ERR_UNEXPECTED; |
253 } | 253 } |
254 pending_auth_target_ = HttpAuth::AUTH_NONE; | 254 pending_auth_target_ = HttpAuth::AUTH_NONE; |
255 | 255 |
256 auth_controllers_[target]->ResetAuth(credentials); | 256 auth_controllers_[target]->ResetAuth(credentials); |
257 | 257 |
258 DCHECK(callback_.is_null()); | 258 DCHECK(callback_.is_null()); |
(...skipping 20 matching lines...) Expand all Loading... |
279 return rv; | 279 return rv; |
280 } | 280 } |
281 | 281 |
282 void HttpNetworkTransaction::PrepareForAuthRestart(HttpAuth::Target target) { | 282 void HttpNetworkTransaction::PrepareForAuthRestart(HttpAuth::Target target) { |
283 DCHECK(HaveAuth(target)); | 283 DCHECK(HaveAuth(target)); |
284 DCHECK(!stream_request_.get()); | 284 DCHECK(!stream_request_.get()); |
285 | 285 |
286 bool keep_alive = false; | 286 bool keep_alive = false; |
287 // Even if the server says the connection is keep-alive, we have to be | 287 // Even if the server says the connection is keep-alive, we have to be |
288 // able to find the end of each response in order to reuse the connection. | 288 // able to find the end of each response in order to reuse the connection. |
289 if (GetResponseHeaders()->IsKeepAlive() && | 289 if (GetResponseHeaders()->IsKeepAlive() && stream_->CanFindEndOfResponse()) { |
290 stream_->CanFindEndOfResponse()) { | |
291 // If the response body hasn't been completely read, we need to drain | 290 // If the response body hasn't been completely read, we need to drain |
292 // it first. | 291 // it first. |
293 if (!stream_->IsResponseBodyComplete()) { | 292 if (!stream_->IsResponseBodyComplete()) { |
294 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART; | 293 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART; |
295 read_buf_ = new IOBuffer(kDrainBodyBufferSize); // A bit bucket. | 294 read_buf_ = new IOBuffer(kDrainBodyBufferSize); // A bit bucket. |
296 read_buf_len_ = kDrainBodyBufferSize; | 295 read_buf_len_ = kDrainBodyBufferSize; |
297 return; | 296 return; |
298 } | 297 } |
299 keep_alive = true; | 298 keep_alive = true; |
300 } | 299 } |
(...skipping 30 matching lines...) Expand all Loading... |
331 } | 330 } |
332 stream_.reset(new_stream); | 331 stream_.reset(new_stream); |
333 } | 332 } |
334 | 333 |
335 // Reset the other member variables. | 334 // Reset the other member variables. |
336 ResetStateForAuthRestart(); | 335 ResetStateForAuthRestart(); |
337 } | 336 } |
338 | 337 |
339 bool HttpNetworkTransaction::IsReadyToRestartForAuth() { | 338 bool HttpNetworkTransaction::IsReadyToRestartForAuth() { |
340 return pending_auth_target_ != HttpAuth::AUTH_NONE && | 339 return pending_auth_target_ != HttpAuth::AUTH_NONE && |
341 HaveAuth(pending_auth_target_); | 340 HaveAuth(pending_auth_target_); |
342 } | 341 } |
343 | 342 |
344 int HttpNetworkTransaction::Read(IOBuffer* buf, int buf_len, | 343 int HttpNetworkTransaction::Read(IOBuffer* buf, |
| 344 int buf_len, |
345 const CompletionCallback& callback) { | 345 const CompletionCallback& callback) { |
346 DCHECK(buf); | 346 DCHECK(buf); |
347 DCHECK_LT(0, buf_len); | 347 DCHECK_LT(0, buf_len); |
348 | 348 |
349 State next_state = STATE_NONE; | 349 State next_state = STATE_NONE; |
350 | 350 |
351 scoped_refptr<HttpResponseHeaders> headers(GetResponseHeaders()); | 351 scoped_refptr<HttpResponseHeaders> headers(GetResponseHeaders()); |
352 if (headers_valid_ && headers.get() && stream_request_.get()) { | 352 if (headers_valid_ && headers.get() && stream_request_.get()) { |
353 // We're trying to read the body of the response but we're still trying | 353 // We're trying to read the body of the response but we're still trying |
354 // to establish an SSL tunnel through an HTTP proxy. We can't read these | 354 // to establish an SSL tunnel through an HTTP proxy. We can't read these |
(...skipping 18 matching lines...) Expand all Loading... |
373 read_buf_ = buf; | 373 read_buf_ = buf; |
374 read_buf_len_ = buf_len; | 374 read_buf_len_ = buf_len; |
375 | 375 |
376 next_state_ = next_state; | 376 next_state_ = next_state; |
377 int rv = DoLoop(OK); | 377 int rv = DoLoop(OK); |
378 if (rv == ERR_IO_PENDING) | 378 if (rv == ERR_IO_PENDING) |
379 callback_ = callback; | 379 callback_ = callback; |
380 return rv; | 380 return rv; |
381 } | 381 } |
382 | 382 |
383 void HttpNetworkTransaction::StopCaching() {} | 383 void HttpNetworkTransaction::StopCaching() { |
| 384 } |
384 | 385 |
385 bool HttpNetworkTransaction::GetFullRequestHeaders( | 386 bool HttpNetworkTransaction::GetFullRequestHeaders( |
386 HttpRequestHeaders* headers) const { | 387 HttpRequestHeaders* headers) const { |
387 // TODO(ttuttle): Make sure we've populated request_headers_. | 388 // TODO(ttuttle): Make sure we've populated request_headers_. |
388 *headers = request_headers_; | 389 *headers = request_headers_; |
389 return true; | 390 return true; |
390 } | 391 } |
391 | 392 |
392 int64 HttpNetworkTransaction::GetTotalReceivedBytes() const { | 393 int64 HttpNetworkTransaction::GetTotalReceivedBytes() const { |
393 int64 total_received_bytes = total_received_bytes_; | 394 int64 total_received_bytes = total_received_bytes_; |
394 if (stream_) | 395 if (stream_) |
395 total_received_bytes += stream_->GetTotalReceivedBytes(); | 396 total_received_bytes += stream_->GetTotalReceivedBytes(); |
396 return total_received_bytes; | 397 return total_received_bytes; |
397 } | 398 } |
398 | 399 |
399 void HttpNetworkTransaction::DoneReading() {} | 400 void HttpNetworkTransaction::DoneReading() { |
| 401 } |
400 | 402 |
401 const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const { | 403 const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const { |
402 return ((headers_valid_ && response_.headers.get()) || | 404 return ((headers_valid_ && response_.headers.get()) || |
403 response_.ssl_info.cert.get() || response_.cert_request_info.get()) | 405 response_.ssl_info.cert.get() || response_.cert_request_info.get()) |
404 ? &response_ | 406 ? &response_ |
405 : NULL; | 407 : NULL; |
406 } | 408 } |
407 | 409 |
408 LoadState HttpNetworkTransaction::GetLoadState() const { | 410 LoadState HttpNetworkTransaction::GetLoadState() const { |
409 // TODO(wtc): Define a new LoadState value for the | 411 // TODO(wtc): Define a new LoadState value for the |
(...skipping 18 matching lines...) Expand all Loading... |
428 | 430 |
429 UploadProgress HttpNetworkTransaction::GetUploadProgress() const { | 431 UploadProgress HttpNetworkTransaction::GetUploadProgress() const { |
430 if (!stream_.get()) | 432 if (!stream_.get()) |
431 return UploadProgress(); | 433 return UploadProgress(); |
432 | 434 |
433 // TODO(bashi): This cast is temporary. Remove later. | 435 // TODO(bashi): This cast is temporary. Remove later. |
434 return static_cast<HttpStream*>(stream_.get())->GetUploadProgress(); | 436 return static_cast<HttpStream*>(stream_.get())->GetUploadProgress(); |
435 } | 437 } |
436 | 438 |
437 void HttpNetworkTransaction::SetQuicServerInfo( | 439 void HttpNetworkTransaction::SetQuicServerInfo( |
438 QuicServerInfo* quic_server_info) {} | 440 QuicServerInfo* quic_server_info) { |
| 441 } |
439 | 442 |
440 bool HttpNetworkTransaction::GetLoadTimingInfo( | 443 bool HttpNetworkTransaction::GetLoadTimingInfo( |
441 LoadTimingInfo* load_timing_info) const { | 444 LoadTimingInfo* load_timing_info) const { |
442 if (!stream_ || !stream_->GetLoadTimingInfo(load_timing_info)) | 445 if (!stream_ || !stream_->GetLoadTimingInfo(load_timing_info)) |
443 return false; | 446 return false; |
444 | 447 |
445 load_timing_info->proxy_resolve_start = | 448 load_timing_info->proxy_resolve_start = |
446 proxy_info_.proxy_resolve_start_time(); | 449 proxy_info_.proxy_resolve_start_time(); |
447 load_timing_info->proxy_resolve_end = proxy_info_.proxy_resolve_end_time(); | 450 load_timing_info->proxy_resolve_end = proxy_info_.proxy_resolve_end_time(); |
448 load_timing_info->send_start = send_start_time_; | 451 load_timing_info->send_start = send_start_time_; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 headers_valid_ = true; | 549 headers_valid_ = true; |
547 server_ssl_config_ = used_ssl_config; | 550 server_ssl_config_ = used_ssl_config; |
548 proxy_info_ = used_proxy_info; | 551 proxy_info_ = used_proxy_info; |
549 | 552 |
550 auth_controllers_[HttpAuth::AUTH_PROXY] = auth_controller; | 553 auth_controllers_[HttpAuth::AUTH_PROXY] = auth_controller; |
551 pending_auth_target_ = HttpAuth::AUTH_PROXY; | 554 pending_auth_target_ = HttpAuth::AUTH_PROXY; |
552 | 555 |
553 DoCallback(OK); | 556 DoCallback(OK); |
554 } | 557 } |
555 | 558 |
556 void HttpNetworkTransaction::OnNeedsClientAuth( | 559 void HttpNetworkTransaction::OnNeedsClientAuth(const SSLConfig& used_ssl_config, |
557 const SSLConfig& used_ssl_config, | 560 SSLCertRequestInfo* cert_info) { |
558 SSLCertRequestInfo* cert_info) { | |
559 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); | 561 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); |
560 | 562 |
561 server_ssl_config_ = used_ssl_config; | 563 server_ssl_config_ = used_ssl_config; |
562 response_.cert_request_info = cert_info; | 564 response_.cert_request_info = cert_info; |
563 OnIOComplete(ERR_SSL_CLIENT_AUTH_CERT_NEEDED); | 565 OnIOComplete(ERR_SSL_CLIENT_AUTH_CERT_NEEDED); |
564 } | 566 } |
565 | 567 |
566 void HttpNetworkTransaction::OnHttpsProxyTunnelResponse( | 568 void HttpNetworkTransaction::OnHttpsProxyTunnelResponse( |
567 const HttpResponseInfo& response_info, | 569 const HttpResponseInfo& response_info, |
568 const SSLConfig& used_ssl_config, | 570 const SSLConfig& used_ssl_config, |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 return OK; | 717 return OK; |
716 return ERR_IO_PENDING; | 718 return ERR_IO_PENDING; |
717 } | 719 } |
718 | 720 |
719 int HttpNetworkTransaction::DoCreateStream() { | 721 int HttpNetworkTransaction::DoCreateStream() { |
720 next_state_ = STATE_CREATE_STREAM_COMPLETE; | 722 next_state_ = STATE_CREATE_STREAM_COMPLETE; |
721 if (ForWebSocketHandshake()) { | 723 if (ForWebSocketHandshake()) { |
722 stream_request_.reset( | 724 stream_request_.reset( |
723 session_->http_stream_factory_for_websocket() | 725 session_->http_stream_factory_for_websocket() |
724 ->RequestWebSocketHandshakeStream( | 726 ->RequestWebSocketHandshakeStream( |
725 *request_, | 727 *request_, |
726 priority_, | 728 priority_, |
727 server_ssl_config_, | 729 server_ssl_config_, |
728 proxy_ssl_config_, | 730 proxy_ssl_config_, |
729 this, | 731 this, |
730 websocket_handshake_stream_base_create_helper_, | 732 websocket_handshake_stream_base_create_helper_, |
731 net_log_)); | 733 net_log_)); |
732 } else { | 734 } else { |
733 stream_request_.reset( | 735 stream_request_.reset( |
734 session_->http_stream_factory()->RequestStream( | 736 session_->http_stream_factory()->RequestStream(*request_, |
735 *request_, | 737 priority_, |
736 priority_, | 738 server_ssl_config_, |
737 server_ssl_config_, | 739 proxy_ssl_config_, |
738 proxy_ssl_config_, | 740 this, |
739 this, | 741 net_log_)); |
740 net_log_)); | |
741 } | 742 } |
742 DCHECK(stream_request_.get()); | 743 DCHECK(stream_request_.get()); |
743 return ERR_IO_PENDING; | 744 return ERR_IO_PENDING; |
744 } | 745 } |
745 | 746 |
746 int HttpNetworkTransaction::DoCreateStreamComplete(int result) { | 747 int HttpNetworkTransaction::DoCreateStreamComplete(int result) { |
747 if (result == OK) { | 748 if (result == OK) { |
748 next_state_ = STATE_INIT_STREAM; | 749 next_state_ = STATE_INIT_STREAM; |
749 DCHECK(stream_.get()); | 750 DCHECK(stream_.get()); |
750 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 751 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
(...skipping 21 matching lines...) Expand all Loading... |
772 | 773 |
773 int HttpNetworkTransaction::DoInitStreamComplete(int result) { | 774 int HttpNetworkTransaction::DoInitStreamComplete(int result) { |
774 if (result == OK) { | 775 if (result == OK) { |
775 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; | 776 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; |
776 } else { | 777 } else { |
777 if (result < 0) | 778 if (result < 0) |
778 result = HandleIOError(result); | 779 result = HandleIOError(result); |
779 | 780 |
780 // The stream initialization failed, so this stream will never be useful. | 781 // The stream initialization failed, so this stream will never be useful. |
781 if (stream_) | 782 if (stream_) |
782 total_received_bytes_ += stream_->GetTotalReceivedBytes(); | 783 total_received_bytes_ += stream_->GetTotalReceivedBytes(); |
783 stream_.reset(); | 784 stream_.reset(); |
784 } | 785 } |
785 | 786 |
786 return result; | 787 return result; |
787 } | 788 } |
788 | 789 |
789 int HttpNetworkTransaction::DoGenerateProxyAuthToken() { | 790 int HttpNetworkTransaction::DoGenerateProxyAuthToken() { |
790 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE; | 791 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE; |
791 if (!ShouldApplyProxyAuth()) | 792 if (!ShouldApplyProxyAuth()) |
792 return OK; | 793 return OK; |
793 HttpAuth::Target target = HttpAuth::AUTH_PROXY; | 794 HttpAuth::Target target = HttpAuth::AUTH_PROXY; |
794 if (!auth_controllers_[target].get()) | 795 if (!auth_controllers_[target].get()) |
795 auth_controllers_[target] = | 796 auth_controllers_[target] = |
796 new HttpAuthController(target, | 797 new HttpAuthController(target, |
797 AuthURL(target), | 798 AuthURL(target), |
798 session_->http_auth_cache(), | 799 session_->http_auth_cache(), |
799 session_->http_auth_handler_factory()); | 800 session_->http_auth_handler_factory()); |
800 return auth_controllers_[target]->MaybeGenerateAuthToken(request_, | 801 return auth_controllers_[target]->MaybeGenerateAuthToken( |
801 io_callback_, | 802 request_, io_callback_, net_log_); |
802 net_log_); | |
803 } | 803 } |
804 | 804 |
805 int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) { | 805 int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) { |
806 DCHECK_NE(ERR_IO_PENDING, rv); | 806 DCHECK_NE(ERR_IO_PENDING, rv); |
807 if (rv == OK) | 807 if (rv == OK) |
808 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN; | 808 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN; |
809 return rv; | 809 return rv; |
810 } | 810 } |
811 | 811 |
812 int HttpNetworkTransaction::DoGenerateServerAuthToken() { | 812 int HttpNetworkTransaction::DoGenerateServerAuthToken() { |
813 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE; | 813 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE; |
814 HttpAuth::Target target = HttpAuth::AUTH_SERVER; | 814 HttpAuth::Target target = HttpAuth::AUTH_SERVER; |
815 if (!auth_controllers_[target].get()) { | 815 if (!auth_controllers_[target].get()) { |
816 auth_controllers_[target] = | 816 auth_controllers_[target] = |
817 new HttpAuthController(target, | 817 new HttpAuthController(target, |
818 AuthURL(target), | 818 AuthURL(target), |
819 session_->http_auth_cache(), | 819 session_->http_auth_cache(), |
820 session_->http_auth_handler_factory()); | 820 session_->http_auth_handler_factory()); |
821 if (request_->load_flags & LOAD_DO_NOT_USE_EMBEDDED_IDENTITY) | 821 if (request_->load_flags & LOAD_DO_NOT_USE_EMBEDDED_IDENTITY) |
822 auth_controllers_[target]->DisableEmbeddedIdentity(); | 822 auth_controllers_[target]->DisableEmbeddedIdentity(); |
823 } | 823 } |
824 if (!ShouldApplyServerAuth()) | 824 if (!ShouldApplyServerAuth()) |
825 return OK; | 825 return OK; |
826 return auth_controllers_[target]->MaybeGenerateAuthToken(request_, | 826 return auth_controllers_[target]->MaybeGenerateAuthToken( |
827 io_callback_, | 827 request_, io_callback_, net_log_); |
828 net_log_); | |
829 } | 828 } |
830 | 829 |
831 int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) { | 830 int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) { |
832 DCHECK_NE(ERR_IO_PENDING, rv); | 831 DCHECK_NE(ERR_IO_PENDING, rv); |
833 if (rv == OK) | 832 if (rv == OK) |
834 next_state_ = STATE_INIT_REQUEST_BODY; | 833 next_state_ = STATE_INIT_REQUEST_BODY; |
835 return rv; | 834 return rv; |
836 } | 835 } |
837 | 836 |
838 void HttpNetworkTransaction::BuildRequestHeaders(bool using_proxy) { | 837 void HttpNetworkTransaction::BuildRequestHeaders(bool using_proxy) { |
839 request_headers_.SetHeader(HttpRequestHeaders::kHost, | 838 request_headers_.SetHeader(HttpRequestHeaders::kHost, |
840 GetHostAndOptionalPort(request_->url)); | 839 GetHostAndOptionalPort(request_->url)); |
841 | 840 |
842 // For compat with HTTP/1.0 servers and proxies: | 841 // For compat with HTTP/1.0 servers and proxies: |
843 if (using_proxy) { | 842 if (using_proxy) { |
844 request_headers_.SetHeader(HttpRequestHeaders::kProxyConnection, | 843 request_headers_.SetHeader(HttpRequestHeaders::kProxyConnection, |
845 "keep-alive"); | 844 "keep-alive"); |
846 } else { | 845 } else { |
847 request_headers_.SetHeader(HttpRequestHeaders::kConnection, "keep-alive"); | 846 request_headers_.SetHeader(HttpRequestHeaders::kConnection, "keep-alive"); |
848 } | 847 } |
849 | 848 |
850 // Add a content length header? | 849 // Add a content length header? |
851 if (request_->upload_data_stream) { | 850 if (request_->upload_data_stream) { |
852 if (request_->upload_data_stream->is_chunked()) { | 851 if (request_->upload_data_stream->is_chunked()) { |
853 request_headers_.SetHeader( | 852 request_headers_.SetHeader(HttpRequestHeaders::kTransferEncoding, |
854 HttpRequestHeaders::kTransferEncoding, "chunked"); | 853 "chunked"); |
855 } else { | 854 } else { |
856 request_headers_.SetHeader( | 855 request_headers_.SetHeader( |
857 HttpRequestHeaders::kContentLength, | 856 HttpRequestHeaders::kContentLength, |
858 base::Uint64ToString(request_->upload_data_stream->size())); | 857 base::Uint64ToString(request_->upload_data_stream->size())); |
859 } | 858 } |
860 } else if (request_->method == "POST" || request_->method == "PUT" || | 859 } else if (request_->method == "POST" || request_->method == "PUT" || |
861 request_->method == "HEAD") { | 860 request_->method == "HEAD") { |
862 // An empty POST/PUT request still needs a content length. As for HEAD, | 861 // An empty POST/PUT request still needs a content length. As for HEAD, |
863 // IE and Safari also add a content length header. Presumably it is to | 862 // IE and Safari also add a content length header. Presumably it is to |
864 // support sending a HEAD request to an URL that only expects to be sent a | 863 // support sending a HEAD request to an URL that only expects to be sent a |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
902 } | 901 } |
903 | 902 |
904 int HttpNetworkTransaction::DoBuildRequest() { | 903 int HttpNetworkTransaction::DoBuildRequest() { |
905 next_state_ = STATE_BUILD_REQUEST_COMPLETE; | 904 next_state_ = STATE_BUILD_REQUEST_COMPLETE; |
906 headers_valid_ = false; | 905 headers_valid_ = false; |
907 | 906 |
908 // This is constructed lazily (instead of within our Start method), so that | 907 // This is constructed lazily (instead of within our Start method), so that |
909 // we have proxy info available. | 908 // we have proxy info available. |
910 if (request_headers_.IsEmpty()) { | 909 if (request_headers_.IsEmpty()) { |
911 bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && | 910 bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) && |
912 !is_https_request(); | 911 !is_https_request(); |
913 BuildRequestHeaders(using_proxy); | 912 BuildRequestHeaders(using_proxy); |
914 } | 913 } |
915 | 914 |
916 return OK; | 915 return OK; |
917 } | 916 } |
918 | 917 |
919 int HttpNetworkTransaction::DoBuildRequestComplete(int result) { | 918 int HttpNetworkTransaction::DoBuildRequestComplete(int result) { |
920 if (result == OK) | 919 if (result == OK) |
921 next_state_ = STATE_SEND_REQUEST; | 920 next_state_ = STATE_SEND_REQUEST; |
922 return result; | 921 return result; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1000 bool data_reduction_fallback_proxy_used = false; | 999 bool data_reduction_fallback_proxy_used = false; |
1001 #if defined(DATA_REDUCTION_FALLBACK_HOST) | 1000 #if defined(DATA_REDUCTION_FALLBACK_HOST) |
1002 if (!data_reduction_proxy_used) { | 1001 if (!data_reduction_proxy_used) { |
1003 data_reduction_fallback_proxy_used = | 1002 data_reduction_fallback_proxy_used = |
1004 proxy_info_.proxy_server().isDataReductionProxyFallback(); | 1003 proxy_info_.proxy_server().isDataReductionProxyFallback(); |
1005 } | 1004 } |
1006 #endif | 1005 #endif |
1007 | 1006 |
1008 if (data_reduction_proxy_used || data_reduction_fallback_proxy_used) { | 1007 if (data_reduction_proxy_used || data_reduction_fallback_proxy_used) { |
1009 net::HttpResponseHeaders::DataReductionProxyInfo | 1008 net::HttpResponseHeaders::DataReductionProxyInfo |
1010 data_reduction_proxy_info; | 1009 data_reduction_proxy_info; |
1011 proxy_bypass_event | 1010 proxy_bypass_event = |
1012 = response_.headers->GetDataReductionProxyBypassEventType( | 1011 response_.headers->GetDataReductionProxyBypassEventType( |
1013 &data_reduction_proxy_info); | 1012 &data_reduction_proxy_info); |
1014 if (proxy_bypass_event < ProxyService::BYPASS_EVENT_TYPE_MAX) { | 1013 if (proxy_bypass_event < ProxyService::BYPASS_EVENT_TYPE_MAX) { |
1015 ProxyService* proxy_service = session_->proxy_service(); | 1014 ProxyService* proxy_service = session_->proxy_service(); |
1016 | 1015 |
1017 proxy_service->RecordDataReductionProxyBypassInfo( | 1016 proxy_service->RecordDataReductionProxyBypassInfo( |
1018 data_reduction_proxy_used, proxy_info_.proxy_server(), | 1017 data_reduction_proxy_used, |
| 1018 proxy_info_.proxy_server(), |
1019 proxy_bypass_event); | 1019 proxy_bypass_event); |
1020 | 1020 |
1021 ProxyServer proxy_server; | 1021 ProxyServer proxy_server; |
1022 #if defined(DATA_REDUCTION_FALLBACK_HOST) | 1022 #if defined(DATA_REDUCTION_FALLBACK_HOST) |
1023 if (data_reduction_proxy_used && data_reduction_proxy_info.bypass_all) { | 1023 if (data_reduction_proxy_used && data_reduction_proxy_info.bypass_all) { |
1024 // TODO(bengr): Rename as DATA_REDUCTION_FALLBACK_ORIGIN. | 1024 // TODO(bengr): Rename as DATA_REDUCTION_FALLBACK_ORIGIN. |
1025 GURL proxy_url(DATA_REDUCTION_FALLBACK_HOST); | 1025 GURL proxy_url(DATA_REDUCTION_FALLBACK_HOST); |
1026 if (proxy_url.SchemeIsHTTPOrHTTPS()) { | 1026 if (proxy_url.SchemeIsHTTPOrHTTPS()) { |
1027 proxy_server = ProxyServer(proxy_url.SchemeIs("http") ? | 1027 proxy_server = ProxyServer(proxy_url.SchemeIs("http") |
1028 ProxyServer::SCHEME_HTTP : | 1028 ? ProxyServer::SCHEME_HTTP |
1029 ProxyServer::SCHEME_HTTPS, | 1029 : ProxyServer::SCHEME_HTTPS, |
1030 HostPortPair::FromURL(proxy_url)); | 1030 HostPortPair::FromURL(proxy_url)); |
1031 } | 1031 } |
1032 } | 1032 } |
1033 #endif | 1033 #endif |
1034 if (proxy_service->MarkProxiesAsBadUntil( | 1034 if (proxy_service->MarkProxiesAsBadUntil( |
1035 proxy_info_, | 1035 proxy_info_, |
1036 data_reduction_proxy_info.bypass_duration, | 1036 data_reduction_proxy_info.bypass_duration, |
1037 proxy_server, | 1037 proxy_server, |
1038 net_log_)) { | 1038 net_log_)) { |
1039 // Only retry idempotent methods. We don't want to resubmit a POST | 1039 // Only retry idempotent methods. We don't want to resubmit a POST |
1040 // if the proxy took some action. | 1040 // if the proxy took some action. |
1041 if (request_->method == "GET" || | 1041 if (request_->method == "GET" || request_->method == "OPTIONS" || |
1042 request_->method == "OPTIONS" || | 1042 request_->method == "HEAD" || request_->method == "PUT" || |
1043 request_->method == "HEAD" || | 1043 request_->method == "DELETE" || request_->method == "TRACE") { |
1044 request_->method == "PUT" || | |
1045 request_->method == "DELETE" || | |
1046 request_->method == "TRACE") { | |
1047 ResetConnectionAndRequestForResend(); | 1044 ResetConnectionAndRequestForResend(); |
1048 return OK; | 1045 return OK; |
1049 } | 1046 } |
1050 } | 1047 } |
1051 } | 1048 } |
1052 } | 1049 } |
1053 } | 1050 } |
1054 #endif // defined(SPDY_PROXY_AUTH_ORIGIN) | 1051 #endif // defined(SPDY_PROXY_AUTH_ORIGIN) |
1055 | 1052 |
1056 // Like Net.HttpResponseCode, but only for MAIN_FRAME loads. | 1053 // Like Net.HttpResponseCode, but only for MAIN_FRAME loads. |
1057 if (request_->load_flags & LOAD_MAIN_FRAME) { | 1054 if (request_->load_flags & LOAD_MAIN_FRAME) { |
1058 const int response_code = response_.headers->response_code(); | 1055 const int response_code = response_.headers->response_code(); |
1059 UMA_HISTOGRAM_ENUMERATION( | 1056 UMA_HISTOGRAM_ENUMERATION( |
1060 "Net.HttpResponseCode_Nxx_MainFrame", response_code/100, 10); | 1057 "Net.HttpResponseCode_Nxx_MainFrame", response_code / 100, 10); |
1061 } | 1058 } |
1062 | 1059 |
1063 net_log_.AddEvent( | 1060 net_log_.AddEvent( |
1064 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS, | 1061 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS, |
1065 base::Bind(&HttpResponseHeaders::NetLogCallback, response_.headers)); | 1062 base::Bind(&HttpResponseHeaders::NetLogCallback, response_.headers)); |
1066 | 1063 |
1067 if (response_.headers->GetParsedHttpVersion() < HttpVersion(1, 0)) { | 1064 if (response_.headers->GetParsedHttpVersion() < HttpVersion(1, 0)) { |
1068 // HTTP/0.9 doesn't support the PUT method, so lack of response headers | 1065 // HTTP/0.9 doesn't support the PUT method, so lack of response headers |
1069 // indicates a buggy server. See: | 1066 // indicates a buggy server. See: |
1070 // https://bugzilla.mozilla.org/show_bug.cgi?id=193921 | 1067 // https://bugzilla.mozilla.org/show_bug.cgi?id=193921 |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1202 } | 1199 } |
1203 | 1200 |
1204 void HttpNetworkTransaction::LogTransactionConnectedMetrics() { | 1201 void HttpNetworkTransaction::LogTransactionConnectedMetrics() { |
1205 if (logged_response_time_) | 1202 if (logged_response_time_) |
1206 return; | 1203 return; |
1207 | 1204 |
1208 logged_response_time_ = true; | 1205 logged_response_time_ = true; |
1209 | 1206 |
1210 base::TimeDelta total_duration = response_.response_time - start_time_; | 1207 base::TimeDelta total_duration = response_.response_time - start_time_; |
1211 | 1208 |
1212 UMA_HISTOGRAM_CUSTOM_TIMES( | 1209 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Transaction_Connected", |
1213 "Net.Transaction_Connected", | 1210 total_duration, |
1214 total_duration, | 1211 base::TimeDelta::FromMilliseconds(1), |
1215 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), | 1212 base::TimeDelta::FromMinutes(10), |
1216 100); | 1213 100); |
1217 | 1214 |
1218 bool reused_socket = stream_->IsConnectionReused(); | 1215 bool reused_socket = stream_->IsConnectionReused(); |
1219 if (!reused_socket) { | 1216 if (!reused_socket) { |
1220 UMA_HISTOGRAM_CUSTOM_TIMES( | 1217 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Transaction_Connected_New_b", |
1221 "Net.Transaction_Connected_New_b", | 1218 total_duration, |
1222 total_duration, | 1219 base::TimeDelta::FromMilliseconds(1), |
1223 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), | 1220 base::TimeDelta::FromMinutes(10), |
1224 100); | 1221 100); |
1225 } | 1222 } |
1226 | 1223 |
1227 // Currently, non-HIGHEST priority requests are frame or sub-frame resource | 1224 // Currently, non-HIGHEST priority requests are frame or sub-frame resource |
1228 // types. This will change when we also prioritize certain subresources like | 1225 // types. This will change when we also prioritize certain subresources like |
1229 // css, js, etc. | 1226 // css, js, etc. |
1230 if (priority_ != HIGHEST) { | 1227 if (priority_ != HIGHEST) { |
1231 UMA_HISTOGRAM_CUSTOM_TIMES( | 1228 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Priority_High_Latency_b", |
1232 "Net.Priority_High_Latency_b", | 1229 total_duration, |
1233 total_duration, | 1230 base::TimeDelta::FromMilliseconds(1), |
1234 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), | 1231 base::TimeDelta::FromMinutes(10), |
1235 100); | 1232 100); |
1236 } else { | 1233 } else { |
1237 UMA_HISTOGRAM_CUSTOM_TIMES( | 1234 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Priority_Low_Latency_b", |
1238 "Net.Priority_Low_Latency_b", | 1235 total_duration, |
1239 total_duration, | 1236 base::TimeDelta::FromMilliseconds(1), |
1240 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), | 1237 base::TimeDelta::FromMinutes(10), |
1241 100); | 1238 100); |
1242 } | 1239 } |
1243 } | 1240 } |
1244 | 1241 |
1245 void HttpNetworkTransaction::LogTransactionMetrics() const { | 1242 void HttpNetworkTransaction::LogTransactionMetrics() const { |
1246 base::TimeDelta duration = base::Time::Now() - | 1243 base::TimeDelta duration = base::Time::Now() - response_.request_time; |
1247 response_.request_time; | |
1248 if (60 < duration.InMinutes()) | 1244 if (60 < duration.InMinutes()) |
1249 return; | 1245 return; |
1250 | 1246 |
1251 base::TimeDelta total_duration = base::Time::Now() - start_time_; | 1247 base::TimeDelta total_duration = base::Time::Now() - start_time_; |
1252 | 1248 |
1253 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Transaction_Latency_b", duration, | 1249 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Transaction_Latency_b", |
| 1250 duration, |
1254 base::TimeDelta::FromMilliseconds(1), | 1251 base::TimeDelta::FromMilliseconds(1), |
1255 base::TimeDelta::FromMinutes(10), | 1252 base::TimeDelta::FromMinutes(10), |
1256 100); | 1253 100); |
1257 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Transaction_Latency_Total", | 1254 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Transaction_Latency_Total", |
1258 total_duration, | 1255 total_duration, |
1259 base::TimeDelta::FromMilliseconds(1), | 1256 base::TimeDelta::FromMilliseconds(1), |
1260 base::TimeDelta::FromMinutes(10), 100); | 1257 base::TimeDelta::FromMinutes(10), |
| 1258 100); |
1261 | 1259 |
1262 if (!stream_->IsConnectionReused()) { | 1260 if (!stream_->IsConnectionReused()) { |
1263 UMA_HISTOGRAM_CUSTOM_TIMES( | 1261 UMA_HISTOGRAM_CUSTOM_TIMES("Net.Transaction_Latency_Total_New_Connection", |
1264 "Net.Transaction_Latency_Total_New_Connection", | 1262 total_duration, |
1265 total_duration, base::TimeDelta::FromMilliseconds(1), | 1263 base::TimeDelta::FromMilliseconds(1), |
1266 base::TimeDelta::FromMinutes(10), 100); | 1264 base::TimeDelta::FromMinutes(10), |
| 1265 100); |
1267 } | 1266 } |
1268 } | 1267 } |
1269 | 1268 |
1270 int HttpNetworkTransaction::HandleCertificateRequest(int error) { | 1269 int HttpNetworkTransaction::HandleCertificateRequest(int error) { |
1271 // There are two paths through which the server can request a certificate | 1270 // There are two paths through which the server can request a certificate |
1272 // from us. The first is during the initial handshake, the second is | 1271 // from us. The first is during the initial handshake, the second is |
1273 // during SSL renegotiation. | 1272 // during SSL renegotiation. |
1274 // | 1273 // |
1275 // In both cases, we want to close the connection before proceeding. | 1274 // In both cases, we want to close the connection before proceeding. |
1276 // We do this for two reasons: | 1275 // We do this for two reasons: |
(...skipping 26 matching lines...) Expand all Loading... |
1303 return error; | 1302 return error; |
1304 | 1303 |
1305 // Check that the certificate selected is still a certificate the server | 1304 // Check that the certificate selected is still a certificate the server |
1306 // is likely to accept, based on the criteria supplied in the | 1305 // is likely to accept, based on the criteria supplied in the |
1307 // CertificateRequest message. | 1306 // CertificateRequest message. |
1308 if (client_cert.get()) { | 1307 if (client_cert.get()) { |
1309 const std::vector<std::string>& cert_authorities = | 1308 const std::vector<std::string>& cert_authorities = |
1310 response_.cert_request_info->cert_authorities; | 1309 response_.cert_request_info->cert_authorities; |
1311 | 1310 |
1312 bool cert_still_valid = cert_authorities.empty() || | 1311 bool cert_still_valid = cert_authorities.empty() || |
1313 client_cert->IsIssuedByEncoded(cert_authorities); | 1312 client_cert->IsIssuedByEncoded(cert_authorities); |
1314 if (!cert_still_valid) | 1313 if (!cert_still_valid) |
1315 return error; | 1314 return error; |
1316 } | 1315 } |
1317 | 1316 |
1318 // TODO(davidben): Add a unit test which covers this path; we need to be | 1317 // TODO(davidben): Add a unit test which covers this path; we need to be |
1319 // able to send a legitimate certificate and also bypass/clear the | 1318 // able to send a legitimate certificate and also bypass/clear the |
1320 // SSL session cache. | 1319 // SSL session cache. |
1321 SSLConfig* ssl_config = response_.cert_request_info->is_proxy ? | 1320 SSLConfig* ssl_config = response_.cert_request_info->is_proxy |
1322 &proxy_ssl_config_ : &server_ssl_config_; | 1321 ? &proxy_ssl_config_ |
| 1322 : &server_ssl_config_; |
1323 ssl_config->send_client_cert = true; | 1323 ssl_config->send_client_cert = true; |
1324 ssl_config->client_cert = client_cert; | 1324 ssl_config->client_cert = client_cert; |
1325 next_state_ = STATE_CREATE_STREAM; | 1325 next_state_ = STATE_CREATE_STREAM; |
1326 // Reset the other member variables. | 1326 // Reset the other member variables. |
1327 // Note: this is necessary only with SSL renegotiation. | 1327 // Note: this is necessary only with SSL renegotiation. |
1328 ResetStateForRestart(); | 1328 ResetStateForRestart(); |
1329 return OK; | 1329 return OK; |
1330 } | 1330 } |
1331 | 1331 |
1332 void HttpNetworkTransaction::HandleClientAuthError(int error) { | 1332 void HttpNetworkTransaction::HandleClientAuthError(int error) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1386 case ERR_SSL_INAPPROPRIATE_FALLBACK: | 1386 case ERR_SSL_INAPPROPRIATE_FALLBACK: |
1387 // The server told us that we should not have fallen back. A buggy server | 1387 // The server told us that we should not have fallen back. A buggy server |
1388 // could trigger ERR_SSL_INAPPROPRIATE_FALLBACK with the initial | 1388 // could trigger ERR_SSL_INAPPROPRIATE_FALLBACK with the initial |
1389 // connection. |fallback_error_code_| is initialised to | 1389 // connection. |fallback_error_code_| is initialised to |
1390 // ERR_SSL_INAPPROPRIATE_FALLBACK to catch this case. | 1390 // ERR_SSL_INAPPROPRIATE_FALLBACK to catch this case. |
1391 error = fallback_error_code_; | 1391 error = fallback_error_code_; |
1392 break; | 1392 break; |
1393 } | 1393 } |
1394 | 1394 |
1395 if (should_fallback) { | 1395 if (should_fallback) { |
1396 net_log_.AddEvent( | 1396 net_log_.AddEvent(NetLog::TYPE_SSL_VERSION_FALLBACK, |
1397 NetLog::TYPE_SSL_VERSION_FALLBACK, | 1397 base::Bind(&NetLogSSLVersionFallbackCallback, |
1398 base::Bind(&NetLogSSLVersionFallbackCallback, | 1398 &request_->url, |
1399 &request_->url, error, server_ssl_config_.version_max, | 1399 error, |
1400 version_max)); | 1400 server_ssl_config_.version_max, |
| 1401 version_max)); |
1401 fallback_error_code_ = error; | 1402 fallback_error_code_ = error; |
1402 server_ssl_config_.version_max = version_max; | 1403 server_ssl_config_.version_max = version_max; |
1403 server_ssl_config_.version_fallback = true; | 1404 server_ssl_config_.version_fallback = true; |
1404 ResetConnectionAndRequestForResend(); | 1405 ResetConnectionAndRequestForResend(); |
1405 error = OK; | 1406 error = OK; |
1406 } | 1407 } |
1407 | 1408 |
1408 return error; | 1409 return error; |
1409 } | 1410 } |
1410 | 1411 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1508 | 1509 |
1509 // We need to clear request_headers_ because it contains the real request | 1510 // We need to clear request_headers_ because it contains the real request |
1510 // headers, but we may need to resend the CONNECT request first to recreate | 1511 // headers, but we may need to resend the CONNECT request first to recreate |
1511 // the SSL tunnel. | 1512 // the SSL tunnel. |
1512 request_headers_.Clear(); | 1513 request_headers_.Clear(); |
1513 next_state_ = STATE_CREATE_STREAM; // Resend the request. | 1514 next_state_ = STATE_CREATE_STREAM; // Resend the request. |
1514 } | 1515 } |
1515 | 1516 |
1516 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const { | 1517 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const { |
1517 return !is_https_request() && | 1518 return !is_https_request() && |
1518 (proxy_info_.is_https() || proxy_info_.is_http()); | 1519 (proxy_info_.is_https() || proxy_info_.is_http()); |
1519 } | 1520 } |
1520 | 1521 |
1521 bool HttpNetworkTransaction::ShouldApplyServerAuth() const { | 1522 bool HttpNetworkTransaction::ShouldApplyServerAuth() const { |
1522 return !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA); | 1523 return !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA); |
1523 } | 1524 } |
1524 | 1525 |
1525 int HttpNetworkTransaction::HandleAuthChallenge() { | 1526 int HttpNetworkTransaction::HandleAuthChallenge() { |
1526 scoped_refptr<HttpResponseHeaders> headers(GetResponseHeaders()); | 1527 scoped_refptr<HttpResponseHeaders> headers(GetResponseHeaders()); |
1527 DCHECK(headers.get()); | 1528 DCHECK(headers.get()); |
1528 | 1529 |
1529 int status = headers->response_code(); | 1530 int status = headers->response_code(); |
1530 if (status != HTTP_UNAUTHORIZED && | 1531 if (status != HTTP_UNAUTHORIZED && |
1531 status != HTTP_PROXY_AUTHENTICATION_REQUIRED) | 1532 status != HTTP_PROXY_AUTHENTICATION_REQUIRED) |
1532 return OK; | 1533 return OK; |
1533 HttpAuth::Target target = status == HTTP_PROXY_AUTHENTICATION_REQUIRED ? | 1534 HttpAuth::Target target = status == HTTP_PROXY_AUTHENTICATION_REQUIRED |
1534 HttpAuth::AUTH_PROXY : HttpAuth::AUTH_SERVER; | 1535 ? HttpAuth::AUTH_PROXY |
| 1536 : HttpAuth::AUTH_SERVER; |
1535 if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct()) | 1537 if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct()) |
1536 return ERR_UNEXPECTED_PROXY_AUTH; | 1538 return ERR_UNEXPECTED_PROXY_AUTH; |
1537 | 1539 |
1538 // This case can trigger when an HTTPS server responds with a "Proxy | 1540 // This case can trigger when an HTTPS server responds with a "Proxy |
1539 // authentication required" status code through a non-authenticating | 1541 // authentication required" status code through a non-authenticating |
1540 // proxy. | 1542 // proxy. |
1541 if (!auth_controllers_[target].get()) | 1543 if (!auth_controllers_[target].get()) |
1542 return ERR_UNEXPECTED_PROXY_AUTH; | 1544 return ERR_UNEXPECTED_PROXY_AUTH; |
1543 | 1545 |
1544 int rv = auth_controllers_[target]->HandleAuthChallenge( | 1546 int rv = auth_controllers_[target]->HandleAuthChallenge( |
1545 headers, (request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA) != 0, false, | 1547 headers, |
| 1548 (request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA) != 0, |
| 1549 false, |
1546 net_log_); | 1550 net_log_); |
1547 if (auth_controllers_[target]->HaveAuthHandler()) | 1551 if (auth_controllers_[target]->HaveAuthHandler()) |
1548 pending_auth_target_ = target; | 1552 pending_auth_target_ = target; |
1549 | 1553 |
1550 scoped_refptr<AuthChallengeInfo> auth_info = | 1554 scoped_refptr<AuthChallengeInfo> auth_info = |
1551 auth_controllers_[target]->auth_info(); | 1555 auth_controllers_[target]->auth_info(); |
1552 if (auth_info.get()) | 1556 if (auth_info.get()) |
1553 response_.auth_challenge = auth_info; | 1557 response_.auth_challenge = auth_info; |
1554 | 1558 |
1555 return rv; | 1559 return rv; |
1556 } | 1560 } |
1557 | 1561 |
1558 bool HttpNetworkTransaction::HaveAuth(HttpAuth::Target target) const { | 1562 bool HttpNetworkTransaction::HaveAuth(HttpAuth::Target target) const { |
1559 return auth_controllers_[target].get() && | 1563 return auth_controllers_[target].get() && |
1560 auth_controllers_[target]->HaveAuth(); | 1564 auth_controllers_[target]->HaveAuth(); |
1561 } | 1565 } |
1562 | 1566 |
1563 GURL HttpNetworkTransaction::AuthURL(HttpAuth::Target target) const { | 1567 GURL HttpNetworkTransaction::AuthURL(HttpAuth::Target target) const { |
1564 switch (target) { | 1568 switch (target) { |
1565 case HttpAuth::AUTH_PROXY: { | 1569 case HttpAuth::AUTH_PROXY: { |
1566 if (!proxy_info_.proxy_server().is_valid() || | 1570 if (!proxy_info_.proxy_server().is_valid() || |
1567 proxy_info_.proxy_server().is_direct()) { | 1571 proxy_info_.proxy_server().is_direct()) { |
1568 return GURL(); // There is no proxy server. | 1572 return GURL(); // There is no proxy server. |
1569 } | 1573 } |
1570 const char* scheme = proxy_info_.is_https() ? "https://" : "http://"; | 1574 const char* scheme = proxy_info_.is_https() ? "https://" : "http://"; |
1571 return GURL(scheme + | 1575 return GURL(scheme + |
1572 proxy_info_.proxy_server().host_port_pair().ToString()); | 1576 proxy_info_.proxy_server().host_port_pair().ToString()); |
1573 } | 1577 } |
1574 case HttpAuth::AUTH_SERVER: | 1578 case HttpAuth::AUTH_SERVER: |
1575 return request_->url; | 1579 return request_->url; |
1576 default: | 1580 default: |
1577 return GURL(); | 1581 return GURL(); |
1578 } | 1582 } |
1579 } | 1583 } |
1580 | 1584 |
1581 bool HttpNetworkTransaction::ForWebSocketHandshake() const { | 1585 bool HttpNetworkTransaction::ForWebSocketHandshake() const { |
1582 return websocket_handshake_stream_base_create_helper_ && | 1586 return websocket_handshake_stream_base_create_helper_ && |
1583 request_->url.SchemeIsWSOrWSS(); | 1587 request_->url.SchemeIsWSOrWSS(); |
1584 } | 1588 } |
1585 | 1589 |
1586 #define STATE_CASE(s) \ | 1590 #define STATE_CASE(s) \ |
1587 case s: \ | 1591 case s: \ |
1588 description = base::StringPrintf("%s (0x%08X)", #s, s); \ | 1592 description = base::StringPrintf("%s (0x%08X)", #s, s); \ |
1589 break | 1593 break |
1590 | 1594 |
1591 std::string HttpNetworkTransaction::DescribeState(State state) { | 1595 std::string HttpNetworkTransaction::DescribeState(State state) { |
1592 std::string description; | 1596 std::string description; |
1593 switch (state) { | 1597 switch (state) { |
1594 STATE_CASE(STATE_NOTIFY_BEFORE_CREATE_STREAM); | 1598 STATE_CASE(STATE_NOTIFY_BEFORE_CREATE_STREAM); |
1595 STATE_CASE(STATE_CREATE_STREAM); | 1599 STATE_CASE(STATE_CREATE_STREAM); |
1596 STATE_CASE(STATE_CREATE_STREAM_COMPLETE); | 1600 STATE_CASE(STATE_CREATE_STREAM_COMPLETE); |
1597 STATE_CASE(STATE_INIT_REQUEST_BODY); | 1601 STATE_CASE(STATE_INIT_REQUEST_BODY); |
1598 STATE_CASE(STATE_INIT_REQUEST_BODY_COMPLETE); | 1602 STATE_CASE(STATE_INIT_REQUEST_BODY_COMPLETE); |
1599 STATE_CASE(STATE_BUILD_REQUEST); | 1603 STATE_CASE(STATE_BUILD_REQUEST); |
1600 STATE_CASE(STATE_BUILD_REQUEST_COMPLETE); | 1604 STATE_CASE(STATE_BUILD_REQUEST_COMPLETE); |
1601 STATE_CASE(STATE_SEND_REQUEST); | 1605 STATE_CASE(STATE_SEND_REQUEST); |
1602 STATE_CASE(STATE_SEND_REQUEST_COMPLETE); | 1606 STATE_CASE(STATE_SEND_REQUEST_COMPLETE); |
1603 STATE_CASE(STATE_READ_HEADERS); | 1607 STATE_CASE(STATE_READ_HEADERS); |
1604 STATE_CASE(STATE_READ_HEADERS_COMPLETE); | 1608 STATE_CASE(STATE_READ_HEADERS_COMPLETE); |
1605 STATE_CASE(STATE_READ_BODY); | 1609 STATE_CASE(STATE_READ_BODY); |
1606 STATE_CASE(STATE_READ_BODY_COMPLETE); | 1610 STATE_CASE(STATE_READ_BODY_COMPLETE); |
1607 STATE_CASE(STATE_DRAIN_BODY_FOR_AUTH_RESTART); | 1611 STATE_CASE(STATE_DRAIN_BODY_FOR_AUTH_RESTART); |
1608 STATE_CASE(STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE); | 1612 STATE_CASE(STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE); |
1609 STATE_CASE(STATE_NONE); | 1613 STATE_CASE(STATE_NONE); |
1610 default: | 1614 default: |
1611 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, | 1615 description = |
1612 state); | 1616 base::StringPrintf("Unknown state 0x%08X (%u)", state, state); |
1613 break; | 1617 break; |
1614 } | 1618 } |
1615 return description; | 1619 return description; |
1616 } | 1620 } |
1617 | 1621 |
1618 #undef STATE_CASE | 1622 #undef STATE_CASE |
1619 | 1623 |
1620 } // namespace net | 1624 } // namespace net |
OLD | NEW |