OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/navigation_url_loader_network_service.h" | 5 #include "content/browser/loader/navigation_url_loader_network_service.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
10 #include "content/browser/blob_storage/chrome_blob_storage_context.h" | 10 #include "content/browser/blob_storage/chrome_blob_storage_context.h" |
11 #include "content/browser/frame_host/frame_tree_node.h" | |
11 #include "content/browser/frame_host/navigation_request_info.h" | 12 #include "content/browser/frame_host/navigation_request_info.h" |
13 #include "content/browser/loader/navigation_factory_creation_data.h" | |
12 #include "content/browser/loader/navigation_resource_handler.h" | 14 #include "content/browser/loader/navigation_resource_handler.h" |
13 #include "content/browser/loader/navigation_resource_throttle.h" | 15 #include "content/browser/loader/navigation_resource_throttle.h" |
14 #include "content/browser/loader/navigation_url_loader_delegate.h" | 16 #include "content/browser/loader/navigation_url_loader_delegate.h" |
17 #include "content/browser/service_worker/service_worker_context_wrapper.h" | |
18 #include "content/browser/service_worker/service_worker_navigation_handle.h" | |
19 #include "content/browser/service_worker/service_worker_navigation_handle_core.h " | |
20 #include "content/browser/service_worker/service_worker_url_loader_factory_creat ion.h" | |
21 #include "content/browser/web_contents/web_contents_impl.h" | |
22 #include "content/common/url_loader_factory.mojom.h" | |
15 #include "content/public/browser/browser_thread.h" | 23 #include "content/public/browser/browser_thread.h" |
16 #include "content/public/browser/global_request_id.h" | 24 #include "content/public/browser/global_request_id.h" |
17 #include "content/public/browser/navigation_data.h" | 25 #include "content/public/browser/navigation_data.h" |
18 #include "content/public/browser/navigation_ui_data.h" | 26 #include "content/public/browser/navigation_ui_data.h" |
19 #include "content/public/browser/ssl_status.h" | 27 #include "content/public/browser/ssl_status.h" |
20 #include "content/public/browser/stream_handle.h" | 28 #include "content/public/browser/stream_handle.h" |
21 #include "content/public/common/referrer.h" | 29 #include "content/public/common/referrer.h" |
22 #include "content/public/common/service_manager_connection.h" | 30 #include "content/public/common/service_manager_connection.h" |
23 #include "content/public/common/service_names.mojom.h" | 31 #include "content/public/common/service_names.mojom.h" |
24 #include "net/base/load_flags.h" | 32 #include "net/base/load_flags.h" |
25 #include "net/url_request/url_request_context.h" | 33 #include "net/url_request/url_request_context.h" |
26 #include "services/service_manager/public/cpp/connector.h" | 34 #include "services/service_manager/public/cpp/connector.h" |
27 | 35 |
28 namespace content { | 36 namespace content { |
29 | 37 |
30 // This function is called on the IO thread for POST/PUT requests for | 38 namespace { |
31 // attaching blob information to the request body. | 39 |
32 void HandleRequestsWithBody( | 40 using CompleteNavigationStart = |
33 std::unique_ptr<ResourceRequest> request, | 41 base::Callback<void(mojom::URLLoaderFactoryPtrInfo, |
34 ResourceContext* resource_context, | 42 std::unique_ptr<ResourceRequest>)>; |
35 base::WeakPtr<NavigationURLLoaderNetworkService> url_loader) { | 43 |
44 void NavigationStartupWorkOnIO( | |
45 std::unique_ptr<NavigationFactoryCreationData> creation_data, | |
46 CompleteNavigationStart complete_request) { | |
36 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 47 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
37 DCHECK(request->request_body.get()); | 48 DCHECK(creation_data->navigation_handle || |
49 creation_data->request->request_body.get()); | |
38 | 50 |
39 AttachRequestBodyBlobDataHandles(request->request_body.get(), | 51 mojom::URLLoaderFactoryPtrInfo url_loader_factory_ptr_info; |
40 resource_context); | 52 if (creation_data->navigation_handle) { |
53 url_loader_factory_ptr_info = | |
54 ServiceWorkerURLLoaderFactoryCreation::InitializeForNavigation( | |
55 *creation_data); | |
56 } | |
57 | |
58 if (creation_data->request->request_body) { | |
59 AttachRequestBodyBlobDataHandles(creation_data->request->request_body.get(), | |
60 creation_data->resource_context); | |
61 } | |
62 | |
41 BrowserThread::PostTask( | 63 BrowserThread::PostTask( |
42 BrowserThread::UI, FROM_HERE, | 64 BrowserThread::UI, FROM_HERE, |
43 base::Bind(&NavigationURLLoaderNetworkService::StartURLRequest, | 65 base::Bind(complete_request, |
44 url_loader, base::Passed(&request))); | 66 base::Passed(std::move(url_loader_factory_ptr_info)), |
67 base::Passed(std::move(creation_data->request)))); | |
45 } | 68 } |
46 | 69 |
70 WebContents* GetWebContentsFromFrameTreeNodeID(int frame_tree_node_id) { | |
71 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
72 FrameTreeNode* frame_tree_node = | |
73 FrameTreeNode::GloballyFindByID(frame_tree_node_id); | |
74 if (!frame_tree_node) | |
75 return nullptr; | |
76 | |
77 return WebContentsImpl::FromFrameTreeNode(frame_tree_node); | |
78 } | |
79 | |
80 } // namespace | |
81 | |
47 NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( | 82 NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( |
48 ResourceContext* resource_context, | 83 ResourceContext* resource_context, |
49 StoragePartition* storage_partition, | 84 StoragePartition* storage_partition, |
50 std::unique_ptr<NavigationRequestInfo> request_info, | 85 std::unique_ptr<NavigationRequestInfo> request_info, |
51 std::unique_ptr<NavigationUIData> navigation_ui_data, | 86 std::unique_ptr<NavigationUIData> navigation_ui_data, |
52 ServiceWorkerNavigationHandle* service_worker_handle, | 87 ServiceWorkerNavigationHandle* service_worker_navigation_handle, |
53 AppCacheNavigationHandle* appcache_handle, | 88 AppCacheNavigationHandle* appcache_handle, |
54 NavigationURLLoaderDelegate* delegate) | 89 NavigationURLLoaderDelegate* delegate) |
55 : delegate_(delegate), binding_(this), weak_factory_(this) { | 90 : delegate_(delegate), binding_(this), weak_factory_(this) { |
56 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 91 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
57 | 92 |
58 // TODO(scottmg): Maybe some of this setup should be done only once, instead | |
59 // of every time. | |
60 ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface( | |
61 mojom::kNetworkServiceName, &url_loader_factory_); | |
62 | |
63 // TODO(scottmg): Port over stuff from RDHI::BeginNavigationRequest() here. | 93 // TODO(scottmg): Port over stuff from RDHI::BeginNavigationRequest() here. |
64 auto new_request = base::MakeUnique<ResourceRequest>(); | 94 auto new_request = base::MakeUnique<ResourceRequest>(); |
65 | 95 |
66 new_request->method = request_info->common_params.method; | 96 new_request->method = request_info->common_params.method; |
67 new_request->url = request_info->common_params.url; | 97 new_request->url = request_info->common_params.url; |
68 new_request->first_party_for_cookies = request_info->first_party_for_cookies; | 98 new_request->first_party_for_cookies = request_info->first_party_for_cookies; |
69 new_request->priority = net::HIGHEST; | 99 new_request->priority = net::HIGHEST; |
70 | 100 |
71 // The code below to set fields like request_initiator, referrer, etc has | 101 // The code below to set fields like request_initiator, referrer, etc has |
72 // been copied from ResourceDispatcherHostImpl. We did not refactor the | 102 // been copied from ResourceDispatcherHostImpl. We did not refactor the |
73 // common code into a function, because RDHI uses accessor functions on the | 103 // common code into a function, because RDHI uses accessor functions on the |
74 // URLRequest class to set these fields. whereas we use ResourceRequest here. | 104 // URLRequest class to set these fields. whereas we use ResourceRequest here. |
75 new_request->request_initiator = request_info->begin_params.initiator_origin; | 105 new_request->request_initiator = request_info->begin_params.initiator_origin; |
76 new_request->referrer = request_info->common_params.referrer.url; | 106 new_request->referrer = request_info->common_params.referrer.url; |
77 new_request->referrer_policy = request_info->common_params.referrer.policy; | 107 new_request->referrer_policy = request_info->common_params.referrer.policy; |
78 new_request->headers = request_info->begin_params.headers; | 108 new_request->headers = request_info->begin_params.headers; |
79 | 109 |
80 int load_flags = request_info->begin_params.load_flags; | 110 int load_flags = request_info->begin_params.load_flags; |
81 load_flags |= net::LOAD_VERIFY_EV_CERT; | 111 load_flags |= net::LOAD_VERIFY_EV_CERT; |
82 if (request_info->is_main_frame) | 112 if (request_info->is_main_frame) |
83 load_flags |= net::LOAD_MAIN_FRAME_DEPRECATED; | 113 load_flags |= net::LOAD_MAIN_FRAME_DEPRECATED; |
84 | 114 |
85 // Sync loads should have maximum priority and should be the only | 115 // Sync loads should have maximum priority and should be the only |
86 // requests that have the ignore limits flag set. | 116 // requests that have the ignore limits flag set. |
87 DCHECK(!(load_flags & net::LOAD_IGNORE_LIMITS)); | 117 DCHECK(!(load_flags & net::LOAD_IGNORE_LIMITS)); |
88 | 118 |
89 new_request->load_flags = load_flags; | 119 new_request->load_flags = load_flags; |
90 | 120 |
91 new_request->request_body = request_info->common_params.post_data.get(); | 121 new_request->request_body = request_info->common_params.post_data.get(); |
92 if (new_request->request_body.get()) { | 122 |
93 // The request body may need blob handles to be added to it. This | 123 // Determine where the request will be serviced. If there's work that needs to |
94 // functionality has to be invoked on the IO thread. | 124 // be done on the IO thread due to Service Worker or POST body, then post to |
125 // the IO thread to have it do that work, and then continue on to | |
126 // StartURLRequest. Otherwise, handle the request directly. | |
127 const bool need_to_work_on_io = | |
128 service_worker_navigation_handle || new_request->request_body; | |
129 if (need_to_work_on_io) { | |
130 auto creation_data = base::MakeUnique<NavigationFactoryCreationData>(); | |
131 creation_data->request = std::move(new_request); | |
132 creation_data->navigation_handle = | |
133 service_worker_navigation_handle | |
134 ? service_worker_navigation_handle->core() | |
135 : nullptr; | |
136 creation_data->resource_context = resource_context; | |
137 creation_data->web_contents_getter = base::Bind( | |
138 &GetWebContentsFromFrameTreeNodeID, request_info->frame_tree_node_id); | |
139 creation_data->resource_type = request_info->is_main_frame | |
140 ? RESOURCE_TYPE_MAIN_FRAME | |
141 : RESOURCE_TYPE_SUB_FRAME; | |
142 creation_data->is_parent_frame_secure = request_info->are_ancestors_secure; | |
143 | |
95 BrowserThread::PostTask( | 144 BrowserThread::PostTask( |
96 BrowserThread::IO, FROM_HERE, | 145 BrowserThread::IO, FROM_HERE, |
97 base::Bind(&HandleRequestsWithBody, | 146 base::Bind( |
98 base::Passed(&new_request), | 147 &NavigationStartupWorkOnIO, base::Passed(std::move(creation_data)), |
99 resource_context, | 148 base::Bind(&NavigationURLLoaderNetworkService::StartURLRequest, |
100 weak_factory_.GetWeakPtr())); | 149 weak_factory_.GetWeakPtr()))); |
101 return; | 150 return; |
102 } | 151 } |
103 | 152 |
104 StartURLRequest(std::move(new_request)); | 153 StartURLRequest(mojom::URLLoaderFactoryPtrInfo(), std::move(new_request)); |
105 } | 154 } |
106 | 155 |
107 NavigationURLLoaderNetworkService::~NavigationURLLoaderNetworkService() {} | 156 NavigationURLLoaderNetworkService::~NavigationURLLoaderNetworkService() {} |
108 | 157 |
109 void NavigationURLLoaderNetworkService::FollowRedirect() { | 158 void NavigationURLLoaderNetworkService::FollowRedirect() { |
110 url_loader_associated_ptr_->FollowRedirect(); | 159 url_loader_associated_ptr_->FollowRedirect(); |
111 } | 160 } |
112 | 161 |
113 void NavigationURLLoaderNetworkService::ProceedWithResponse() {} | 162 void NavigationURLLoaderNetworkService::ProceedWithResponse() {} |
114 | 163 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
163 | 212 |
164 void NavigationURLLoaderNetworkService::OnComplete( | 213 void NavigationURLLoaderNetworkService::OnComplete( |
165 const ResourceRequestCompletionStatus& completion_status) { | 214 const ResourceRequestCompletionStatus& completion_status) { |
166 if (completion_status.error_code != net::OK) { | 215 if (completion_status.error_code != net::OK) { |
167 delegate_->OnRequestFailed(completion_status.exists_in_cache, | 216 delegate_->OnRequestFailed(completion_status.exists_in_cache, |
168 completion_status.error_code); | 217 completion_status.error_code); |
169 } | 218 } |
170 } | 219 } |
171 | 220 |
172 void NavigationURLLoaderNetworkService::StartURLRequest( | 221 void NavigationURLLoaderNetworkService::StartURLRequest( |
222 mojom::URLLoaderFactoryPtrInfo url_loader_factory_info, | |
173 std::unique_ptr<ResourceRequest> request) { | 223 std::unique_ptr<ResourceRequest> request) { |
174 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 224 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
175 | 225 |
226 // If a URLLoaderFactory was provided, then we use that one, otherwise | |
227 // fall back to connecting directly to the network service. | |
kinuko
2017/05/01 02:06:24
Initially this is probably ok, but we'll need netw
| |
228 if (url_loader_factory_info.is_valid()) { | |
229 url_loader_factory_.Bind(std::move(url_loader_factory_info)); | |
230 } else { | |
231 ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface( | |
232 mojom::kNetworkServiceName, &url_loader_factory_); | |
233 } | |
234 | |
235 // Bind the URLClient implementation to this object to pass to the URLLoader. | |
kinuko
2017/05/01 02:06:24
nit: URLClient -> URLLoaderClient
| |
176 mojom::URLLoaderClientPtr url_loader_client_ptr_to_pass; | 236 mojom::URLLoaderClientPtr url_loader_client_ptr_to_pass; |
177 binding_.Bind(&url_loader_client_ptr_to_pass); | 237 binding_.Bind(&url_loader_client_ptr_to_pass); |
178 | 238 |
239 // Use the URLLoaderFactory to create a URLLoader that uses |binding_| as the | |
240 // URLLoaderClient. | |
179 url_loader_factory_->CreateLoaderAndStart( | 241 url_loader_factory_->CreateLoaderAndStart( |
180 mojo::MakeRequest(&url_loader_associated_ptr_), 0 /* routing_id? */, | 242 mojo::MakeRequest(&url_loader_associated_ptr_), 0 /* routing_id? */, |
181 0 /* request_id? */, mojom::kURLLoadOptionSendSSLInfo, *request, | 243 0 /* request_id? */, mojom::kURLLoadOptionSendSSLInfo, *request, |
182 std::move(url_loader_client_ptr_to_pass)); | 244 std::move(url_loader_client_ptr_to_pass)); |
183 } | 245 } |
184 | 246 |
185 } // namespace content | 247 } // namespace content |
OLD | NEW |