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 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc
e-loading | 5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc
e-loading |
6 | 6 |
7 #include "content/child/resource_dispatcher.h" | 7 #include "content/child/resource_dispatcher.h" |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
13 #include "base/debug/alias.h" | 13 #include "base/debug/alias.h" |
14 #include "base/debug/dump_without_crashing.h" | 14 #include "base/debug/dump_without_crashing.h" |
15 #include "base/debug/stack_trace.h" | 15 #include "base/debug/stack_trace.h" |
16 #include "base/feature_list.h" | 16 #include "base/feature_list.h" |
17 #include "base/files/file_path.h" | 17 #include "base/files/file_path.h" |
18 #include "base/memory/ptr_util.h" | 18 #include "base/memory/ptr_util.h" |
19 #include "base/memory/shared_memory.h" | 19 #include "base/memory/shared_memory.h" |
20 #include "base/message_loop/message_loop.h" | 20 #include "base/message_loop/message_loop.h" |
21 #include "base/metrics/histogram.h" | 21 #include "base/metrics/histogram.h" |
22 #include "base/rand_util.h" | 22 #include "base/rand_util.h" |
23 #include "base/strings/string_util.h" | 23 #include "base/strings/string_util.h" |
24 #include "build/build_config.h" | 24 #include "build/build_config.h" |
| 25 #include "content/child/body_consumer.h" |
25 #include "content/child/request_extra_data.h" | 26 #include "content/child/request_extra_data.h" |
26 #include "content/child/request_info.h" | 27 #include "content/child/request_info.h" |
27 #include "content/child/resource_scheduling_filter.h" | 28 #include "content/child/resource_scheduling_filter.h" |
28 #include "content/child/shared_memory_received_data_factory.h" | 29 #include "content/child/shared_memory_received_data_factory.h" |
29 #include "content/child/site_isolation_stats_gatherer.h" | 30 #include "content/child/site_isolation_stats_gatherer.h" |
30 #include "content/child/sync_load_response.h" | 31 #include "content/child/sync_load_response.h" |
31 #include "content/common/inter_process_time_ticks_converter.h" | 32 #include "content/common/inter_process_time_ticks_converter.h" |
32 #include "content/common/navigation_params.h" | 33 #include "content/common/navigation_params.h" |
33 #include "content/common/resource_messages.h" | 34 #include "content/common/resource_messages.h" |
| 35 #include "content/common/url_loader_type_converters.h" |
34 #include "content/public/child/fixed_received_data.h" | 36 #include "content/public/child/fixed_received_data.h" |
35 #include "content/public/child/request_peer.h" | 37 #include "content/public/child/request_peer.h" |
36 #include "content/public/child/resource_dispatcher_delegate.h" | 38 #include "content/public/child/resource_dispatcher_delegate.h" |
37 #include "content/public/common/content_features.h" | 39 #include "content/public/common/content_features.h" |
38 #include "content/public/common/resource_response.h" | 40 #include "content/public/common/resource_response.h" |
39 #include "content/public/common/resource_type.h" | 41 #include "content/public/common/resource_type.h" |
| 42 #include "mojo/public/cpp/bindings/binding.h" |
40 #include "net/base/net_errors.h" | 43 #include "net/base/net_errors.h" |
41 #include "net/base/request_priority.h" | 44 #include "net/base/request_priority.h" |
42 #include "net/http/http_response_headers.h" | 45 #include "net/http/http_response_headers.h" |
43 | 46 |
44 namespace content { | 47 namespace content { |
45 | 48 |
46 namespace { | 49 namespace { |
47 | 50 |
48 // Converts |time| from a remote to local TimeTicks, overwriting the original | 51 // Converts |time| from a remote to local TimeTicks, overwriting the original |
49 // value. | 52 // value. |
(...skipping 14 matching lines...) Expand all Loading... |
64 | 67 |
65 // Each resource request is assigned an ID scoped to this process. | 68 // Each resource request is assigned an ID scoped to this process. |
66 int MakeRequestID() { | 69 int MakeRequestID() { |
67 // NOTE: The resource_dispatcher_host also needs probably unique | 70 // NOTE: The resource_dispatcher_host also needs probably unique |
68 // request_ids, so they count down from -2 (-1 is a special we're | 71 // request_ids, so they count down from -2 (-1 is a special we're |
69 // screwed value), while the renderer process counts up. | 72 // screwed value), while the renderer process counts up. |
70 static int next_request_id = 0; | 73 static int next_request_id = 0; |
71 return next_request_id++; | 74 return next_request_id++; |
72 } | 75 } |
73 | 76 |
| 77 class URLLoaderClientImpl final : public mojom::URLLoaderClient { |
| 78 public: |
| 79 URLLoaderClientImpl(int request_id, ResourceDispatcher* resource_dispatcher) |
| 80 : binding_(this), |
| 81 request_id_(request_id), |
| 82 resource_dispatcher_(resource_dispatcher) {} |
| 83 ~URLLoaderClientImpl() override { |
| 84 if (body_consumer_) |
| 85 body_consumer_->Cancel(); |
| 86 } |
| 87 |
| 88 void OnReceiveResponse(mojom::URLResponsePtr response) override { |
| 89 body_consumer_ = new BodyConsumer(request_id_, resource_dispatcher_, |
| 90 std::move(response->body)); |
| 91 |
| 92 resource_dispatcher_->OnMessageReceived(ResourceMsg_ReceivedResponse( |
| 93 request_id_, response->To<ResourceResponseHead>())); |
| 94 } |
| 95 void OnComplete(mojom::URLLoaderStatusPtr status) override { |
| 96 body_consumer_->OnComplete(std::move(status)); |
| 97 } |
| 98 |
| 99 mojom::URLLoaderClientPtr CreateInterfacePtrAndBind() { |
| 100 return binding_.CreateInterfacePtrAndBind(); |
| 101 } |
| 102 |
| 103 private: |
| 104 mojo::Binding<mojom::URLLoaderClient> binding_; |
| 105 scoped_refptr<BodyConsumer> body_consumer_; |
| 106 const int request_id_; |
| 107 ResourceDispatcher* const resource_dispatcher_; |
| 108 }; |
| 109 |
74 } // namespace | 110 } // namespace |
75 | 111 |
76 ResourceDispatcher::ResourceDispatcher( | 112 ResourceDispatcher::ResourceDispatcher( |
77 IPC::Sender* sender, | 113 IPC::Sender* sender, |
78 scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) | 114 scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) |
79 : message_sender_(sender), | 115 : message_sender_(sender), |
80 delegate_(NULL), | 116 delegate_(NULL), |
81 io_timestamp_(base::TimeTicks()), | 117 io_timestamp_(base::TimeTicks()), |
82 main_thread_task_runner_(main_thread_task_runner), | 118 main_thread_task_runner_(main_thread_task_runner), |
83 weak_factory_(this) { | 119 weak_factory_(this) { |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 if (pending_request->is_deferred) { | 570 if (pending_request->is_deferred) { |
535 pending_request->deferred_message_queue.swap(q); | 571 pending_request->deferred_message_queue.swap(q); |
536 return; | 572 return; |
537 } | 573 } |
538 } | 574 } |
539 } | 575 } |
540 } | 576 } |
541 | 577 |
542 void ResourceDispatcher::StartSync(const RequestInfo& request_info, | 578 void ResourceDispatcher::StartSync(const RequestInfo& request_info, |
543 ResourceRequestBody* request_body, | 579 ResourceRequestBody* request_body, |
544 SyncLoadResponse* response) { | 580 SyncLoadResponse* response, |
| 581 mojom::URLLoaderPtr url_loader) { |
545 std::unique_ptr<ResourceHostMsg_Request> request = | 582 std::unique_ptr<ResourceHostMsg_Request> request = |
546 CreateRequest(request_info, request_body, NULL); | 583 CreateRequest(request_info, request_body, NULL); |
547 | 584 |
548 SyncLoadResult result; | 585 SyncLoadResult result; |
549 IPC::SyncMessage* msg = new ResourceHostMsg_SyncLoad( | 586 IPC::SyncMessage* msg = new ResourceHostMsg_SyncLoad( |
550 request_info.routing_id, MakeRequestID(), *request, &result); | 587 request_info.routing_id, MakeRequestID(), *request, &result); |
551 | 588 |
552 // NOTE: This may pump events (see RenderThread::Send). | 589 // NOTE: This may pump events (see RenderThread::Send). |
553 if (!message_sender_->Send(msg)) { | 590 if (!message_sender_->Send(msg)) { |
554 response->error_code = net::ERR_FAILED; | 591 response->error_code = net::ERR_FAILED; |
(...skipping 10 matching lines...) Expand all Loading... |
565 response->encoded_data_length = result.encoded_data_length; | 602 response->encoded_data_length = result.encoded_data_length; |
566 response->load_timing = result.load_timing; | 603 response->load_timing = result.load_timing; |
567 response->devtools_info = result.devtools_info; | 604 response->devtools_info = result.devtools_info; |
568 response->data.swap(result.data); | 605 response->data.swap(result.data); |
569 response->download_file_path = result.download_file_path; | 606 response->download_file_path = result.download_file_path; |
570 response->socket_address = result.socket_address; | 607 response->socket_address = result.socket_address; |
571 } | 608 } |
572 | 609 |
573 int ResourceDispatcher::StartAsync(const RequestInfo& request_info, | 610 int ResourceDispatcher::StartAsync(const RequestInfo& request_info, |
574 ResourceRequestBody* request_body, | 611 ResourceRequestBody* request_body, |
575 std::unique_ptr<RequestPeer> peer) { | 612 std::unique_ptr<RequestPeer> peer, |
| 613 mojom::URLLoaderPtr url_loader) { |
576 GURL frame_origin; | 614 GURL frame_origin; |
577 std::unique_ptr<ResourceHostMsg_Request> request = | 615 std::unique_ptr<ResourceHostMsg_Request> request = |
578 CreateRequest(request_info, request_body, &frame_origin); | 616 CreateRequest(request_info, request_body, &frame_origin); |
579 | 617 |
580 // Compute a unique request_id for this renderer process. | 618 // Compute a unique request_id for this renderer process. |
581 int request_id = MakeRequestID(); | 619 int request_id = MakeRequestID(); |
582 pending_requests_[request_id] = base::WrapUnique(new PendingRequestInfo( | 620 pending_requests_[request_id] = base::WrapUnique(new PendingRequestInfo( |
583 std::move(peer), request->resource_type, request->origin_pid, | 621 std::move(peer), request->resource_type, request->origin_pid, |
584 frame_origin, request->url, request_info.download_to_file)); | 622 frame_origin, request->url, request_info.download_to_file)); |
585 | 623 |
586 if (resource_scheduling_filter_.get() && | 624 if (resource_scheduling_filter_.get() && |
587 request_info.loading_web_task_runner) { | 625 request_info.loading_web_task_runner) { |
588 resource_scheduling_filter_->SetRequestIdTaskRunner( | 626 resource_scheduling_filter_->SetRequestIdTaskRunner( |
589 request_id, | 627 request_id, |
590 base::WrapUnique(request_info.loading_web_task_runner->clone())); | 628 base::WrapUnique(request_info.loading_web_task_runner->clone())); |
591 } | 629 } |
592 | 630 |
593 message_sender_->Send(new ResourceHostMsg_RequestResource( | 631 if (url_loader) { |
594 request_info.routing_id, request_id, *request)); | 632 mojom::URLRequestPtr mojo_request = mojom::URLRequest::From(*request); |
| 633 std::unique_ptr<URLLoaderClientImpl> client( |
| 634 new URLLoaderClientImpl(request_id, this)); |
| 635 mojo_request->request_id = request_id; |
| 636 mojo_request->routing_id = request_info.routing_id; |
| 637 url_loader->Load(std::move(mojo_request), |
| 638 client->CreateInterfacePtrAndBind()); |
| 639 pending_requests_[request_id]->url_loader = std::move(url_loader); |
| 640 pending_requests_[request_id]->url_loader_client = std::move(client); |
| 641 } else { |
| 642 message_sender_->Send(new ResourceHostMsg_RequestResource( |
| 643 request_info.routing_id, request_id, *request)); |
| 644 } |
595 | 645 |
596 return request_id; | 646 return request_id; |
597 } | 647 } |
598 | 648 |
599 void ResourceDispatcher::ToResourceResponseInfo( | 649 void ResourceDispatcher::ToResourceResponseInfo( |
600 const PendingRequestInfo& request_info, | 650 const PendingRequestInfo& request_info, |
601 const ResourceResponseHead& browser_info, | 651 const ResourceResponseHead& browser_info, |
602 ResourceResponseInfo* renderer_info) const { | 652 ResourceResponseInfo* renderer_info) const { |
603 *renderer_info = browser_info; | 653 *renderer_info = browser_info; |
604 if (request_info.request_start.is_null() || | 654 if (request_info.request_start.is_null() || |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 *frame_origin = extra_data->frame_origin(); | 853 *frame_origin = extra_data->frame_origin(); |
804 return request; | 854 return request; |
805 } | 855 } |
806 | 856 |
807 void ResourceDispatcher::SetResourceSchedulingFilter( | 857 void ResourceDispatcher::SetResourceSchedulingFilter( |
808 scoped_refptr<ResourceSchedulingFilter> resource_scheduling_filter) { | 858 scoped_refptr<ResourceSchedulingFilter> resource_scheduling_filter) { |
809 resource_scheduling_filter_ = resource_scheduling_filter; | 859 resource_scheduling_filter_ = resource_scheduling_filter; |
810 } | 860 } |
811 | 861 |
812 } // namespace content | 862 } // namespace content |
OLD | NEW |