| 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 "content/browser/loader/resource_loader.h" | 5 #include "content/browser/loader/resource_loader.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
| 10 #include "base/profiler/scoped_tracker.h" | 10 #include "base/profiler/scoped_tracker.h" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 #include "net/ssl/client_cert_store.h" | 37 #include "net/ssl/client_cert_store.h" |
| 38 #include "net/url_request/redirect_info.h" | 38 #include "net/url_request/redirect_info.h" |
| 39 #include "net/url_request/url_request_status.h" | 39 #include "net/url_request/url_request_status.h" |
| 40 | 40 |
| 41 using base::TimeDelta; | 41 using base::TimeDelta; |
| 42 using base::TimeTicks; | 42 using base::TimeTicks; |
| 43 | 43 |
| 44 namespace content { | 44 namespace content { |
| 45 namespace { | 45 namespace { |
| 46 | 46 |
| 47 // The interval for calls to ResourceLoader::ReportUploadProgress. | |
| 48 const int kUploadProgressIntervalMsec = 100; | |
| 49 | |
| 50 void StoreSignedCertificateTimestamps( | 47 void StoreSignedCertificateTimestamps( |
| 51 const net::SignedCertificateTimestampAndStatusList& sct_list, | 48 const net::SignedCertificateTimestampAndStatusList& sct_list, |
| 52 int process_id, | 49 int process_id, |
| 53 SignedCertificateTimestampIDStatusList* sct_ids) { | 50 SignedCertificateTimestampIDStatusList* sct_ids) { |
| 54 SignedCertificateTimestampStore* sct_store( | 51 SignedCertificateTimestampStore* sct_store( |
| 55 SignedCertificateTimestampStore::GetInstance()); | 52 SignedCertificateTimestampStore::GetInstance()); |
| 56 | 53 |
| 57 for (auto iter = sct_list.begin(); iter != sct_list.end(); ++iter) { | 54 for (auto iter = sct_list.begin(); iter != sct_list.end(); ++iter) { |
| 58 const int sct_id(sct_store->Store(iter->sct.get(), process_id)); | 55 const int sct_id(sct_store->Store(iter->sct.get(), process_id)); |
| 59 sct_ids->push_back( | 56 sct_ids->push_back( |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 | 124 |
| 128 } // namespace | 125 } // namespace |
| 129 | 126 |
| 130 ResourceLoader::ResourceLoader(scoped_ptr<net::URLRequest> request, | 127 ResourceLoader::ResourceLoader(scoped_ptr<net::URLRequest> request, |
| 131 scoped_ptr<ResourceHandler> handler, | 128 scoped_ptr<ResourceHandler> handler, |
| 132 ResourceLoaderDelegate* delegate) | 129 ResourceLoaderDelegate* delegate) |
| 133 : deferred_stage_(DEFERRED_NONE), | 130 : deferred_stage_(DEFERRED_NONE), |
| 134 request_(request.Pass()), | 131 request_(request.Pass()), |
| 135 handler_(handler.Pass()), | 132 handler_(handler.Pass()), |
| 136 delegate_(delegate), | 133 delegate_(delegate), |
| 137 last_upload_position_(0), | |
| 138 waiting_for_upload_progress_ack_(false), | |
| 139 is_transferring_(false), | 134 is_transferring_(false), |
| 140 times_cancelled_before_request_start_(0), | 135 times_cancelled_before_request_start_(0), |
| 141 started_request_(false), | 136 started_request_(false), |
| 142 times_cancelled_after_request_start_(0), | 137 times_cancelled_after_request_start_(0), |
| 143 weak_ptr_factory_(this) { | 138 weak_ptr_factory_(this) { |
| 144 request_->set_delegate(this); | 139 request_->set_delegate(this); |
| 145 handler_->SetController(this); | 140 handler_->SetController(this); |
| 146 } | 141 } |
| 147 | 142 |
| 148 ResourceLoader::~ResourceLoader() { | 143 ResourceLoader::~ResourceLoader() { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 void ResourceLoader::CancelAndIgnore() { | 177 void ResourceLoader::CancelAndIgnore() { |
| 183 ResourceRequestInfoImpl* info = GetRequestInfo(); | 178 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 184 info->set_was_ignored_by_handler(true); | 179 info->set_was_ignored_by_handler(true); |
| 185 CancelRequest(false); | 180 CancelRequest(false); |
| 186 } | 181 } |
| 187 | 182 |
| 188 void ResourceLoader::CancelWithError(int error_code) { | 183 void ResourceLoader::CancelWithError(int error_code) { |
| 189 CancelRequestInternal(error_code, false); | 184 CancelRequestInternal(error_code, false); |
| 190 } | 185 } |
| 191 | 186 |
| 192 void ResourceLoader::ReportUploadProgress() { | |
| 193 DCHECK(GetRequestInfo()->is_upload_progress_enabled()); | |
| 194 | |
| 195 if (waiting_for_upload_progress_ack_) | |
| 196 return; // Send one progress event at a time. | |
| 197 | |
| 198 net::UploadProgress progress = request_->GetUploadProgress(); | |
| 199 if (!progress.size()) | |
| 200 return; // Nothing to upload. | |
| 201 | |
| 202 if (progress.position() == last_upload_position_) | |
| 203 return; // No progress made since last time. | |
| 204 | |
| 205 const uint64 kHalfPercentIncrements = 200; | |
| 206 const TimeDelta kOneSecond = TimeDelta::FromMilliseconds(1000); | |
| 207 | |
| 208 uint64 amt_since_last = progress.position() - last_upload_position_; | |
| 209 TimeDelta time_since_last = TimeTicks::Now() - last_upload_ticks_; | |
| 210 | |
| 211 bool is_finished = (progress.size() == progress.position()); | |
| 212 bool enough_new_progress = | |
| 213 (amt_since_last > (progress.size() / kHalfPercentIncrements)); | |
| 214 bool too_much_time_passed = time_since_last > kOneSecond; | |
| 215 | |
| 216 if (is_finished || enough_new_progress || too_much_time_passed) { | |
| 217 handler_->OnUploadProgress(progress.position(), progress.size()); | |
| 218 waiting_for_upload_progress_ack_ = true; | |
| 219 last_upload_ticks_ = TimeTicks::Now(); | |
| 220 last_upload_position_ = progress.position(); | |
| 221 } | |
| 222 } | |
| 223 | |
| 224 void ResourceLoader::MarkAsTransferring() { | 187 void ResourceLoader::MarkAsTransferring() { |
| 225 CHECK(IsResourceTypeFrame(GetRequestInfo()->GetResourceType())) | 188 CHECK(IsResourceTypeFrame(GetRequestInfo()->GetResourceType())) |
| 226 << "Can only transfer for navigations"; | 189 << "Can only transfer for navigations"; |
| 227 is_transferring_ = true; | 190 is_transferring_ = true; |
| 228 | 191 |
| 229 int child_id = GetRequestInfo()->GetChildID(); | 192 int child_id = GetRequestInfo()->GetChildID(); |
| 230 AppCacheInterceptor::PrepareForCrossSiteTransfer(request(), child_id); | 193 AppCacheInterceptor::PrepareForCrossSiteTransfer(request(), child_id); |
| 231 ServiceWorkerRequestHandler* handler = | 194 ServiceWorkerRequestHandler* handler = |
| 232 ServiceWorkerRequestHandler::GetHandler(request()); | 195 ServiceWorkerRequestHandler::GetHandler(request()); |
| 233 if (handler) | 196 if (handler) |
| (...skipping 25 matching lines...) Expand all Loading... |
| 259 } | 222 } |
| 260 | 223 |
| 261 ResourceRequestInfoImpl* ResourceLoader::GetRequestInfo() { | 224 ResourceRequestInfoImpl* ResourceLoader::GetRequestInfo() { |
| 262 return ResourceRequestInfoImpl::ForRequest(request_.get()); | 225 return ResourceRequestInfoImpl::ForRequest(request_.get()); |
| 263 } | 226 } |
| 264 | 227 |
| 265 void ResourceLoader::ClearLoginDelegate() { | 228 void ResourceLoader::ClearLoginDelegate() { |
| 266 login_delegate_ = NULL; | 229 login_delegate_ = NULL; |
| 267 } | 230 } |
| 268 | 231 |
| 269 void ResourceLoader::OnUploadProgressACK() { | |
| 270 waiting_for_upload_progress_ack_ = false; | |
| 271 } | |
| 272 | |
| 273 void ResourceLoader::OnReceivedRedirect(net::URLRequest* unused, | 232 void ResourceLoader::OnReceivedRedirect(net::URLRequest* unused, |
| 274 const net::RedirectInfo& redirect_info, | 233 const net::RedirectInfo& redirect_info, |
| 275 bool* defer) { | 234 bool* defer) { |
| 276 DCHECK_EQ(request_.get(), unused); | 235 DCHECK_EQ(request_.get(), unused); |
| 277 | 236 |
| 278 DVLOG(1) << "OnReceivedRedirect: " << request_->url().spec(); | 237 DVLOG(1) << "OnReceivedRedirect: " << request_->url().spec(); |
| 279 DCHECK(request_->status().is_success()); | 238 DCHECK(request_->status().is_success()); |
| 280 | 239 |
| 281 ResourceRequestInfoImpl* info = GetRequestInfo(); | 240 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 282 | 241 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 } else if (*defer) { | 336 } else if (*defer) { |
| 378 deferred_stage_ = DEFERRED_NETWORK_START; | 337 deferred_stage_ = DEFERRED_NETWORK_START; |
| 379 } | 338 } |
| 380 } | 339 } |
| 381 | 340 |
| 382 void ResourceLoader::OnResponseStarted(net::URLRequest* unused) { | 341 void ResourceLoader::OnResponseStarted(net::URLRequest* unused) { |
| 383 DCHECK_EQ(request_.get(), unused); | 342 DCHECK_EQ(request_.get(), unused); |
| 384 | 343 |
| 385 DVLOG(1) << "OnResponseStarted: " << request_->url().spec(); | 344 DVLOG(1) << "OnResponseStarted: " << request_->url().spec(); |
| 386 | 345 |
| 387 progress_timer_.Stop(); | |
| 388 | |
| 389 if (!request_->status().is_success()) { | 346 if (!request_->status().is_success()) { |
| 390 ResponseCompleted(); | 347 ResponseCompleted(); |
| 391 return; | 348 return; |
| 392 } | 349 } |
| 393 | 350 |
| 394 // We want to send a final upload progress message prior to sending the | |
| 395 // response complete message even if we're waiting for an ack to to a | |
| 396 // previous upload progress message. | |
| 397 ResourceRequestInfoImpl* info = GetRequestInfo(); | |
| 398 if (info->is_upload_progress_enabled()) { | |
| 399 waiting_for_upload_progress_ack_ = false; | |
| 400 ReportUploadProgress(); | |
| 401 } | |
| 402 | |
| 403 CompleteResponseStarted(); | 351 CompleteResponseStarted(); |
| 404 | 352 |
| 405 if (is_deferred()) | 353 if (is_deferred()) |
| 406 return; | 354 return; |
| 407 | 355 |
| 408 if (request_->status().is_success()) | 356 if (request_->status().is_success()) |
| 409 StartReading(false); // Read the first chunk. | 357 StartReading(false); // Read the first chunk. |
| 410 else | 358 else |
| 411 ResponseCompleted(); | 359 ResponseCompleted(); |
| 412 } | 360 } |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 DCHECK(!request_->is_pending()); | 477 DCHECK(!request_->is_pending()); |
| 530 | 478 |
| 531 if (!request_->status().is_success()) { | 479 if (!request_->status().is_success()) { |
| 532 return; | 480 return; |
| 533 } | 481 } |
| 534 | 482 |
| 535 started_request_ = true; | 483 started_request_ = true; |
| 536 request_->Start(); | 484 request_->Start(); |
| 537 | 485 |
| 538 delegate_->DidStartRequest(this); | 486 delegate_->DidStartRequest(this); |
| 539 | |
| 540 if (GetRequestInfo()->is_upload_progress_enabled() && | |
| 541 request_->has_upload()) { | |
| 542 progress_timer_.Start( | |
| 543 FROM_HERE, | |
| 544 base::TimeDelta::FromMilliseconds(kUploadProgressIntervalMsec), | |
| 545 this, | |
| 546 &ResourceLoader::ReportUploadProgress); | |
| 547 } | |
| 548 } | 487 } |
| 549 | 488 |
| 550 void ResourceLoader::CancelRequestInternal(int error, bool from_renderer) { | 489 void ResourceLoader::CancelRequestInternal(int error, bool from_renderer) { |
| 551 DVLOG(1) << "CancelRequestInternal: " << request_->url().spec(); | 490 DVLOG(1) << "CancelRequestInternal: " << request_->url().spec(); |
| 552 | 491 |
| 553 ResourceRequestInfoImpl* info = GetRequestInfo(); | 492 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 554 | 493 |
| 555 // WebKit will send us a cancel for downloads since it no longer handles | 494 // WebKit will send us a cancel for downloads since it no longer handles |
| 556 // them. In this case, ignore the cancel since we handle downloads in the | 495 // them. In this case, ignore the cancel since we handle downloads in the |
| 557 // browser. | 496 // browser. |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 case net::URLRequestStatus::FAILED: | 701 case net::URLRequestStatus::FAILED: |
| 763 status = STATUS_UNDEFINED; | 702 status = STATUS_UNDEFINED; |
| 764 break; | 703 break; |
| 765 } | 704 } |
| 766 | 705 |
| 767 UMA_HISTOGRAM_ENUMERATION("Net.Prefetch.Pattern", status, STATUS_MAX); | 706 UMA_HISTOGRAM_ENUMERATION("Net.Prefetch.Pattern", status, STATUS_MAX); |
| 768 } | 707 } |
| 769 } | 708 } |
| 770 | 709 |
| 771 } // namespace content | 710 } // namespace content |
| OLD | NEW |