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/async_resource_handler.h" | 5 #include "content/browser/loader/async_resource_handler.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 11 matching lines...) Expand all Loading... | |
22 #include "content/browser/loader/resource_dispatcher_host_impl.h" | 22 #include "content/browser/loader/resource_dispatcher_host_impl.h" |
23 #include "content/browser/loader/resource_message_filter.h" | 23 #include "content/browser/loader/resource_message_filter.h" |
24 #include "content/browser/loader/resource_request_info_impl.h" | 24 #include "content/browser/loader/resource_request_info_impl.h" |
25 #include "content/browser/resource_context_impl.h" | 25 #include "content/browser/resource_context_impl.h" |
26 #include "content/common/resource_messages.h" | 26 #include "content/common/resource_messages.h" |
27 #include "content/common/resource_request_completion_status.h" | 27 #include "content/common/resource_request_completion_status.h" |
28 #include "content/common/view_messages.h" | 28 #include "content/common/view_messages.h" |
29 #include "content/public/browser/resource_dispatcher_host_delegate.h" | 29 #include "content/public/browser/resource_dispatcher_host_delegate.h" |
30 #include "content/public/common/content_features.h" | 30 #include "content/public/common/content_features.h" |
31 #include "content/public/common/resource_response.h" | 31 #include "content/public/common/resource_response.h" |
32 #include "mojo/message_pump/handle_watcher.h" | |
32 #include "net/base/io_buffer.h" | 33 #include "net/base/io_buffer.h" |
33 #include "net/base/load_flags.h" | 34 #include "net/base/load_flags.h" |
34 #include "net/log/net_log.h" | 35 #include "net/log/net_log.h" |
35 #include "net/url_request/redirect_info.h" | 36 #include "net/url_request/redirect_info.h" |
36 | 37 |
37 using base::TimeDelta; | 38 using base::TimeDelta; |
38 using base::TimeTicks; | 39 using base::TimeTicks; |
39 | 40 |
40 namespace content { | 41 namespace content { |
41 namespace { | 42 namespace { |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
184 public: | 185 public: |
185 DependentIOBuffer(ResourceBuffer* backing, char* memory) | 186 DependentIOBuffer(ResourceBuffer* backing, char* memory) |
186 : net::WrappedIOBuffer(memory), | 187 : net::WrappedIOBuffer(memory), |
187 backing_(backing) { | 188 backing_(backing) { |
188 } | 189 } |
189 private: | 190 private: |
190 ~DependentIOBuffer() override {} | 191 ~DependentIOBuffer() override {} |
191 scoped_refptr<ResourceBuffer> backing_; | 192 scoped_refptr<ResourceBuffer> backing_; |
192 }; | 193 }; |
193 | 194 |
194 AsyncResourceHandler::AsyncResourceHandler( | 195 class AsyncResourceHandler::MojoHelper final { |
mmenke
2016/05/23 17:34:53
Think this class needs some docs
yhirano
2016/05/24 06:40:02
Done.
| |
195 net::URLRequest* request, | 196 public: |
196 ResourceDispatcherHostImpl* rdh) | 197 explicit MojoHelper(AsyncResourceHandler* owner) : owner_(owner) {} |
198 | |
199 void OnResponseStarted() { | |
200 MojoCreateDataPipeOptions options; | |
201 options.struct_size = sizeof(MojoCreateDataPipeOptions); | |
202 options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; | |
203 options.element_num_bytes = 1; | |
204 options.capacity_num_bytes = kMaxAllocationSize; | |
205 mojo::DataPipe data_pipe(options); | |
206 | |
207 writer_ = std::move(data_pipe.producer_handle); | |
208 owner_->GetRequestInfo()->InstallBodyReader( | |
209 std::move(data_pipe.consumer_handle)); | |
210 } | |
211 | |
212 bool OnWillRead(scoped_refptr<net::IOBuffer>* buf, | |
213 int* buf_size, | |
214 int min_size) { | |
215 void* buffer = nullptr; | |
216 uint32_t available = 0; | |
217 MojoResult result = mojo::BeginWriteDataRaw( | |
218 writer_.get(), &buffer, &available, MOJO_WRITE_DATA_FLAG_NONE); | |
219 // Note that we cannot handle SHOULD_WAIT here. It should be handled in | |
220 // OnReadCompleted. | |
mmenke
2016/05/23 17:34:53
Avoid "we" in comments.
yhirano
2016/05/24 06:40:03
Done.
| |
221 if (result == MOJO_RESULT_OK) { | |
222 *buf = new net::WrappedIOBuffer(static_cast<const char*>(buffer)); | |
223 *buf_size = available; | |
224 return true; | |
225 } | |
226 return false; | |
227 } | |
228 | |
229 bool OnReadCompleted(int bytes_read, bool* defer) { | |
230 MojoResult result = mojo::EndWriteDataRaw(writer_.get(), bytes_read); | |
231 if (result != MOJO_RESULT_OK) | |
232 return false; | |
233 void* buffer = nullptr; | |
234 uint32_t available = 0; | |
235 // To see if we can continue writing. | |
236 result = mojo::BeginWriteDataRaw(writer_.get(), &buffer, &available, | |
237 MOJO_WRITE_DATA_FLAG_NONE); | |
238 if (result == MOJO_RESULT_SHOULD_WAIT || | |
239 (result == MOJO_RESULT_OK && available == 0)) { | |
240 *defer = owner_->did_defer_ = true; | |
241 owner_->OnDefer(); | |
242 handle_watcher_.Start( | |
243 writer_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE, | |
244 base::Bind(&MojoHelper::OnWritable, base::Unretained(this))); | |
245 } | |
246 if (result == MOJO_RESULT_OK) | |
247 mojo::EndWriteDataRaw(writer_.get(), 0); | |
248 return true; | |
249 } | |
250 | |
251 private: | |
252 void OnWritable(MojoResult result) { owner_->ResumeIfDeferred(); } | |
253 | |
254 mojo::ScopedDataPipeProducerHandle writer_; | |
255 mojo::common::HandleWatcher handle_watcher_; | |
256 AsyncResourceHandler* owner_; | |
257 | |
258 DISALLOW_COPY_AND_ASSIGN(MojoHelper); | |
259 }; | |
260 | |
261 AsyncResourceHandler::AsyncResourceHandler(net::URLRequest* request, | |
262 ResourceDispatcherHostImpl* rdh, | |
263 bool using_mojo_data_handle) | |
197 : ResourceHandler(request), | 264 : ResourceHandler(request), |
198 ResourceMessageDelegate(request), | 265 ResourceMessageDelegate(request), |
199 rdh_(rdh), | 266 rdh_(rdh), |
200 pending_data_count_(0), | 267 pending_data_count_(0), |
201 allocation_size_(0), | 268 allocation_size_(0), |
202 did_defer_(false), | 269 did_defer_(false), |
203 has_checked_for_sufficient_resources_(false), | 270 has_checked_for_sufficient_resources_(false), |
204 sent_received_response_msg_(false), | 271 sent_received_response_msg_(false), |
205 sent_data_buffer_msg_(false), | 272 sent_data_buffer_msg_(false), |
206 inlining_helper_(new InliningHelper), | 273 inlining_helper_(new InliningHelper), |
207 last_upload_position_(0), | 274 last_upload_position_(0), |
208 waiting_for_upload_progress_ack_(false), | 275 waiting_for_upload_progress_ack_(false), |
209 reported_transfer_size_(0) { | 276 reported_transfer_size_(0), |
277 mojo_helper_(using_mojo_data_handle ? new MojoHelper(this) : nullptr) { | |
210 InitializeResourceBufferConstants(); | 278 InitializeResourceBufferConstants(); |
211 } | 279 } |
212 | 280 |
213 AsyncResourceHandler::~AsyncResourceHandler() { | 281 AsyncResourceHandler::~AsyncResourceHandler() { |
214 if (has_checked_for_sufficient_resources_) | 282 if (has_checked_for_sufficient_resources_) |
215 rdh_->FinishedWithResourcesForRequest(request()); | 283 rdh_->FinishedWithResourcesForRequest(request()); |
216 } | 284 } |
217 | 285 |
218 bool AsyncResourceHandler::OnMessageReceived(const IPC::Message& message) { | 286 bool AsyncResourceHandler::OnMessageReceived(const IPC::Message& message) { |
219 bool handled = true; | 287 bool handled = true; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
348 // If the parent handler downloaded the resource to a file, grant the child | 416 // If the parent handler downloaded the resource to a file, grant the child |
349 // read permissions on it. | 417 // read permissions on it. |
350 if (!response->head.download_file_path.empty()) { | 418 if (!response->head.download_file_path.empty()) { |
351 rdh_->RegisterDownloadedTempFile( | 419 rdh_->RegisterDownloadedTempFile( |
352 info->GetChildID(), info->GetRequestID(), | 420 info->GetChildID(), info->GetRequestID(), |
353 response->head.download_file_path); | 421 response->head.download_file_path); |
354 } | 422 } |
355 | 423 |
356 response->head.request_start = request()->creation_time(); | 424 response->head.request_start = request()->creation_time(); |
357 response->head.response_start = TimeTicks::Now(); | 425 response->head.response_start = TimeTicks::Now(); |
426 if (mojo_helper_) | |
427 mojo_helper_->OnResponseStarted(); | |
428 | |
358 info->filter()->Send(new ResourceMsg_ReceivedResponse(GetRequestID(), | 429 info->filter()->Send(new ResourceMsg_ReceivedResponse(GetRequestID(), |
359 response->head)); | 430 response->head)); |
360 sent_received_response_msg_ = true; | 431 sent_received_response_msg_ = true; |
361 | 432 |
362 if (request()->response_info().metadata.get()) { | 433 if (request()->response_info().metadata.get()) { |
363 std::vector<char> copy(request()->response_info().metadata->data(), | 434 std::vector<char> copy(request()->response_info().metadata->data(), |
364 request()->response_info().metadata->data() + | 435 request()->response_info().metadata->data() + |
365 request()->response_info().metadata->size()); | 436 request()->response_info().metadata->size()); |
366 info->filter()->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), | 437 info->filter()->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), |
367 copy)); | 438 copy)); |
(...skipping 21 matching lines...) Expand all Loading... | |
389 } | 460 } |
390 | 461 |
391 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, | 462 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
392 int* buf_size, | 463 int* buf_size, |
393 int min_size) { | 464 int min_size) { |
394 DCHECK_EQ(-1, min_size); | 465 DCHECK_EQ(-1, min_size); |
395 | 466 |
396 if (!CheckForSufficientResource()) | 467 if (!CheckForSufficientResource()) |
397 return false; | 468 return false; |
398 | 469 |
470 if (mojo_helper_) | |
471 return mojo_helper_->OnWillRead(buf, buf_size, min_size); | |
mmenke
2016/05/23 17:34:53
When using the helper, we also send the results ov
yhirano
2016/05/24 06:40:03
No.
| |
472 | |
399 // Return early if InliningHelper allocates the buffer, so that we should | 473 // Return early if InliningHelper allocates the buffer, so that we should |
400 // inline the data into the IPC message without allocating SharedMemory. | 474 // inline the data into the IPC message without allocating SharedMemory. |
401 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) | 475 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) |
402 return true; | 476 return true; |
403 | 477 |
404 if (!EnsureResourceBufferIsInitialized()) | 478 if (!EnsureResourceBufferIsInitialized()) |
405 return false; | 479 return false; |
406 | 480 |
407 DCHECK(buffer_->CanAllocate()); | 481 DCHECK(buffer_->CanAllocate()); |
408 char* memory = buffer_->Allocate(&allocation_size_); | 482 char* memory = buffer_->Allocate(&allocation_size_); |
409 CHECK(memory); | 483 CHECK(memory); |
410 | 484 |
411 *buf = new DependentIOBuffer(buffer_.get(), memory); | 485 *buf = new DependentIOBuffer(buffer_.get(), memory); |
412 *buf_size = allocation_size_; | 486 *buf_size = allocation_size_; |
413 | 487 |
414 return true; | 488 return true; |
415 } | 489 } |
416 | 490 |
417 bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { | 491 bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { |
418 DCHECK_GE(bytes_read, 0); | 492 DCHECK_GE(bytes_read, 0); |
419 | 493 |
420 if (!bytes_read) | 494 if (!bytes_read) |
421 return true; | 495 return true; |
422 | 496 |
497 if (mojo_helper_) | |
498 return mojo_helper_->OnReadCompleted(bytes_read, defer); | |
499 | |
423 ResourceMessageFilter* filter = GetFilter(); | 500 ResourceMessageFilter* filter = GetFilter(); |
424 if (!filter) | 501 if (!filter) |
425 return false; | 502 return false; |
426 | 503 |
427 int encoded_data_length = CalculateEncodedDataLengthToReport(); | 504 int encoded_data_length = CalculateEncodedDataLengthToReport(); |
428 | 505 |
429 // Return early if InliningHelper handled the received data. | 506 // Return early if InliningHelper handled the received data. |
430 if (inlining_helper_->SendInlinedDataIfApplicable( | 507 if (inlining_helper_->SendInlinedDataIfApplicable( |
431 bytes_read, encoded_data_length, filter, GetRequestID())) | 508 bytes_read, encoded_data_length, filter, GetRequestID())) |
432 return true; | 509 return true; |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
587 } else { | 664 } else { |
588 UMA_HISTOGRAM_CUSTOM_COUNTS( | 665 UMA_HISTOGRAM_CUSTOM_COUNTS( |
589 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", | 666 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", |
590 elapsed_time, 1, 100000, 100); | 667 elapsed_time, 1, 100000, 100); |
591 } | 668 } |
592 | 669 |
593 inlining_helper_->RecordHistogram(elapsed_time); | 670 inlining_helper_->RecordHistogram(elapsed_time); |
594 } | 671 } |
595 | 672 |
596 } // namespace content | 673 } // namespace content |
OLD | NEW |