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/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.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 22 matching lines...) Expand all Loading... | |
33 #include "net/ssl/client_cert_store.h" | 33 #include "net/ssl/client_cert_store.h" |
34 #include "net/url_request/redirect_info.h" | 34 #include "net/url_request/redirect_info.h" |
35 #include "net/url_request/url_request_status.h" | 35 #include "net/url_request/url_request_status.h" |
36 | 36 |
37 using base::TimeDelta; | 37 using base::TimeDelta; |
38 using base::TimeTicks; | 38 using base::TimeTicks; |
39 | 39 |
40 namespace content { | 40 namespace content { |
41 namespace { | 41 namespace { |
42 | 42 |
43 // The interval for calls to ResourceLoader::ReportUploadProgress. | |
44 const int kUploadProgressIntervalMsec = 100; | |
45 | |
43 void PopulateResourceResponse(ResourceRequestInfoImpl* info, | 46 void PopulateResourceResponse(ResourceRequestInfoImpl* info, |
44 net::URLRequest* request, | 47 net::URLRequest* request, |
45 ResourceResponse* response) { | 48 ResourceResponse* response) { |
46 response->head.request_time = request->request_time(); | 49 response->head.request_time = request->request_time(); |
47 response->head.response_time = request->response_time(); | 50 response->head.response_time = request->response_time(); |
48 response->head.headers = request->response_headers(); | 51 response->head.headers = request->response_headers(); |
49 request->GetCharset(&response->head.charset); | 52 request->GetCharset(&response->head.charset); |
50 response->head.content_length = request->GetExpectedContentSize(); | 53 response->head.content_length = request->GetExpectedContentSize(); |
51 request->GetMimeType(&response->head.mime_type); | 54 request->GetMimeType(&response->head.mime_type); |
52 net::HttpResponseInfo response_info = request->response_info(); | 55 net::HttpResponseInfo response_info = request->response_info(); |
(...skipping 27 matching lines...) Expand all Loading... | |
80 } // namespace | 83 } // namespace |
81 | 84 |
82 ResourceLoader::ResourceLoader(scoped_ptr<net::URLRequest> request, | 85 ResourceLoader::ResourceLoader(scoped_ptr<net::URLRequest> request, |
83 scoped_ptr<ResourceHandler> handler, | 86 scoped_ptr<ResourceHandler> handler, |
84 ResourceLoaderDelegate* delegate) | 87 ResourceLoaderDelegate* delegate) |
85 : deferred_stage_(DEFERRED_NONE), | 88 : deferred_stage_(DEFERRED_NONE), |
86 request_(request.Pass()), | 89 request_(request.Pass()), |
87 handler_(handler.Pass()), | 90 handler_(handler.Pass()), |
88 delegate_(delegate), | 91 delegate_(delegate), |
89 last_upload_position_(0), | 92 last_upload_position_(0), |
90 waiting_for_upload_progress_ack_(false), | |
91 is_transferring_(false), | 93 is_transferring_(false), |
92 weak_ptr_factory_(this) { | 94 weak_ptr_factory_(this) { |
93 request_->set_delegate(this); | 95 request_->set_delegate(this); |
94 handler_->SetController(this); | 96 handler_->SetController(this); |
95 } | 97 } |
96 | 98 |
97 ResourceLoader::~ResourceLoader() { | 99 ResourceLoader::~ResourceLoader() { |
98 if (login_delegate_.get()) | 100 if (login_delegate_.get()) |
99 login_delegate_->OnRequestCancelled(); | 101 login_delegate_->OnRequestCancelled(); |
100 ssl_client_auth_handler_.reset(); | 102 ssl_client_auth_handler_.reset(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
132 ResourceRequestInfoImpl* info = GetRequestInfo(); | 134 ResourceRequestInfoImpl* info = GetRequestInfo(); |
133 info->set_was_ignored_by_handler(true); | 135 info->set_was_ignored_by_handler(true); |
134 CancelRequest(false); | 136 CancelRequest(false); |
135 } | 137 } |
136 | 138 |
137 void ResourceLoader::CancelWithError(int error_code) { | 139 void ResourceLoader::CancelWithError(int error_code) { |
138 CancelRequestInternal(error_code, false); | 140 CancelRequestInternal(error_code, false); |
139 } | 141 } |
140 | 142 |
141 void ResourceLoader::ReportUploadProgress() { | 143 void ResourceLoader::ReportUploadProgress() { |
142 if (waiting_for_upload_progress_ack_) | |
143 return; // Send one progress event at a time. | |
144 | |
145 net::UploadProgress progress = request_->GetUploadProgress(); | 144 net::UploadProgress progress = request_->GetUploadProgress(); |
146 if (!progress.size()) | 145 if (!progress.size()) |
147 return; // Nothing to upload. | 146 return; // Nothing to upload. |
mmenke
2015/05/20 20:05:41
BUG: A request will return a size of 0 until it a
Andre
2015/05/20 21:05:12
Thanks. Changed to use a RepeatingTimer.
| |
148 | 147 |
149 if (progress.position() == last_upload_position_) | |
150 return; // No progress made since last time. | |
151 | |
152 const uint64 kHalfPercentIncrements = 200; | 148 const uint64 kHalfPercentIncrements = 200; |
153 const TimeDelta kOneSecond = TimeDelta::FromMilliseconds(1000); | 149 const TimeDelta kOneSecond = TimeDelta::FromMilliseconds(1000); |
154 | 150 |
155 uint64 amt_since_last = progress.position() - last_upload_position_; | 151 uint64 amt_since_last = progress.position() - last_upload_position_; |
156 TimeDelta time_since_last = TimeTicks::Now() - last_upload_ticks_; | 152 TimeDelta time_since_last = TimeTicks::Now() - last_upload_ticks_; |
157 | 153 |
158 bool is_finished = (progress.size() == progress.position()); | 154 bool is_finished = (progress.size() == progress.position()); |
159 bool enough_new_progress = | 155 bool enough_new_progress = |
160 (amt_since_last > (progress.size() / kHalfPercentIncrements)); | 156 (amt_since_last > (progress.size() / kHalfPercentIncrements)); |
161 bool too_much_time_passed = time_since_last > kOneSecond; | 157 bool too_much_time_passed = time_since_last > kOneSecond; |
162 | 158 |
163 if (is_finished || enough_new_progress || too_much_time_passed) { | 159 if (is_finished || enough_new_progress || too_much_time_passed) { |
164 ResourceRequestInfoImpl* info = GetRequestInfo(); | 160 handler_->OnUploadProgress(progress.position(), progress.size()); |
165 if (info->is_upload_progress_enabled()) { | |
166 handler_->OnUploadProgress(progress.position(), progress.size()); | |
167 waiting_for_upload_progress_ack_ = true; | |
168 } | |
169 last_upload_ticks_ = TimeTicks::Now(); | 161 last_upload_ticks_ = TimeTicks::Now(); |
170 last_upload_position_ = progress.position(); | 162 last_upload_position_ = progress.position(); |
mmenke
2015/05/20 20:05:41
BUG: In the redirect case, we'll start uploading
Andre
2015/05/20 21:05:11
Now using a RepeatingTimer until OnResponseStarted
| |
163 } else { | |
164 ScheduleReportUploadProgress(); | |
171 } | 165 } |
172 } | 166 } |
173 | 167 |
174 void ResourceLoader::MarkAsTransferring() { | 168 void ResourceLoader::MarkAsTransferring() { |
175 CHECK(IsResourceTypeFrame(GetRequestInfo()->GetResourceType())) | 169 CHECK(IsResourceTypeFrame(GetRequestInfo()->GetResourceType())) |
176 << "Can only transfer for navigations"; | 170 << "Can only transfer for navigations"; |
177 is_transferring_ = true; | 171 is_transferring_ = true; |
178 | 172 |
179 int child_id = GetRequestInfo()->GetChildID(); | 173 int child_id = GetRequestInfo()->GetChildID(); |
180 AppCacheInterceptor::PrepareForCrossSiteTransfer(request(), child_id); | 174 AppCacheInterceptor::PrepareForCrossSiteTransfer(request(), child_id); |
(...skipping 29 matching lines...) Expand all Loading... | |
210 | 204 |
211 ResourceRequestInfoImpl* ResourceLoader::GetRequestInfo() { | 205 ResourceRequestInfoImpl* ResourceLoader::GetRequestInfo() { |
212 return ResourceRequestInfoImpl::ForRequest(request_.get()); | 206 return ResourceRequestInfoImpl::ForRequest(request_.get()); |
213 } | 207 } |
214 | 208 |
215 void ResourceLoader::ClearLoginDelegate() { | 209 void ResourceLoader::ClearLoginDelegate() { |
216 login_delegate_ = NULL; | 210 login_delegate_ = NULL; |
217 } | 211 } |
218 | 212 |
219 void ResourceLoader::OnUploadProgressACK() { | 213 void ResourceLoader::OnUploadProgressACK() { |
220 waiting_for_upload_progress_ack_ = false; | 214 if (last_upload_position_ < request_->GetUploadProgress().size()) |
215 ScheduleReportUploadProgress(); | |
221 } | 216 } |
222 | 217 |
223 void ResourceLoader::OnReceivedRedirect(net::URLRequest* unused, | 218 void ResourceLoader::OnReceivedRedirect(net::URLRequest* unused, |
224 const net::RedirectInfo& redirect_info, | 219 const net::RedirectInfo& redirect_info, |
225 bool* defer) { | 220 bool* defer) { |
226 DCHECK_EQ(request_.get(), unused); | 221 DCHECK_EQ(request_.get(), unused); |
227 | 222 |
228 VLOG(1) << "OnReceivedRedirect: " << request_->url().spec(); | 223 VLOG(1) << "OnReceivedRedirect: " << request_->url().spec(); |
229 DCHECK(request_->status().is_success()); | 224 DCHECK(request_->status().is_success()); |
230 | 225 |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
344 request_->url(), | 339 request_->url(), |
345 info->GetResourceType())) { | 340 info->GetResourceType())) { |
346 Cancel(); | 341 Cancel(); |
347 return; | 342 return; |
348 } | 343 } |
349 | 344 |
350 if (!request_->status().is_success()) { | 345 if (!request_->status().is_success()) { |
351 ResponseCompleted(); | 346 ResponseCompleted(); |
352 return; | 347 return; |
353 } | 348 } |
354 | 349 |
mmenke
2015/05/20 20:05:41
Why did you remove the code here?
Andre
2015/05/20 21:05:12
Because the way I was posting a delayed task in On
| |
355 // We want to send a final upload progress message prior to sending the | |
356 // response complete message even if we're waiting for an ack to to a | |
357 // previous upload progress message. | |
358 waiting_for_upload_progress_ack_ = false; | |
359 ReportUploadProgress(); | |
360 | |
361 CompleteResponseStarted(); | 350 CompleteResponseStarted(); |
362 | 351 |
363 if (is_deferred()) | 352 if (is_deferred()) |
364 return; | 353 return; |
365 | 354 |
366 if (request_->status().is_success()) | 355 if (request_->status().is_success()) |
367 StartReading(false); // Read the first chunk. | 356 StartReading(false); // Read the first chunk. |
368 else | 357 else |
369 ResponseCompleted(); | 358 ResponseCompleted(); |
370 } | 359 } |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
489 void ResourceLoader::StartRequestInternal() { | 478 void ResourceLoader::StartRequestInternal() { |
490 DCHECK(!request_->is_pending()); | 479 DCHECK(!request_->is_pending()); |
491 | 480 |
492 if (!request_->status().is_success()) { | 481 if (!request_->status().is_success()) { |
493 return; | 482 return; |
494 } | 483 } |
495 | 484 |
496 request_->Start(); | 485 request_->Start(); |
497 | 486 |
498 delegate_->DidStartRequest(this); | 487 delegate_->DidStartRequest(this); |
488 | |
489 if (GetRequestInfo()->is_upload_progress_enabled()) | |
490 ScheduleReportUploadProgress(); | |
499 } | 491 } |
500 | 492 |
501 void ResourceLoader::CancelRequestInternal(int error, bool from_renderer) { | 493 void ResourceLoader::CancelRequestInternal(int error, bool from_renderer) { |
502 VLOG(1) << "CancelRequestInternal: " << request_->url().spec(); | 494 VLOG(1) << "CancelRequestInternal: " << request_->url().spec(); |
503 | 495 |
504 ResourceRequestInfoImpl* info = GetRequestInfo(); | 496 ResourceRequestInfoImpl* info = GetRequestInfo(); |
505 | 497 |
506 // WebKit will send us a cancel for downloads since it no longer handles | 498 // WebKit will send us a cancel for downloads since it no longer handles |
507 // them. In this case, ignore the cancel since we handle downloads in the | 499 // them. In this case, ignore the cancel since we handle downloads in the |
508 // browser. | 500 // browser. |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
719 } else { | 711 } else { |
720 // This will result in our destruction. | 712 // This will result in our destruction. |
721 CallDidFinishLoading(); | 713 CallDidFinishLoading(); |
722 } | 714 } |
723 } | 715 } |
724 | 716 |
725 void ResourceLoader::CallDidFinishLoading() { | 717 void ResourceLoader::CallDidFinishLoading() { |
726 delegate_->DidFinishLoading(this); | 718 delegate_->DidFinishLoading(this); |
727 } | 719 } |
728 | 720 |
721 void ResourceLoader::ScheduleReportUploadProgress() { | |
722 base::MessageLoop::current()->PostDelayedTask( | |
723 FROM_HERE, | |
724 base::Bind(&ResourceLoader::ReportUploadProgress, | |
725 weak_ptr_factory_.GetWeakPtr()), | |
726 base::TimeDelta::FromMilliseconds(kUploadProgressIntervalMsec)); | |
727 } | |
728 | |
729 void ResourceLoader::RecordHistograms() { | 729 void ResourceLoader::RecordHistograms() { |
730 ResourceRequestInfoImpl* info = GetRequestInfo(); | 730 ResourceRequestInfoImpl* info = GetRequestInfo(); |
731 | 731 |
732 if (info->GetResourceType() == RESOURCE_TYPE_PREFETCH) { | 732 if (info->GetResourceType() == RESOURCE_TYPE_PREFETCH) { |
733 PrefetchStatus status = STATUS_UNDEFINED; | 733 PrefetchStatus status = STATUS_UNDEFINED; |
734 TimeDelta total_time = base::TimeTicks::Now() - request_->creation_time(); | 734 TimeDelta total_time = base::TimeTicks::Now() - request_->creation_time(); |
735 | 735 |
736 switch (request_->status().status()) { | 736 switch (request_->status().status()) { |
737 case net::URLRequestStatus::SUCCESS: | 737 case net::URLRequestStatus::SUCCESS: |
738 if (request_->was_cached()) { | 738 if (request_->was_cached()) { |
(...skipping 14 matching lines...) Expand all Loading... | |
753 case net::URLRequestStatus::FAILED: | 753 case net::URLRequestStatus::FAILED: |
754 status = STATUS_UNDEFINED; | 754 status = STATUS_UNDEFINED; |
755 break; | 755 break; |
756 } | 756 } |
757 | 757 |
758 UMA_HISTOGRAM_ENUMERATION("Net.Prefetch.Pattern", status, STATUS_MAX); | 758 UMA_HISTOGRAM_ENUMERATION("Net.Prefetch.Pattern", status, STATUS_MAX); |
759 } | 759 } |
760 } | 760 } |
761 | 761 |
762 } // namespace content | 762 } // namespace content |
OLD | NEW |