| 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/url_request/url_request_http_job.h" | 5 #include "net/url_request/url_request_http_job.h" |
| 6 | 6 |
| 7 #include "base/base_switches.h" | 7 #include "base/base_switches.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 bool URLRequestHttpJob::HttpFilterContext::GetURL(GURL* gurl) const { | 94 bool URLRequestHttpJob::HttpFilterContext::GetURL(GURL* gurl) const { |
| 95 if (!job_->request()) | 95 if (!job_->request()) |
| 96 return false; | 96 return false; |
| 97 *gurl = job_->request()->url(); | 97 *gurl = job_->request()->url(); |
| 98 return true; | 98 return true; |
| 99 } | 99 } |
| 100 | 100 |
| 101 bool URLRequestHttpJob::HttpFilterContext::GetContentDisposition( | 101 bool URLRequestHttpJob::HttpFilterContext::GetContentDisposition( |
| 102 std::string* disposition) const { | 102 std::string* disposition) const { |
| 103 HttpResponseHeaders* headers = job_->GetResponseHeaders(); | 103 HttpResponseHeaders* headers = job_->GetResponseHeaders(); |
| 104 void *iter = NULL; | 104 void* iter = NULL; |
| 105 return headers->EnumerateHeader(&iter, "Content-Disposition", disposition); | 105 return headers->EnumerateHeader(&iter, "Content-Disposition", disposition); |
| 106 } | 106 } |
| 107 | 107 |
| 108 base::Time URLRequestHttpJob::HttpFilterContext::GetRequestTime() const { | 108 base::Time URLRequestHttpJob::HttpFilterContext::GetRequestTime() const { |
| 109 return job_->request() ? job_->request()->request_time() : base::Time(); | 109 return job_->request() ? job_->request()->request_time() : base::Time(); |
| 110 } | 110 } |
| 111 | 111 |
| 112 bool URLRequestHttpJob::HttpFilterContext::IsCachedContent() const { | 112 bool URLRequestHttpJob::HttpFilterContext::IsCachedContent() const { |
| 113 return job_->is_cached_content_; | 113 return job_->is_cached_content_; |
| 114 } | 114 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 | 149 |
| 150 if (!request->context()->http_transaction_factory()) { | 150 if (!request->context()->http_transaction_factory()) { |
| 151 NOTREACHED() << "requires a valid context"; | 151 NOTREACHED() << "requires a valid context"; |
| 152 return new URLRequestErrorJob( | 152 return new URLRequestErrorJob( |
| 153 request, network_delegate, ERR_INVALID_ARGUMENT); | 153 request, network_delegate, ERR_INVALID_ARGUMENT); |
| 154 } | 154 } |
| 155 | 155 |
| 156 GURL redirect_url; | 156 GURL redirect_url; |
| 157 if (request->GetHSTSRedirect(&redirect_url)) { | 157 if (request->GetHSTSRedirect(&redirect_url)) { |
| 158 return new URLRequestRedirectJob( | 158 return new URLRequestRedirectJob( |
| 159 request, network_delegate, redirect_url, | 159 request, |
| 160 network_delegate, |
| 161 redirect_url, |
| 160 // Use status code 307 to preserve the method, so POST requests work. | 162 // Use status code 307 to preserve the method, so POST requests work. |
| 161 URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT, "HSTS"); | 163 URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT, |
| 164 "HSTS"); |
| 162 } | 165 } |
| 163 return new URLRequestHttpJob(request, | 166 return new URLRequestHttpJob(request, |
| 164 network_delegate, | 167 network_delegate, |
| 165 request->context()->http_user_agent_settings()); | 168 request->context()->http_user_agent_settings()); |
| 166 } | 169 } |
| 167 | 170 |
| 168 URLRequestHttpJob::URLRequestHttpJob( | 171 URLRequestHttpJob::URLRequestHttpJob( |
| 169 URLRequest* request, | 172 URLRequest* request, |
| 170 NetworkDelegate* network_delegate, | 173 NetworkDelegate* network_delegate, |
| 171 const HttpUserAgentSettings* http_user_agent_settings) | 174 const HttpUserAgentSettings* http_user_agent_settings) |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 request_info_.method = request_->method(); | 257 request_info_.method = request_->method(); |
| 255 request_info_.load_flags = request_->load_flags(); | 258 request_info_.load_flags = request_->load_flags(); |
| 256 // Enable privacy mode if cookie settings or flags tell us not send or | 259 // Enable privacy mode if cookie settings or flags tell us not send or |
| 257 // save cookies. | 260 // save cookies. |
| 258 bool enable_privacy_mode = | 261 bool enable_privacy_mode = |
| 259 (request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES) || | 262 (request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES) || |
| 260 (request_info_.load_flags & LOAD_DO_NOT_SAVE_COOKIES) || | 263 (request_info_.load_flags & LOAD_DO_NOT_SAVE_COOKIES) || |
| 261 CanEnablePrivacyMode(); | 264 CanEnablePrivacyMode(); |
| 262 // Privacy mode could still be disabled in OnCookiesLoaded if we are going | 265 // Privacy mode could still be disabled in OnCookiesLoaded if we are going |
| 263 // to send previously saved cookies. | 266 // to send previously saved cookies. |
| 264 request_info_.privacy_mode = enable_privacy_mode ? | 267 request_info_.privacy_mode = |
| 265 PRIVACY_MODE_ENABLED : PRIVACY_MODE_DISABLED; | 268 enable_privacy_mode ? PRIVACY_MODE_ENABLED : PRIVACY_MODE_DISABLED; |
| 266 | 269 |
| 267 // Strip Referer from request_info_.extra_headers to prevent, e.g., plugins | 270 // Strip Referer from request_info_.extra_headers to prevent, e.g., plugins |
| 268 // from overriding headers that are controlled using other means. Otherwise a | 271 // from overriding headers that are controlled using other means. Otherwise a |
| 269 // plugin could set a referrer although sending the referrer is inhibited. | 272 // plugin could set a referrer although sending the referrer is inhibited. |
| 270 request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kReferer); | 273 request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kReferer); |
| 271 | 274 |
| 272 // Our consumer should have made sure that this is a safe referrer. See for | 275 // Our consumer should have made sure that this is a safe referrer. See for |
| 273 // instance WebCore::FrameLoader::HideReferrer. | 276 // instance WebCore::FrameLoader::HideReferrer. |
| 274 if (referrer.is_valid()) { | 277 if (referrer.is_valid()) { |
| 275 request_info_.extra_headers.SetHeader(HttpRequestHeaders::kReferer, | 278 request_info_.extra_headers.SetHeader(HttpRequestHeaders::kReferer, |
| 276 referrer.spec()); | 279 referrer.spec()); |
| 277 } | 280 } |
| 278 | 281 |
| 279 request_info_.extra_headers.SetHeaderIfMissing( | 282 request_info_.extra_headers.SetHeaderIfMissing( |
| 280 HttpRequestHeaders::kUserAgent, | 283 HttpRequestHeaders::kUserAgent, |
| 281 http_user_agent_settings_ ? | 284 http_user_agent_settings_ ? http_user_agent_settings_->GetUserAgent() |
| 282 http_user_agent_settings_->GetUserAgent() : std::string()); | 285 : std::string()); |
| 283 | 286 |
| 284 AddExtraHeaders(); | 287 AddExtraHeaders(); |
| 285 AddCookieHeaderAndStart(); | 288 AddCookieHeaderAndStart(); |
| 286 } | 289 } |
| 287 | 290 |
| 288 void URLRequestHttpJob::Kill() { | 291 void URLRequestHttpJob::Kill() { |
| 289 if (!transaction_.get()) | 292 if (!transaction_.get()) |
| 290 return; | 293 return; |
| 291 | 294 |
| 292 weak_factory_.InvalidateWeakPtrs(); | 295 weak_factory_.InvalidateWeakPtrs(); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 DoneWithRequest(ABORTED); | 363 DoneWithRequest(ABORTED); |
| 361 transaction_.reset(); | 364 transaction_.reset(); |
| 362 response_info_ = NULL; | 365 response_info_ = NULL; |
| 363 receive_headers_end_ = base::TimeTicks(); | 366 receive_headers_end_ = base::TimeTicks(); |
| 364 } | 367 } |
| 365 | 368 |
| 366 void URLRequestHttpJob::StartTransaction() { | 369 void URLRequestHttpJob::StartTransaction() { |
| 367 if (network_delegate()) { | 370 if (network_delegate()) { |
| 368 OnCallToDelegate(); | 371 OnCallToDelegate(); |
| 369 int rv = network_delegate()->NotifyBeforeSendHeaders( | 372 int rv = network_delegate()->NotifyBeforeSendHeaders( |
| 370 request_, notify_before_headers_sent_callback_, | 373 request_, |
| 374 notify_before_headers_sent_callback_, |
| 371 &request_info_.extra_headers); | 375 &request_info_.extra_headers); |
| 372 // If an extension blocks the request, we rely on the callback to | 376 // If an extension blocks the request, we rely on the callback to |
| 373 // MaybeStartTransactionInternal(). | 377 // MaybeStartTransactionInternal(). |
| 374 if (rv == ERR_IO_PENDING) | 378 if (rv == ERR_IO_PENDING) |
| 375 return; | 379 return; |
| 376 MaybeStartTransactionInternal(rv); | 380 MaybeStartTransactionInternal(rv); |
| 377 return; | 381 return; |
| 378 } | 382 } |
| 379 StartTransactionInternal(); | 383 StartTransactionInternal(); |
| 380 } | 384 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 401 | 405 |
| 402 void URLRequestHttpJob::StartTransactionInternal() { | 406 void URLRequestHttpJob::StartTransactionInternal() { |
| 403 // NOTE: This method assumes that request_info_ is already setup properly. | 407 // NOTE: This method assumes that request_info_ is already setup properly. |
| 404 | 408 |
| 405 // If we already have a transaction, then we should restart the transaction | 409 // If we already have a transaction, then we should restart the transaction |
| 406 // with auth provided by auth_credentials_. | 410 // with auth provided by auth_credentials_. |
| 407 | 411 |
| 408 int rv; | 412 int rv; |
| 409 | 413 |
| 410 if (network_delegate()) { | 414 if (network_delegate()) { |
| 411 network_delegate()->NotifySendHeaders( | 415 network_delegate()->NotifySendHeaders(request_, |
| 412 request_, request_info_.extra_headers); | 416 request_info_.extra_headers); |
| 413 } | 417 } |
| 414 | 418 |
| 415 if (transaction_.get()) { | 419 if (transaction_.get()) { |
| 416 rv = transaction_->RestartWithAuth(auth_credentials_, start_callback_); | 420 rv = transaction_->RestartWithAuth(auth_credentials_, start_callback_); |
| 417 auth_credentials_ = AuthCredentials(); | 421 auth_credentials_ = AuthCredentials(); |
| 418 } else { | 422 } else { |
| 419 DCHECK(request_->context()->http_transaction_factory()); | 423 DCHECK(request_->context()->http_transaction_factory()); |
| 420 | 424 |
| 421 rv = request_->context()->http_transaction_factory()->CreateTransaction( | 425 rv = request_->context()->http_transaction_factory()->CreateTransaction( |
| 422 priority_, &transaction_); | 426 priority_, &transaction_); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 452 } | 456 } |
| 453 | 457 |
| 454 if (rv == ERR_IO_PENDING) | 458 if (rv == ERR_IO_PENDING) |
| 455 return; | 459 return; |
| 456 | 460 |
| 457 // The transaction started synchronously, but we need to notify the | 461 // The transaction started synchronously, but we need to notify the |
| 458 // URLRequest delegate via the message loop. | 462 // URLRequest delegate via the message loop. |
| 459 base::MessageLoop::current()->PostTask( | 463 base::MessageLoop::current()->PostTask( |
| 460 FROM_HERE, | 464 FROM_HERE, |
| 461 base::Bind(&URLRequestHttpJob::OnStartCompleted, | 465 base::Bind(&URLRequestHttpJob::OnStartCompleted, |
| 462 weak_factory_.GetWeakPtr(), rv)); | 466 weak_factory_.GetWeakPtr(), |
| 467 rv)); |
| 463 } | 468 } |
| 464 | 469 |
| 465 void URLRequestHttpJob::AddExtraHeaders() { | 470 void URLRequestHttpJob::AddExtraHeaders() { |
| 466 // Supply Accept-Encoding field only if it is not already provided. | 471 // Supply Accept-Encoding field only if it is not already provided. |
| 467 // It should be provided IF the content is known to have restrictions on | 472 // It should be provided IF the content is known to have restrictions on |
| 468 // potential encoding, such as streaming multi-media. | 473 // potential encoding, such as streaming multi-media. |
| 469 // For details see bug 47381. | 474 // For details see bug 47381. |
| 470 // TODO(jar, enal): jpeg files etc. should set up a request header if | 475 // TODO(jar, enal): jpeg files etc. should set up a request header if |
| 471 // possible. Right now it is done only by buffered_resource_loader and | 476 // possible. Right now it is done only by buffered_resource_loader and |
| 472 // simple_data_source. | 477 // simple_data_source. |
| 473 if (!request_info_.extra_headers.HasHeader( | 478 if (!request_info_.extra_headers.HasHeader( |
| 474 HttpRequestHeaders::kAcceptEncoding)) { | 479 HttpRequestHeaders::kAcceptEncoding)) { |
| 475 bool advertise_sdch = SdchManager::Global() && | 480 bool advertise_sdch = |
| 481 SdchManager::Global() && |
| 476 SdchManager::Global()->IsInSupportedDomain(request_->url()); | 482 SdchManager::Global()->IsInSupportedDomain(request_->url()); |
| 477 std::string avail_dictionaries; | 483 std::string avail_dictionaries; |
| 478 if (advertise_sdch) { | 484 if (advertise_sdch) { |
| 479 SdchManager::Global()->GetAvailDictionaryList(request_->url(), | 485 SdchManager::Global()->GetAvailDictionaryList(request_->url(), |
| 480 &avail_dictionaries); | 486 &avail_dictionaries); |
| 481 | 487 |
| 482 // The AllowLatencyExperiment() is only true if we've successfully done a | 488 // The AllowLatencyExperiment() is only true if we've successfully done a |
| 483 // full SDCH compression recently in this browser session for this host. | 489 // full SDCH compression recently in this browser session for this host. |
| 484 // Note that for this path, there might be no applicable dictionaries, | 490 // Note that for this path, there might be no applicable dictionaries, |
| 485 // and hence we can't participate in the experiment. | 491 // and hence we can't participate in the experiment. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 498 } | 504 } |
| 499 } | 505 } |
| 500 | 506 |
| 501 // Supply Accept-Encoding headers first so that it is more likely that they | 507 // Supply Accept-Encoding headers first so that it is more likely that they |
| 502 // will be in the first transmitted packet. This can sometimes make it | 508 // will be in the first transmitted packet. This can sometimes make it |
| 503 // easier to filter and analyze the streams to assure that a proxy has not | 509 // easier to filter and analyze the streams to assure that a proxy has not |
| 504 // damaged these headers. Some proxies deliberately corrupt Accept-Encoding | 510 // damaged these headers. Some proxies deliberately corrupt Accept-Encoding |
| 505 // headers. | 511 // headers. |
| 506 if (!advertise_sdch) { | 512 if (!advertise_sdch) { |
| 507 // Tell the server what compression formats we support (other than SDCH). | 513 // Tell the server what compression formats we support (other than SDCH). |
| 508 request_info_.extra_headers.SetHeader( | 514 request_info_.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding, |
| 509 HttpRequestHeaders::kAcceptEncoding, "gzip,deflate"); | 515 "gzip,deflate"); |
| 510 } else { | 516 } else { |
| 511 // Include SDCH in acceptable list. | 517 // Include SDCH in acceptable list. |
| 512 request_info_.extra_headers.SetHeader( | 518 request_info_.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding, |
| 513 HttpRequestHeaders::kAcceptEncoding, "gzip,deflate,sdch"); | 519 "gzip,deflate,sdch"); |
| 514 if (!avail_dictionaries.empty()) { | 520 if (!avail_dictionaries.empty()) { |
| 515 request_info_.extra_headers.SetHeader( | 521 request_info_.extra_headers.SetHeader(kAvailDictionaryHeader, |
| 516 kAvailDictionaryHeader, | 522 avail_dictionaries); |
| 517 avail_dictionaries); | |
| 518 sdch_dictionary_advertised_ = true; | 523 sdch_dictionary_advertised_ = true; |
| 519 // Since we're tagging this transaction as advertising a dictionary, | 524 // Since we're tagging this transaction as advertising a dictionary, |
| 520 // we'll definitely employ an SDCH filter (or tentative sdch filter) | 525 // we'll definitely employ an SDCH filter (or tentative sdch filter) |
| 521 // when we get a response. When done, we'll record histograms via | 526 // when we get a response. When done, we'll record histograms via |
| 522 // SDCH_DECODE or SDCH_PASSTHROUGH. Hence we need to record packet | 527 // SDCH_DECODE or SDCH_PASSTHROUGH. Hence we need to record packet |
| 523 // arrival times. | 528 // arrival times. |
| 524 packet_timing_enabled_ = true; | 529 packet_timing_enabled_ = true; |
| 525 } | 530 } |
| 526 } | 531 } |
| 527 } | 532 } |
| 528 | 533 |
| 529 if (http_user_agent_settings_) { | 534 if (http_user_agent_settings_) { |
| 530 // Only add default Accept-Language if the request didn't have it | 535 // Only add default Accept-Language if the request didn't have it |
| 531 // specified. | 536 // specified. |
| 532 std::string accept_language = | 537 std::string accept_language = |
| 533 http_user_agent_settings_->GetAcceptLanguage(); | 538 http_user_agent_settings_->GetAcceptLanguage(); |
| 534 if (!accept_language.empty()) { | 539 if (!accept_language.empty()) { |
| 535 request_info_.extra_headers.SetHeaderIfMissing( | 540 request_info_.extra_headers.SetHeaderIfMissing( |
| 536 HttpRequestHeaders::kAcceptLanguage, | 541 HttpRequestHeaders::kAcceptLanguage, accept_language); |
| 537 accept_language); | |
| 538 } | 542 } |
| 539 } | 543 } |
| 540 } | 544 } |
| 541 | 545 |
| 542 void URLRequestHttpJob::AddCookieHeaderAndStart() { | 546 void URLRequestHttpJob::AddCookieHeaderAndStart() { |
| 543 // No matter what, we want to report our status as IO pending since we will | 547 // No matter what, we want to report our status as IO pending since we will |
| 544 // be notifying our consumer asynchronously via OnStartCompleted. | 548 // be notifying our consumer asynchronously via OnStartCompleted. |
| 545 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); | 549 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); |
| 546 | 550 |
| 547 // If the request was destroyed, then there is no more work to do. | 551 // If the request was destroyed, then there is no more work to do. |
| 548 if (!request_) | 552 if (!request_) |
| 549 return; | 553 return; |
| 550 | 554 |
| 551 CookieStore* cookie_store = GetCookieStore(); | 555 CookieStore* cookie_store = GetCookieStore(); |
| 552 if (cookie_store && !(request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES)) { | 556 if (cookie_store && !(request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES)) { |
| 553 cookie_store->GetAllCookiesForURLAsync( | 557 cookie_store->GetAllCookiesForURLAsync( |
| 554 request_->url(), | 558 request_->url(), |
| 555 base::Bind(&URLRequestHttpJob::CheckCookiePolicyAndLoad, | 559 base::Bind(&URLRequestHttpJob::CheckCookiePolicyAndLoad, |
| 556 weak_factory_.GetWeakPtr())); | 560 weak_factory_.GetWeakPtr())); |
| 557 } else { | 561 } else { |
| 558 DoStartTransaction(); | 562 DoStartTransaction(); |
| 559 } | 563 } |
| 560 } | 564 } |
| 561 | 565 |
| 562 void URLRequestHttpJob::DoLoadCookies() { | 566 void URLRequestHttpJob::DoLoadCookies() { |
| 563 CookieOptions options; | 567 CookieOptions options; |
| 564 options.set_include_httponly(); | 568 options.set_include_httponly(); |
| 565 GetCookieStore()->GetCookiesWithOptionsAsync( | 569 GetCookieStore()->GetCookiesWithOptionsAsync( |
| 566 request_->url(), options, | 570 request_->url(), |
| 571 options, |
| 567 base::Bind(&URLRequestHttpJob::OnCookiesLoaded, | 572 base::Bind(&URLRequestHttpJob::OnCookiesLoaded, |
| 568 weak_factory_.GetWeakPtr())); | 573 weak_factory_.GetWeakPtr())); |
| 569 } | 574 } |
| 570 | 575 |
| 571 void URLRequestHttpJob::CheckCookiePolicyAndLoad( | 576 void URLRequestHttpJob::CheckCookiePolicyAndLoad( |
| 572 const CookieList& cookie_list) { | 577 const CookieList& cookie_list) { |
| 573 if (CanGetCookies(cookie_list)) | 578 if (CanGetCookies(cookie_list)) |
| 574 DoLoadCookies(); | 579 DoLoadCookies(); |
| 575 else | 580 else |
| 576 DoStartTransaction(); | 581 DoStartTransaction(); |
| 577 } | 582 } |
| 578 | 583 |
| 579 void URLRequestHttpJob::OnCookiesLoaded(const std::string& cookie_line) { | 584 void URLRequestHttpJob::OnCookiesLoaded(const std::string& cookie_line) { |
| 580 if (!cookie_line.empty()) { | 585 if (!cookie_line.empty()) { |
| 581 request_info_.extra_headers.SetHeader( | 586 request_info_.extra_headers.SetHeader(HttpRequestHeaders::kCookie, |
| 582 HttpRequestHeaders::kCookie, cookie_line); | 587 cookie_line); |
| 583 // Disable privacy mode as we are sending cookies anyway. | 588 // Disable privacy mode as we are sending cookies anyway. |
| 584 request_info_.privacy_mode = PRIVACY_MODE_DISABLED; | 589 request_info_.privacy_mode = PRIVACY_MODE_DISABLED; |
| 585 } | 590 } |
| 586 DoStartTransaction(); | 591 DoStartTransaction(); |
| 587 } | 592 } |
| 588 | 593 |
| 589 void URLRequestHttpJob::DoStartTransaction() { | 594 void URLRequestHttpJob::DoStartTransaction() { |
| 590 // We may have been canceled while retrieving cookies. | 595 // We may have been canceled while retrieving cookies. |
| 591 if (GetStatus().is_success()) { | 596 if (GetStatus().is_success()) { |
| 592 StartTransaction(); | 597 StartTransaction(); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 net::CookieStore::SetCookiesCallback callback( | 655 net::CookieStore::SetCookiesCallback callback( |
| 651 base::Bind(&URLRequestHttpJob::OnCookieSaved, | 656 base::Bind(&URLRequestHttpJob::OnCookieSaved, |
| 652 weak_factory_.GetWeakPtr(), | 657 weak_factory_.GetWeakPtr(), |
| 653 save_next_cookie_running, | 658 save_next_cookie_running, |
| 654 callback_pending)); | 659 callback_pending)); |
| 655 | 660 |
| 656 // Loop through the cookies as long as SetCookieWithOptionsAsync completes | 661 // Loop through the cookies as long as SetCookieWithOptionsAsync completes |
| 657 // synchronously. | 662 // synchronously. |
| 658 while (!callback_pending->data && | 663 while (!callback_pending->data && |
| 659 response_cookies_save_index_ < response_cookies_.size()) { | 664 response_cookies_save_index_ < response_cookies_.size()) { |
| 660 if (CanSetCookie( | 665 if (CanSetCookie(response_cookies_[response_cookies_save_index_], |
| 661 response_cookies_[response_cookies_save_index_], &options)) { | 666 &options)) { |
| 662 callback_pending->data = true; | 667 callback_pending->data = true; |
| 663 GetCookieStore()->SetCookieWithOptionsAsync( | 668 GetCookieStore()->SetCookieWithOptionsAsync( |
| 664 request_->url(), response_cookies_[response_cookies_save_index_], | 669 request_->url(), |
| 665 options, callback); | 670 response_cookies_[response_cookies_save_index_], |
| 671 options, |
| 672 callback); |
| 666 } | 673 } |
| 667 ++response_cookies_save_index_; | 674 ++response_cookies_save_index_; |
| 668 } | 675 } |
| 669 } | 676 } |
| 670 | 677 |
| 671 save_next_cookie_running->data = false; | 678 save_next_cookie_running->data = false; |
| 672 | 679 |
| 673 if (!callback_pending->data) { | 680 if (!callback_pending->data) { |
| 674 response_cookies_.clear(); | 681 response_cookies_.clear(); |
| 675 response_cookies_save_index_ = 0; | 682 response_cookies_save_index_ = 0; |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 receive_headers_end_ = base::TimeTicks::Now(); | 789 receive_headers_end_ = base::TimeTicks::Now(); |
| 783 | 790 |
| 784 // Clear the IO_PENDING status | 791 // Clear the IO_PENDING status |
| 785 SetStatus(URLRequestStatus()); | 792 SetStatus(URLRequestStatus()); |
| 786 | 793 |
| 787 const URLRequestContext* context = request_->context(); | 794 const URLRequestContext* context = request_->context(); |
| 788 | 795 |
| 789 if (result == ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN && | 796 if (result == ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN && |
| 790 transaction_->GetResponseInfo() != NULL) { | 797 transaction_->GetResponseInfo() != NULL) { |
| 791 FraudulentCertificateReporter* reporter = | 798 FraudulentCertificateReporter* reporter = |
| 792 context->fraudulent_certificate_reporter(); | 799 context->fraudulent_certificate_reporter(); |
| 793 if (reporter != NULL) { | 800 if (reporter != NULL) { |
| 794 const SSLInfo& ssl_info = transaction_->GetResponseInfo()->ssl_info; | 801 const SSLInfo& ssl_info = transaction_->GetResponseInfo()->ssl_info; |
| 795 bool sni_available = SSLConfigService::IsSNIAvailable( | 802 bool sni_available = |
| 796 context->ssl_config_service()); | 803 SSLConfigService::IsSNIAvailable(context->ssl_config_service()); |
| 797 const std::string& host = request_->url().host(); | 804 const std::string& host = request_->url().host(); |
| 798 | 805 |
| 799 reporter->SendReport(host, ssl_info, sni_available); | 806 reporter->SendReport(host, ssl_info, sni_available); |
| 800 } | 807 } |
| 801 } | 808 } |
| 802 | 809 |
| 803 if (result == OK) { | 810 if (result == OK) { |
| 804 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); | 811 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); |
| 805 if (network_delegate()) { | 812 if (network_delegate()) { |
| 806 // Note that |this| may not be deleted until | 813 // Note that |this| may not be deleted until |
| 807 // |on_headers_received_callback_| or | 814 // |on_headers_received_callback_| or |
| 808 // |NetworkDelegate::URLRequestDestroyed()| has been called. | 815 // |NetworkDelegate::URLRequestDestroyed()| has been called. |
| 809 OnCallToDelegate(); | 816 OnCallToDelegate(); |
| 810 allowed_unsafe_redirect_url_ = GURL(); | 817 allowed_unsafe_redirect_url_ = GURL(); |
| 811 int error = network_delegate()->NotifyHeadersReceived( | 818 int error = network_delegate()->NotifyHeadersReceived( |
| 812 request_, | 819 request_, |
| 813 on_headers_received_callback_, | 820 on_headers_received_callback_, |
| 814 headers.get(), | 821 headers.get(), |
| 815 &override_response_headers_, | 822 &override_response_headers_, |
| 816 &allowed_unsafe_redirect_url_); | 823 &allowed_unsafe_redirect_url_); |
| 817 if (error != net::OK) { | 824 if (error != net::OK) { |
| 818 if (error == net::ERR_IO_PENDING) { | 825 if (error == net::ERR_IO_PENDING) { |
| 819 awaiting_callback_ = true; | 826 awaiting_callback_ = true; |
| 820 } else { | 827 } else { |
| 821 std::string source("delegate"); | 828 std::string source("delegate"); |
| 822 request_->net_log().AddEvent(NetLog::TYPE_CANCELLED, | 829 request_->net_log().AddEvent( |
| 823 NetLog::StringCallback("source", | 830 NetLog::TYPE_CANCELLED, |
| 824 &source)); | 831 NetLog::StringCallback("source", &source)); |
| 825 OnCallToDelegateComplete(); | 832 OnCallToDelegateComplete(); |
| 826 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, error)); | 833 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, error)); |
| 827 } | 834 } |
| 828 return; | 835 return; |
| 829 } | 836 } |
| 830 } | 837 } |
| 831 | 838 |
| 832 SaveCookiesAndNotifyHeadersComplete(net::OK); | 839 SaveCookiesAndNotifyHeadersComplete(net::OK); |
| 833 } else if (IsCertificateError(result)) { | 840 } else if (IsCertificateError(result)) { |
| 834 // We encountered an SSL certificate error. | 841 // We encountered an SSL certificate error. |
| 835 if (result == ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY || | 842 if (result == ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY || |
| 836 result == ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN) { | 843 result == ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN) { |
| 837 // These are hard failures. They're handled separately and don't have | 844 // These are hard failures. They're handled separately and don't have |
| 838 // the correct cert status, so set it here. | 845 // the correct cert status, so set it here. |
| 839 SSLInfo info(transaction_->GetResponseInfo()->ssl_info); | 846 SSLInfo info(transaction_->GetResponseInfo()->ssl_info); |
| 840 info.cert_status = MapNetErrorToCertStatus(result); | 847 info.cert_status = MapNetErrorToCertStatus(result); |
| 841 NotifySSLCertificateError(info, true); | 848 NotifySSLCertificateError(info, true); |
| 842 } else { | 849 } else { |
| 843 // Maybe overridable, maybe not. Ask the delegate to decide. | 850 // Maybe overridable, maybe not. Ask the delegate to decide. |
| 844 TransportSecurityState::DomainState domain_state; | 851 TransportSecurityState::DomainState domain_state; |
| 845 const URLRequestContext* context = request_->context(); | 852 const URLRequestContext* context = request_->context(); |
| 846 const bool fatal = context->transport_security_state() && | 853 const bool fatal = |
| 854 context->transport_security_state() && |
| 847 context->transport_security_state()->GetDomainState( | 855 context->transport_security_state()->GetDomainState( |
| 848 request_info_.url.host(), | 856 request_info_.url.host(), |
| 849 SSLConfigService::IsSNIAvailable(context->ssl_config_service()), | 857 SSLConfigService::IsSNIAvailable(context->ssl_config_service()), |
| 850 &domain_state) && | 858 &domain_state) && |
| 851 domain_state.ShouldSSLErrorsBeFatal(); | 859 domain_state.ShouldSSLErrorsBeFatal(); |
| 852 NotifySSLCertificateError( | 860 NotifySSLCertificateError(transaction_->GetResponseInfo()->ssl_info, |
| 853 transaction_->GetResponseInfo()->ssl_info, fatal); | 861 fatal); |
| 854 } | 862 } |
| 855 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 863 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
| 856 NotifyCertificateRequested( | 864 NotifyCertificateRequested( |
| 857 transaction_->GetResponseInfo()->cert_request_info.get()); | 865 transaction_->GetResponseInfo()->cert_request_info.get()); |
| 858 } else { | 866 } else { |
| 859 // Even on an error, there may be useful information in the response | 867 // Even on an error, there may be useful information in the response |
| 860 // info (e.g. whether there's a cached copy). | 868 // info (e.g. whether there's a cached copy). |
| 861 if (transaction_.get()) | 869 if (transaction_.get()) |
| 862 response_info_ = transaction_->GetResponseInfo(); | 870 response_info_ = transaction_->GetResponseInfo(); |
| 863 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); | 871 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result)); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 915 request_info_.upload_data_stream = upload; | 923 request_info_.upload_data_stream = upload; |
| 916 } | 924 } |
| 917 | 925 |
| 918 void URLRequestHttpJob::SetExtraRequestHeaders( | 926 void URLRequestHttpJob::SetExtraRequestHeaders( |
| 919 const HttpRequestHeaders& headers) { | 927 const HttpRequestHeaders& headers) { |
| 920 DCHECK(!transaction_.get()) << "cannot change once started"; | 928 DCHECK(!transaction_.get()) << "cannot change once started"; |
| 921 request_info_.extra_headers.CopyFrom(headers); | 929 request_info_.extra_headers.CopyFrom(headers); |
| 922 } | 930 } |
| 923 | 931 |
| 924 LoadState URLRequestHttpJob::GetLoadState() const { | 932 LoadState URLRequestHttpJob::GetLoadState() const { |
| 925 return transaction_.get() ? | 933 return transaction_.get() ? transaction_->GetLoadState() : LOAD_STATE_IDLE; |
| 926 transaction_->GetLoadState() : LOAD_STATE_IDLE; | |
| 927 } | 934 } |
| 928 | 935 |
| 929 UploadProgress URLRequestHttpJob::GetUploadProgress() const { | 936 UploadProgress URLRequestHttpJob::GetUploadProgress() const { |
| 930 return transaction_.get() ? | 937 return transaction_.get() ? transaction_->GetUploadProgress() |
| 931 transaction_->GetUploadProgress() : UploadProgress(); | 938 : UploadProgress(); |
| 932 } | 939 } |
| 933 | 940 |
| 934 bool URLRequestHttpJob::GetMimeType(std::string* mime_type) const { | 941 bool URLRequestHttpJob::GetMimeType(std::string* mime_type) const { |
| 935 DCHECK(transaction_.get()); | 942 DCHECK(transaction_.get()); |
| 936 | 943 |
| 937 if (!response_info_) | 944 if (!response_info_) |
| 938 return false; | 945 return false; |
| 939 | 946 |
| 940 return GetResponseHeaders()->GetMimeType(mime_type); | 947 return GetResponseHeaders()->GetMimeType(mime_type); |
| 941 } | 948 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1008 } | 1015 } |
| 1009 | 1016 |
| 1010 if (filter_context_->IsSdchResponse()) { | 1017 if (filter_context_->IsSdchResponse()) { |
| 1011 // We are wary of proxies that discard or damage SDCH encoding. If a server | 1018 // We are wary of proxies that discard or damage SDCH encoding. If a server |
| 1012 // explicitly states that this is not SDCH content, then we can correct our | 1019 // explicitly states that this is not SDCH content, then we can correct our |
| 1013 // assumption that this is an SDCH response, and avoid the need to recover | 1020 // assumption that this is an SDCH response, and avoid the need to recover |
| 1014 // as though the content is corrupted (when we discover it is not SDCH | 1021 // as though the content is corrupted (when we discover it is not SDCH |
| 1015 // encoded). | 1022 // encoded). |
| 1016 std::string sdch_response_status; | 1023 std::string sdch_response_status; |
| 1017 iter = NULL; | 1024 iter = NULL; |
| 1018 while (headers->EnumerateHeader(&iter, "X-Sdch-Encode", | 1025 while (headers->EnumerateHeader( |
| 1019 &sdch_response_status)) { | 1026 &iter, "X-Sdch-Encode", &sdch_response_status)) { |
| 1020 if (sdch_response_status == "0") { | 1027 if (sdch_response_status == "0") { |
| 1021 filter_context_->ResetSdchResponseToFalse(); | 1028 filter_context_->ResetSdchResponseToFalse(); |
| 1022 break; | 1029 break; |
| 1023 } | 1030 } |
| 1024 } | 1031 } |
| 1025 } | 1032 } |
| 1026 | 1033 |
| 1027 // Even if encoding types are empty, there is a chance that we need to add | 1034 // Even if encoding types are empty, there is a chance that we need to add |
| 1028 // some decoding, as some proxies strip encoding completely. In such cases, | 1035 // some decoding, as some proxies strip encoding completely. In such cases, |
| 1029 // we may need to add (for example) SDCH filtering (when the context suggests | 1036 // we may need to add (for example) SDCH filtering (when the context suggests |
| 1030 // it is appropriate). | 1037 // it is appropriate). |
| 1031 Filter::FixupEncodingTypes(*filter_context_, &encoding_types); | 1038 Filter::FixupEncodingTypes(*filter_context_, &encoding_types); |
| 1032 | 1039 |
| 1033 return !encoding_types.empty() | 1040 return !encoding_types.empty() |
| 1034 ? Filter::Factory(encoding_types, *filter_context_) : NULL; | 1041 ? Filter::Factory(encoding_types, *filter_context_) |
| 1042 : NULL; |
| 1035 } | 1043 } |
| 1036 | 1044 |
| 1037 bool URLRequestHttpJob::CopyFragmentOnRedirect(const GURL& location) const { | 1045 bool URLRequestHttpJob::CopyFragmentOnRedirect(const GURL& location) const { |
| 1038 // Allow modification of reference fragments by default, unless | 1046 // Allow modification of reference fragments by default, unless |
| 1039 // |allowed_unsafe_redirect_url_| is set and equal to the redirect URL. | 1047 // |allowed_unsafe_redirect_url_| is set and equal to the redirect URL. |
| 1040 // When this is the case, we assume that the network delegate has set the | 1048 // When this is the case, we assume that the network delegate has set the |
| 1041 // desired redirect URL (with or without fragment), so it must not be changed | 1049 // desired redirect URL (with or without fragment), so it must not be changed |
| 1042 // any more. | 1050 // any more. |
| 1043 return !allowed_unsafe_redirect_url_.is_valid() || | 1051 return !allowed_unsafe_redirect_url_.is_valid() || |
| 1044 allowed_unsafe_redirect_url_ != location; | 1052 allowed_unsafe_redirect_url_ != location; |
| 1045 } | 1053 } |
| 1046 | 1054 |
| 1047 bool URLRequestHttpJob::IsSafeRedirect(const GURL& location) { | 1055 bool URLRequestHttpJob::IsSafeRedirect(const GURL& location) { |
| 1048 // HTTP is always safe. | 1056 // HTTP is always safe. |
| 1049 // TODO(pauljensen): Remove once crbug.com/146591 is fixed. | 1057 // TODO(pauljensen): Remove once crbug.com/146591 is fixed. |
| 1050 if (location.is_valid() && | 1058 if (location.is_valid() && |
| 1051 (location.scheme() == "http" || location.scheme() == "https")) { | 1059 (location.scheme() == "http" || location.scheme() == "https")) { |
| 1052 return true; | 1060 return true; |
| 1053 } | 1061 } |
| 1054 // Delegates may mark a URL as safe for redirection. | 1062 // Delegates may mark a URL as safe for redirection. |
| 1055 if (allowed_unsafe_redirect_url_.is_valid() && | 1063 if (allowed_unsafe_redirect_url_.is_valid() && |
| 1056 allowed_unsafe_redirect_url_ == location) { | 1064 allowed_unsafe_redirect_url_ == location) { |
| 1057 return true; | 1065 return true; |
| 1058 } | 1066 } |
| 1059 // Query URLRequestJobFactory as to whether |location| would be safe to | 1067 // Query URLRequestJobFactory as to whether |location| would be safe to |
| 1060 // redirect to. | 1068 // redirect to. |
| 1061 return request_->context()->job_factory() && | 1069 return request_->context()->job_factory() && |
| 1062 request_->context()->job_factory()->IsSafeRedirectTarget(location); | 1070 request_->context()->job_factory()->IsSafeRedirectTarget(location); |
| 1063 } | 1071 } |
| 1064 | 1072 |
| 1065 bool URLRequestHttpJob::NeedsAuth() { | 1073 bool URLRequestHttpJob::NeedsAuth() { |
| 1066 int code = GetResponseCode(); | 1074 int code = GetResponseCode(); |
| 1067 if (code == -1) | 1075 if (code == -1) |
| 1068 return false; | 1076 return false; |
| 1069 | 1077 |
| 1070 // Check if we need either Proxy or WWW Authentication. This could happen | 1078 // Check if we need either Proxy or WWW Authentication. This could happen |
| 1071 // because we either provided no auth info, or provided incorrect info. | 1079 // because we either provided no auth info, or provided incorrect info. |
| 1072 switch (code) { | 1080 switch (code) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1133 // | 1141 // |
| 1134 // Because we set the AUTH_STATE_CANCELED flag, NeedsAuth will return false, | 1142 // Because we set the AUTH_STATE_CANCELED flag, NeedsAuth will return false, |
| 1135 // which will cause the consumer to receive OnResponseStarted instead of | 1143 // which will cause the consumer to receive OnResponseStarted instead of |
| 1136 // OnAuthRequired. | 1144 // OnAuthRequired. |
| 1137 // | 1145 // |
| 1138 // We have to do this via InvokeLater to avoid "recursing" the consumer. | 1146 // We have to do this via InvokeLater to avoid "recursing" the consumer. |
| 1139 // | 1147 // |
| 1140 base::MessageLoop::current()->PostTask( | 1148 base::MessageLoop::current()->PostTask( |
| 1141 FROM_HERE, | 1149 FROM_HERE, |
| 1142 base::Bind(&URLRequestHttpJob::OnStartCompleted, | 1150 base::Bind(&URLRequestHttpJob::OnStartCompleted, |
| 1143 weak_factory_.GetWeakPtr(), OK)); | 1151 weak_factory_.GetWeakPtr(), |
| 1152 OK)); |
| 1144 } | 1153 } |
| 1145 | 1154 |
| 1146 void URLRequestHttpJob::ContinueWithCertificate( | 1155 void URLRequestHttpJob::ContinueWithCertificate(X509Certificate* client_cert) { |
| 1147 X509Certificate* client_cert) { | |
| 1148 DCHECK(transaction_.get()); | 1156 DCHECK(transaction_.get()); |
| 1149 | 1157 |
| 1150 DCHECK(!response_info_) << "should not have a response yet"; | 1158 DCHECK(!response_info_) << "should not have a response yet"; |
| 1151 receive_headers_end_ = base::TimeTicks(); | 1159 receive_headers_end_ = base::TimeTicks(); |
| 1152 | 1160 |
| 1153 ResetTimer(); | 1161 ResetTimer(); |
| 1154 | 1162 |
| 1155 // No matter what, we want to report our status as IO pending since we will | 1163 // No matter what, we want to report our status as IO pending since we will |
| 1156 // be notifying our consumer asynchronously via OnStartCompleted. | 1164 // be notifying our consumer asynchronously via OnStartCompleted. |
| 1157 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); | 1165 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); |
| 1158 | 1166 |
| 1159 int rv = transaction_->RestartWithCertificate(client_cert, start_callback_); | 1167 int rv = transaction_->RestartWithCertificate(client_cert, start_callback_); |
| 1160 if (rv == ERR_IO_PENDING) | 1168 if (rv == ERR_IO_PENDING) |
| 1161 return; | 1169 return; |
| 1162 | 1170 |
| 1163 // The transaction started synchronously, but we need to notify the | 1171 // The transaction started synchronously, but we need to notify the |
| 1164 // URLRequest delegate via the message loop. | 1172 // URLRequest delegate via the message loop. |
| 1165 base::MessageLoop::current()->PostTask( | 1173 base::MessageLoop::current()->PostTask( |
| 1166 FROM_HERE, | 1174 FROM_HERE, |
| 1167 base::Bind(&URLRequestHttpJob::OnStartCompleted, | 1175 base::Bind(&URLRequestHttpJob::OnStartCompleted, |
| 1168 weak_factory_.GetWeakPtr(), rv)); | 1176 weak_factory_.GetWeakPtr(), |
| 1177 rv)); |
| 1169 } | 1178 } |
| 1170 | 1179 |
| 1171 void URLRequestHttpJob::ContinueDespiteLastError() { | 1180 void URLRequestHttpJob::ContinueDespiteLastError() { |
| 1172 // If the transaction was destroyed, then the job was cancelled. | 1181 // If the transaction was destroyed, then the job was cancelled. |
| 1173 if (!transaction_.get()) | 1182 if (!transaction_.get()) |
| 1174 return; | 1183 return; |
| 1175 | 1184 |
| 1176 DCHECK(!response_info_) << "should not have a response yet"; | 1185 DCHECK(!response_info_) << "should not have a response yet"; |
| 1177 receive_headers_end_ = base::TimeTicks(); | 1186 receive_headers_end_ = base::TimeTicks(); |
| 1178 | 1187 |
| 1179 ResetTimer(); | 1188 ResetTimer(); |
| 1180 | 1189 |
| 1181 // No matter what, we want to report our status as IO pending since we will | 1190 // No matter what, we want to report our status as IO pending since we will |
| 1182 // be notifying our consumer asynchronously via OnStartCompleted. | 1191 // be notifying our consumer asynchronously via OnStartCompleted. |
| 1183 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); | 1192 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); |
| 1184 | 1193 |
| 1185 int rv = transaction_->RestartIgnoringLastError(start_callback_); | 1194 int rv = transaction_->RestartIgnoringLastError(start_callback_); |
| 1186 if (rv == ERR_IO_PENDING) | 1195 if (rv == ERR_IO_PENDING) |
| 1187 return; | 1196 return; |
| 1188 | 1197 |
| 1189 // The transaction started synchronously, but we need to notify the | 1198 // The transaction started synchronously, but we need to notify the |
| 1190 // URLRequest delegate via the message loop. | 1199 // URLRequest delegate via the message loop. |
| 1191 base::MessageLoop::current()->PostTask( | 1200 base::MessageLoop::current()->PostTask( |
| 1192 FROM_HERE, | 1201 FROM_HERE, |
| 1193 base::Bind(&URLRequestHttpJob::OnStartCompleted, | 1202 base::Bind(&URLRequestHttpJob::OnStartCompleted, |
| 1194 weak_factory_.GetWeakPtr(), rv)); | 1203 weak_factory_.GetWeakPtr(), |
| 1204 rv)); |
| 1195 } | 1205 } |
| 1196 | 1206 |
| 1197 void URLRequestHttpJob::ResumeNetworkStart() { | 1207 void URLRequestHttpJob::ResumeNetworkStart() { |
| 1198 DCHECK(transaction_.get()); | 1208 DCHECK(transaction_.get()); |
| 1199 transaction_->ResumeNetworkStart(); | 1209 transaction_->ResumeNetworkStart(); |
| 1200 } | 1210 } |
| 1201 | 1211 |
| 1202 bool URLRequestHttpJob::ShouldFixMismatchedContentLength(int rv) const { | 1212 bool URLRequestHttpJob::ShouldFixMismatchedContentLength(int rv) const { |
| 1203 // Some servers send the body compressed, but specify the content length as | 1213 // Some servers send the body compressed, but specify the content length as |
| 1204 // the uncompressed size. Although this violates the HTTP spec we want to | 1214 // the uncompressed size. Although this violates the HTTP spec we want to |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1215 << " post total = " << postfilter_bytes_read(); | 1225 << " post total = " << postfilter_bytes_read(); |
| 1216 if (postfilter_bytes_read() == expected_length) { | 1226 if (postfilter_bytes_read() == expected_length) { |
| 1217 // Clear the error. | 1227 // Clear the error. |
| 1218 return true; | 1228 return true; |
| 1219 } | 1229 } |
| 1220 } | 1230 } |
| 1221 } | 1231 } |
| 1222 return false; | 1232 return false; |
| 1223 } | 1233 } |
| 1224 | 1234 |
| 1225 bool URLRequestHttpJob::ReadRawData(IOBuffer* buf, int buf_size, | 1235 bool URLRequestHttpJob::ReadRawData(IOBuffer* buf, |
| 1236 int buf_size, |
| 1226 int* bytes_read) { | 1237 int* bytes_read) { |
| 1227 DCHECK_NE(buf_size, 0); | 1238 DCHECK_NE(buf_size, 0); |
| 1228 DCHECK(bytes_read); | 1239 DCHECK(bytes_read); |
| 1229 DCHECK(!read_in_progress_); | 1240 DCHECK(!read_in_progress_); |
| 1230 | 1241 |
| 1231 int rv = transaction_->Read( | 1242 int rv = transaction_->Read( |
| 1232 buf, buf_size, | 1243 buf, |
| 1244 buf_size, |
| 1233 base::Bind(&URLRequestHttpJob::OnReadCompleted, base::Unretained(this))); | 1245 base::Bind(&URLRequestHttpJob::OnReadCompleted, base::Unretained(this))); |
| 1234 | 1246 |
| 1235 if (ShouldFixMismatchedContentLength(rv)) | 1247 if (ShouldFixMismatchedContentLength(rv)) |
| 1236 rv = 0; | 1248 rv = 0; |
| 1237 | 1249 |
| 1238 if (rv >= 0) { | 1250 if (rv >= 0) { |
| 1239 *bytes_read = rv; | 1251 *bytes_read = rv; |
| 1240 if (!rv) | 1252 if (!rv) |
| 1241 DoneWithRequest(FINISHED); | 1253 DoneWithRequest(FINISHED); |
| 1242 return true; | 1254 return true; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1309 } | 1321 } |
| 1310 | 1322 |
| 1311 base::TimeDelta to_start = base::Time::Now() - request_creation_time_; | 1323 base::TimeDelta to_start = base::Time::Now() - request_creation_time_; |
| 1312 request_creation_time_ = base::Time(); | 1324 request_creation_time_ = base::Time(); |
| 1313 | 1325 |
| 1314 UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpTimeToFirstByte", to_start); | 1326 UMA_HISTOGRAM_MEDIUM_TIMES("Net.HttpTimeToFirstByte", to_start); |
| 1315 } | 1327 } |
| 1316 | 1328 |
| 1317 void URLRequestHttpJob::ResetTimer() { | 1329 void URLRequestHttpJob::ResetTimer() { |
| 1318 if (!request_creation_time_.is_null()) { | 1330 if (!request_creation_time_.is_null()) { |
| 1319 NOTREACHED() | 1331 NOTREACHED() << "The timer was reset before it was recorded."; |
| 1320 << "The timer was reset before it was recorded."; | |
| 1321 return; | 1332 return; |
| 1322 } | 1333 } |
| 1323 request_creation_time_ = base::Time::Now(); | 1334 request_creation_time_ = base::Time::Now(); |
| 1324 } | 1335 } |
| 1325 | 1336 |
| 1326 void URLRequestHttpJob::UpdatePacketReadTimes() { | 1337 void URLRequestHttpJob::UpdatePacketReadTimes() { |
| 1327 if (!packet_timing_enabled_) | 1338 if (!packet_timing_enabled_) |
| 1328 return; | 1339 return; |
| 1329 | 1340 |
| 1330 if (filter_input_byte_count() <= bytes_observed_in_packets_) { | 1341 if (filter_input_byte_count() <= bytes_observed_in_packets_) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1341 | 1352 |
| 1342 void URLRequestHttpJob::RecordPacketStats( | 1353 void URLRequestHttpJob::RecordPacketStats( |
| 1343 FilterContext::StatisticSelector statistic) const { | 1354 FilterContext::StatisticSelector statistic) const { |
| 1344 if (!packet_timing_enabled_ || (final_packet_time_ == base::Time())) | 1355 if (!packet_timing_enabled_ || (final_packet_time_ == base::Time())) |
| 1345 return; | 1356 return; |
| 1346 | 1357 |
| 1347 base::TimeDelta duration = final_packet_time_ - request_time_snapshot_; | 1358 base::TimeDelta duration = final_packet_time_ - request_time_snapshot_; |
| 1348 switch (statistic) { | 1359 switch (statistic) { |
| 1349 case FilterContext::SDCH_DECODE: { | 1360 case FilterContext::SDCH_DECODE: { |
| 1350 UMA_HISTOGRAM_CUSTOM_COUNTS("Sdch3.Network_Decode_Bytes_Processed_b", | 1361 UMA_HISTOGRAM_CUSTOM_COUNTS("Sdch3.Network_Decode_Bytes_Processed_b", |
| 1351 static_cast<int>(bytes_observed_in_packets_), 500, 100000, 100); | 1362 static_cast<int>(bytes_observed_in_packets_), |
| 1363 500, |
| 1364 100000, |
| 1365 100); |
| 1352 return; | 1366 return; |
| 1353 } | 1367 } |
| 1354 case FilterContext::SDCH_PASSTHROUGH: { | 1368 case FilterContext::SDCH_PASSTHROUGH: { |
| 1355 // Despite advertising a dictionary, we handled non-sdch compressed | 1369 // Despite advertising a dictionary, we handled non-sdch compressed |
| 1356 // content. | 1370 // content. |
| 1357 return; | 1371 return; |
| 1358 } | 1372 } |
| 1359 | 1373 |
| 1360 case FilterContext::SDCH_EXPERIMENT_DECODE: { | 1374 case FilterContext::SDCH_EXPERIMENT_DECODE: { |
| 1361 UMA_HISTOGRAM_CUSTOM_TIMES("Sdch3.Experiment2_Decode", | 1375 UMA_HISTOGRAM_CUSTOM_TIMES("Sdch3.Experiment2_Decode", |
| 1362 duration, | 1376 duration, |
| 1363 base::TimeDelta::FromMilliseconds(20), | 1377 base::TimeDelta::FromMilliseconds(20), |
| 1364 base::TimeDelta::FromMinutes(10), 100); | 1378 base::TimeDelta::FromMinutes(10), |
| 1379 100); |
| 1365 return; | 1380 return; |
| 1366 } | 1381 } |
| 1367 case FilterContext::SDCH_EXPERIMENT_HOLDBACK: { | 1382 case FilterContext::SDCH_EXPERIMENT_HOLDBACK: { |
| 1368 UMA_HISTOGRAM_CUSTOM_TIMES("Sdch3.Experiment2_Holdback", | 1383 UMA_HISTOGRAM_CUSTOM_TIMES("Sdch3.Experiment2_Holdback", |
| 1369 duration, | 1384 duration, |
| 1370 base::TimeDelta::FromMilliseconds(20), | 1385 base::TimeDelta::FromMilliseconds(20), |
| 1371 base::TimeDelta::FromMinutes(10), 100); | 1386 base::TimeDelta::FromMinutes(10), |
| 1387 100); |
| 1372 return; | 1388 return; |
| 1373 } | 1389 } |
| 1374 default: | 1390 default: |
| 1375 NOTREACHED(); | 1391 NOTREACHED(); |
| 1376 return; | 1392 return; |
| 1377 } | 1393 } |
| 1378 } | 1394 } |
| 1379 | 1395 |
| 1380 // The common type of histogram we use for all compression-tracking histograms. | 1396 // The common type of histogram we use for all compression-tracking histograms. |
| 1381 #define COMPRESSION_HISTOGRAM(name, sample) \ | 1397 #define COMPRESSION_HISTOGRAM(name, sample) \ |
| 1382 do { \ | 1398 do { \ |
| 1383 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.Compress." name, sample, \ | 1399 UMA_HISTOGRAM_CUSTOM_COUNTS( \ |
| 1384 500, 1000000, 100); \ | 1400 "Net.Compress." name, sample, 500, 1000000, 100); \ |
| 1385 } while (0) | 1401 } while (0) |
| 1386 | 1402 |
| 1387 void URLRequestHttpJob::RecordCompressionHistograms() { | 1403 void URLRequestHttpJob::RecordCompressionHistograms() { |
| 1388 DCHECK(request_); | 1404 DCHECK(request_); |
| 1389 if (!request_) | 1405 if (!request_) |
| 1390 return; | 1406 return; |
| 1391 | 1407 |
| 1392 if (is_cached_content_ || // Don't record cached content | 1408 if (is_cached_content_ || // Don't record cached content |
| 1393 !GetStatus().is_success() || // Don't record failed content | 1409 !GetStatus().is_success() || // Don't record failed content |
| 1394 !IsCompressibleContent() || // Only record compressible content | 1410 !IsCompressibleContent() || // Only record compressible content |
| 1395 !prefilter_bytes_read()) // Zero-byte responses aren't useful. | 1411 !prefilter_bytes_read()) // Zero-byte responses aren't useful. |
| 1396 return; | 1412 return; |
| 1397 | 1413 |
| 1398 // Miniature requests aren't really compressible. Don't count them. | 1414 // Miniature requests aren't really compressible. Don't count them. |
| 1399 const int kMinSize = 16; | 1415 const int kMinSize = 16; |
| 1400 if (prefilter_bytes_read() < kMinSize) | 1416 if (prefilter_bytes_read() < kMinSize) |
| 1401 return; | 1417 return; |
| 1402 | 1418 |
| 1403 // Only record for http or https urls. | 1419 // Only record for http or https urls. |
| 1404 bool is_http = request_->url().SchemeIs("http"); | 1420 bool is_http = request_->url().SchemeIs("http"); |
| 1405 bool is_https = request_->url().SchemeIs("https"); | 1421 bool is_https = request_->url().SchemeIs("https"); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1448 COMPRESSION_HISTOGRAM("NoProxy.BytesBeforeCompression", compressed_B); | 1464 COMPRESSION_HISTOGRAM("NoProxy.BytesBeforeCompression", compressed_B); |
| 1449 COMPRESSION_HISTOGRAM("NoProxy.BytesAfterCompression", decompressed_B); | 1465 COMPRESSION_HISTOGRAM("NoProxy.BytesAfterCompression", decompressed_B); |
| 1450 } else { | 1466 } else { |
| 1451 COMPRESSION_HISTOGRAM("NoProxy.ShouldHaveBeenCompressed", decompressed_B); | 1467 COMPRESSION_HISTOGRAM("NoProxy.ShouldHaveBeenCompressed", decompressed_B); |
| 1452 } | 1468 } |
| 1453 } | 1469 } |
| 1454 | 1470 |
| 1455 bool URLRequestHttpJob::IsCompressibleContent() const { | 1471 bool URLRequestHttpJob::IsCompressibleContent() const { |
| 1456 std::string mime_type; | 1472 std::string mime_type; |
| 1457 return GetMimeType(&mime_type) && | 1473 return GetMimeType(&mime_type) && |
| 1458 (IsSupportedJavascriptMimeType(mime_type.c_str()) || | 1474 (IsSupportedJavascriptMimeType(mime_type.c_str()) || |
| 1459 IsSupportedNonImageMimeType(mime_type.c_str())); | 1475 IsSupportedNonImageMimeType(mime_type.c_str())); |
| 1460 } | 1476 } |
| 1461 | 1477 |
| 1462 void URLRequestHttpJob::RecordPerfHistograms(CompletionCause reason) { | 1478 void URLRequestHttpJob::RecordPerfHistograms(CompletionCause reason) { |
| 1463 if (start_time_.is_null()) | 1479 if (start_time_.is_null()) |
| 1464 return; | 1480 return; |
| 1465 | 1481 |
| 1466 base::TimeDelta total_time = base::TimeTicks::Now() - start_time_; | 1482 base::TimeDelta total_time = base::TimeTicks::Now() - start_time_; |
| 1467 UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTime", total_time); | 1483 UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTime", total_time); |
| 1468 | 1484 |
| 1469 if (reason == FINISHED) { | 1485 if (reason == FINISHED) { |
| 1470 UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeSuccess", total_time); | 1486 UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeSuccess", total_time); |
| 1471 } else { | 1487 } else { |
| 1472 UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeCancel", total_time); | 1488 UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeCancel", total_time); |
| 1473 } | 1489 } |
| 1474 | 1490 |
| 1475 if (response_info_) { | 1491 if (response_info_) { |
| 1476 if (response_info_->was_cached) { | 1492 if (response_info_->was_cached) { |
| 1477 UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeCached", total_time); | 1493 UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeCached", total_time); |
| 1478 } else { | 1494 } else { |
| 1479 UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeNotCached", total_time); | 1495 UMA_HISTOGRAM_TIMES("Net.HttpJob.TotalTimeNotCached", total_time); |
| 1480 } | 1496 } |
| 1481 } | 1497 } |
| 1482 | 1498 |
| 1483 if (request_info_.load_flags & LOAD_PREFETCH && !request_->was_cached()) | 1499 if (request_info_.load_flags & LOAD_PREFETCH && !request_->was_cached()) |
| 1484 UMA_HISTOGRAM_COUNTS("Net.Prefetch.PrefilterBytesReadFromNetwork", | 1500 UMA_HISTOGRAM_COUNTS("Net.Prefetch.PrefilterBytesReadFromNetwork", |
| 1485 prefilter_bytes_read()); | 1501 prefilter_bytes_read()); |
| 1486 | 1502 |
| 1487 start_time_ = base::TimeTicks(); | 1503 start_time_ = base::TimeTicks(); |
| 1488 } | 1504 } |
| 1489 | 1505 |
| 1490 void URLRequestHttpJob::DoneWithRequest(CompletionCause reason) { | 1506 void URLRequestHttpJob::DoneWithRequest(CompletionCause reason) { |
| 1491 if (done_) | 1507 if (done_) |
| 1492 return; | 1508 return; |
| 1493 done_ = true; | 1509 done_ = true; |
| 1494 RecordPerfHistograms(reason); | 1510 RecordPerfHistograms(reason); |
| 1495 if (reason == FINISHED) { | 1511 if (reason == FINISHED) { |
| 1496 request_->set_received_response_content_length(prefilter_bytes_read()); | 1512 request_->set_received_response_content_length(prefilter_bytes_read()); |
| 1497 RecordCompressionHistograms(); | 1513 RecordCompressionHistograms(); |
| 1498 } | 1514 } |
| 1499 } | 1515 } |
| 1500 | 1516 |
| 1501 HttpResponseHeaders* URLRequestHttpJob::GetResponseHeaders() const { | 1517 HttpResponseHeaders* URLRequestHttpJob::GetResponseHeaders() const { |
| 1502 DCHECK(transaction_.get()); | 1518 DCHECK(transaction_.get()); |
| 1503 DCHECK(transaction_->GetResponseInfo()); | 1519 DCHECK(transaction_->GetResponseInfo()); |
| 1504 return override_response_headers_.get() ? | 1520 return override_response_headers_.get() |
| 1505 override_response_headers_.get() : | 1521 ? override_response_headers_.get() |
| 1506 transaction_->GetResponseInfo()->headers.get(); | 1522 : transaction_->GetResponseInfo()->headers.get(); |
| 1507 } | 1523 } |
| 1508 | 1524 |
| 1509 void URLRequestHttpJob::NotifyURLRequestDestroyed() { | 1525 void URLRequestHttpJob::NotifyURLRequestDestroyed() { |
| 1510 awaiting_callback_ = false; | 1526 awaiting_callback_ = false; |
| 1511 } | 1527 } |
| 1512 | 1528 |
| 1513 } // namespace net | 1529 } // namespace net |
| OLD | NEW |