Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(241)

Side by Side Diff: content/child/resource_dispatcher.cc

Issue 1103813002: Make WebURLLoader capable of retaining received buffers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/child/resource_dispatcher.h ('k') | content/child/resource_dispatcher_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/compiler_specific.h" 11 #include "base/compiler_specific.h"
12 #include "base/debug/alias.h" 12 #include "base/debug/alias.h"
13 #include "base/debug/dump_without_crashing.h" 13 #include "base/debug/dump_without_crashing.h"
14 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
15 #include "base/memory/shared_memory.h" 15 #include "base/memory/shared_memory.h"
16 #include "base/message_loop/message_loop.h" 16 #include "base/message_loop/message_loop.h"
17 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
18 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
19 #include "content/child/request_extra_data.h" 19 #include "content/child/request_extra_data.h"
20 #include "content/child/request_info.h" 20 #include "content/child/request_info.h"
21 #include "content/child/shared_memory_received_data_factory.h"
21 #include "content/child/site_isolation_policy.h" 22 #include "content/child/site_isolation_policy.h"
22 #include "content/child/sync_load_response.h" 23 #include "content/child/sync_load_response.h"
23 #include "content/child/threaded_data_provider.h" 24 #include "content/child/threaded_data_provider.h"
24 #include "content/common/inter_process_time_ticks_converter.h" 25 #include "content/common/inter_process_time_ticks_converter.h"
25 #include "content/common/resource_messages.h" 26 #include "content/common/resource_messages.h"
27 #include "content/public/child/fixed_received_data.h"
26 #include "content/public/child/request_peer.h" 28 #include "content/public/child/request_peer.h"
27 #include "content/public/child/resource_dispatcher_delegate.h" 29 #include "content/public/child/resource_dispatcher_delegate.h"
28 #include "content/public/common/resource_response.h" 30 #include "content/public/common/resource_response.h"
29 #include "content/public/common/resource_type.h" 31 #include "content/public/common/resource_type.h"
30 #include "net/base/net_errors.h" 32 #include "net/base/net_errors.h"
31 #include "net/base/net_util.h" 33 #include "net/base/net_util.h"
32 #include "net/base/request_priority.h" 34 #include "net/base/request_priority.h"
33 #include "net/http/http_response_headers.h" 35 #include "net/http/http_response_headers.h"
34 36
35 namespace content { 37 namespace content {
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 TRACE_EVENT0("loader", "ResourceDispatcher::OnSetDataBuffer"); 186 TRACE_EVENT0("loader", "ResourceDispatcher::OnSetDataBuffer");
185 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); 187 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
186 if (!request_info) 188 if (!request_info)
187 return; 189 return;
188 190
189 bool shm_valid = base::SharedMemory::IsHandleValid(shm_handle); 191 bool shm_valid = base::SharedMemory::IsHandleValid(shm_handle);
190 CHECK((shm_valid && shm_size > 0) || (!shm_valid && !shm_size)); 192 CHECK((shm_valid && shm_size > 0) || (!shm_valid && !shm_size));
191 193
192 request_info->buffer.reset( 194 request_info->buffer.reset(
193 new base::SharedMemory(shm_handle, true)); // read only 195 new base::SharedMemory(shm_handle, true)); // read only
196 request_info->received_data_factory =
197 make_scoped_refptr(new SharedMemoryReceivedDataFactory(
198 message_sender_, request_id, request_info->buffer));
194 199
195 bool ok = request_info->buffer->Map(shm_size); 200 bool ok = request_info->buffer->Map(shm_size);
196 if (!ok) { 201 if (!ok) {
197 // Added to help debug crbug/160401. 202 // Added to help debug crbug/160401.
198 base::ProcessId renderer_pid_copy = renderer_pid; 203 base::ProcessId renderer_pid_copy = renderer_pid;
199 base::debug::Alias(&renderer_pid_copy); 204 base::debug::Alias(&renderer_pid_copy);
200 205
201 base::SharedMemoryHandle shm_handle_copy = shm_handle; 206 base::SharedMemoryHandle shm_handle_copy = shm_handle;
202 base::debug::Alias(&shm_handle_copy); 207 base::debug::Alias(&shm_handle_copy);
203 208
(...skipping 11 matching lines...) Expand all
215 TRACE_EVENT0("loader", "ResourceDispatcher::OnReceivedData"); 220 TRACE_EVENT0("loader", "ResourceDispatcher::OnReceivedData");
216 DCHECK_GT(data_length, 0); 221 DCHECK_GT(data_length, 0);
217 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); 222 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
218 bool send_ack = true; 223 bool send_ack = true;
219 if (request_info && data_length > 0) { 224 if (request_info && data_length > 0) {
220 CHECK(base::SharedMemory::IsHandleValid(request_info->buffer->handle())); 225 CHECK(base::SharedMemory::IsHandleValid(request_info->buffer->handle()));
221 CHECK_GE(request_info->buffer_size, data_offset + data_length); 226 CHECK_GE(request_info->buffer_size, data_offset + data_length);
222 227
223 // Ensure that the SHM buffer remains valid for the duration of this scope. 228 // Ensure that the SHM buffer remains valid for the duration of this scope.
224 // It is possible for Cancel() to be called before we exit this scope. 229 // It is possible for Cancel() to be called before we exit this scope.
225 linked_ptr<base::SharedMemory> retain_buffer(request_info->buffer); 230 // SharedMemoryReceivedDataFactory stores the SHM buffer inside it.
231 scoped_refptr<SharedMemoryReceivedDataFactory> factory(
232 request_info->received_data_factory);
226 233
227 base::TimeTicks time_start = base::TimeTicks::Now(); 234 base::TimeTicks time_start = base::TimeTicks::Now();
228 235
229 const char* data_start = static_cast<char*>(request_info->buffer->memory()); 236 const char* data_start = static_cast<char*>(request_info->buffer->memory());
230 CHECK(data_start); 237 CHECK(data_start);
231 CHECK(data_start + data_offset); 238 CHECK(data_start + data_offset);
232 const char* data_ptr = data_start + data_offset; 239 const char* data_ptr = data_start + data_offset;
233 240
234 // Check whether this response data is compliant with our cross-site 241 // Check whether this response data is compliant with our cross-site
235 // document blocking policy. We only do this for the first packet. 242 // document blocking policy. We only do this for the first packet.
236 std::string alternative_data; 243 std::string alternative_data;
237 if (request_info->site_isolation_metadata.get()) { 244 if (request_info->site_isolation_metadata.get()) {
238 request_info->blocked_response = 245 request_info->blocked_response = SiteIsolationPolicy::ShouldBlockResponse(
239 SiteIsolationPolicy::ShouldBlockResponse( 246 request_info->site_isolation_metadata, data_ptr, data_length,
240 request_info->site_isolation_metadata, data_ptr, data_length, 247 &alternative_data);
241 &alternative_data);
242 request_info->site_isolation_metadata.reset(); 248 request_info->site_isolation_metadata.reset();
249 }
243 250
244 // When the response is blocked we may have any alternative data to 251 // When the response is blocked we may have any alternative data to
245 // send to the renderer. When |alternative_data| is zero-sized, we do not 252 // send to the renderer.
246 // call peer's callback. 253 // When |alternative_data| is zero-sized, we do not call peer's callback.
247 if (request_info->blocked_response && !alternative_data.empty()) { 254 if (!request_info->blocked_response || !alternative_data.empty()) {
248 data_ptr = alternative_data.data(); 255 if (request_info->threaded_data_provider) {
249 data_length = alternative_data.size(); 256 // TODO(yhirano): Use |alternative_data| when it is not null.
250 encoded_data_length = alternative_data.size(); 257 // A threaded data provider will take care of its own ACKing, as the
258 // data may be processed later on another thread.
259 send_ack = false;
260 request_info->threaded_data_provider->OnReceivedDataOnForegroundThread(
261 data_ptr, data_length, encoded_data_length);
262 } else {
263 scoped_ptr<RequestPeer::ReceivedData> data;
264 if (!alternative_data.empty()) {
265 data = make_scoped_ptr(new FixedReceivedData(
266 alternative_data.data(), alternative_data.size(),
267 alternative_data.size()));
268 } else {
269 data = factory->Create(data_offset, data_length, encoded_data_length);
270 // |data| takes care of ACKing.
271 send_ack = false;
272 }
273 request_info->peer->OnReceivedData(data.Pass());
251 } 274 }
252 } 275 }
253 276
254 if (!request_info->blocked_response || !alternative_data.empty()) {
255 if (request_info->threaded_data_provider) {
256 request_info->threaded_data_provider->OnReceivedDataOnForegroundThread(
257 data_ptr, data_length, encoded_data_length);
258 // A threaded data provider will take care of its own ACKing, as the
259 // data may be processed later on another thread.
260 send_ack = false;
261 } else {
262 request_info->peer->OnReceivedData(
263 data_ptr, data_length, encoded_data_length);
264 }
265 }
266
267 UMA_HISTOGRAM_TIMES("ResourceDispatcher.OnReceivedDataTime", 277 UMA_HISTOGRAM_TIMES("ResourceDispatcher.OnReceivedDataTime",
268 base::TimeTicks::Now() - time_start); 278 base::TimeTicks::Now() - time_start);
269 } 279 }
270 280
271 // Acknowledge the reception of this data. 281 // Acknowledge the reception of this data.
272 if (send_ack) 282 if (send_ack)
273 message_sender_->Send(new ResourceHostMsg_DataReceived_ACK(request_id)); 283 message_sender_->Send(new ResourceHostMsg_DataReceived_ACK(request_id));
274 } 284 }
275 285
276 void ResourceDispatcher::OnDownloadedData(int request_id, 286 void ResourceDispatcher::OnDownloadedData(int request_id,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 void ResourceDispatcher::OnRequestComplete( 339 void ResourceDispatcher::OnRequestComplete(
330 int request_id, 340 int request_id,
331 const ResourceMsg_RequestCompleteData& request_complete_data) { 341 const ResourceMsg_RequestCompleteData& request_complete_data) {
332 TRACE_EVENT0("loader", "ResourceDispatcher::OnRequestComplete"); 342 TRACE_EVENT0("loader", "ResourceDispatcher::OnRequestComplete");
333 343
334 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); 344 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
335 if (!request_info) 345 if (!request_info)
336 return; 346 return;
337 request_info->completion_time = ConsumeIOTimestamp(); 347 request_info->completion_time = ConsumeIOTimestamp();
338 request_info->buffer.reset(); 348 request_info->buffer.reset();
349 if (request_info->received_data_factory)
350 request_info->received_data_factory->Stop();
351 request_info->received_data_factory = nullptr;
339 request_info->buffer_size = 0; 352 request_info->buffer_size = 0;
340 353
341 RequestPeer* peer = request_info->peer; 354 RequestPeer* peer = request_info->peer;
342 355
343 if (delegate_) { 356 if (delegate_) {
344 RequestPeer* new_peer = 357 RequestPeer* new_peer =
345 delegate_->OnRequestComplete( 358 delegate_->OnRequestComplete(
346 request_info->peer, request_info->resource_type, 359 request_info->peer, request_info->resource_type,
347 request_complete_data.error_code); 360 request_complete_data.error_code);
348 if (new_peer) 361 if (new_peer)
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 extra_data->transferred_request_request_id(); 803 extra_data->transferred_request_request_id();
791 request->service_worker_provider_id = 804 request->service_worker_provider_id =
792 extra_data->service_worker_provider_id(); 805 extra_data->service_worker_provider_id();
793 request->request_body = request_body; 806 request->request_body = request_body;
794 if (frame_origin) 807 if (frame_origin)
795 *frame_origin = extra_data->frame_origin(); 808 *frame_origin = extra_data->frame_origin();
796 return request.Pass(); 809 return request.Pass();
797 } 810 }
798 811
799 } // namespace content 812 } // namespace content
OLDNEW
« no previous file with comments | « content/child/resource_dispatcher.h ('k') | content/child/resource_dispatcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698