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

Side by Side Diff: content/browser/loader/async_resource_handler.cc

Issue 2526983002: Refactor ResourceHandler API. (Closed)
Patch Set: Fix Created 4 years 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
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 #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 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 if (buffer_->CanAllocate()) 242 if (buffer_->CanAllocate())
243 ResumeIfDeferred(); 243 ResumeIfDeferred();
244 } 244 }
245 } 245 }
246 246
247 void AsyncResourceHandler::OnUploadProgressACK(int request_id) { 247 void AsyncResourceHandler::OnUploadProgressACK(int request_id) {
248 if (upload_progress_tracker_) 248 if (upload_progress_tracker_)
249 upload_progress_tracker_->OnAckReceived(); 249 upload_progress_tracker_->OnAckReceived();
250 } 250 }
251 251
252 bool AsyncResourceHandler::OnRequestRedirected( 252 void AsyncResourceHandler::OnRequestRedirected(
253 const net::RedirectInfo& redirect_info, 253 const net::RedirectInfo& redirect_info,
254 ResourceResponse* response, 254 ResourceResponse* response,
255 bool* defer) { 255 std::unique_ptr<ResourceController> controller) {
256 ResourceMessageFilter* filter = GetFilter(); 256 ResourceMessageFilter* filter = GetFilter();
257 if (!filter) 257 if (!filter) {
258 return false; 258 controller->Cancel();
259 259 return;
260 *defer = did_defer_ = true; 260 }
261 OnDefer();
262 261
263 NetLogObserver::PopulateResponseInfo(request(), response); 262 NetLogObserver::PopulateResponseInfo(request(), response);
264 response->head.encoded_data_length = request()->GetTotalReceivedBytes(); 263 response->head.encoded_data_length = request()->GetTotalReceivedBytes();
265 reported_transfer_size_ = 0; 264 reported_transfer_size_ = 0;
266 response->head.request_start = request()->creation_time(); 265 response->head.request_start = request()->creation_time();
267 response->head.response_start = TimeTicks::Now(); 266 response->head.response_start = TimeTicks::Now();
268 // TODO(davidben): Is it necessary to pass the new first party URL for 267 // TODO(davidben): Is it necessary to pass the new first party URL for
269 // cookies? The only case where it can change is top-level navigation requests 268 // cookies? The only case where it can change is top-level navigation requests
270 // and hopefully those will eventually all be owned by the browser. It's 269 // and hopefully those will eventually all be owned by the browser. It's
271 // possible this is still needed while renderer-owned ones exist. 270 // possible this is still needed while renderer-owned ones exist.
272 return filter->Send(new ResourceMsg_ReceivedRedirect( 271 if (!filter->Send(new ResourceMsg_ReceivedRedirect(
273 GetRequestID(), redirect_info, response->head)); 272 GetRequestID(), redirect_info, response->head))) {
273 controller->Cancel();
274 } else {
275 did_defer_ = true;
276 OnDefer();
277 set_controller(std::move(controller));
278 }
274 } 279 }
275 280
276 bool AsyncResourceHandler::OnResponseStarted(ResourceResponse* response, 281 void AsyncResourceHandler::OnResponseStarted(
277 bool* defer) { 282 ResourceResponse* response,
283 std::unique_ptr<ResourceController> controller) {
278 // For changes to the main frame, inform the renderer of the new URL's 284 // For changes to the main frame, inform the renderer of the new URL's
279 // per-host settings before the request actually commits. This way the 285 // per-host settings before the request actually commits. This way the
280 // renderer will be able to set these precisely at the time the 286 // renderer will be able to set these precisely at the time the
281 // request commits, avoiding the possibility of e.g. zooming the old content 287 // request commits, avoiding the possibility of e.g. zooming the old content
282 // or of having to layout the new content twice. 288 // or of having to layout the new content twice.
289 DCHECK(!has_controller());
283 290
284 response_started_ticks_ = base::TimeTicks::Now(); 291 response_started_ticks_ = base::TimeTicks::Now();
285 292
286 // We want to send a final upload progress message prior to sending the 293 // We want to send a final upload progress message prior to sending the
287 // response complete message even if we're waiting for an ack to to a 294 // response complete message even if we're waiting for an ack to to a
288 // previous upload progress message. 295 // previous upload progress message.
289 if (upload_progress_tracker_) { 296 if (upload_progress_tracker_) {
290 upload_progress_tracker_->OnUploadCompleted(); 297 upload_progress_tracker_->OnUploadCompleted();
291 upload_progress_tracker_ = nullptr; 298 upload_progress_tracker_ = nullptr;
292 } 299 }
293 300
294 const ResourceRequestInfoImpl* info = GetRequestInfo(); 301 const ResourceRequestInfoImpl* info = GetRequestInfo();
295 if (rdh_->delegate()) { 302 if (rdh_->delegate()) {
296 rdh_->delegate()->OnResponseStarted(request(), info->GetContext(), 303 rdh_->delegate()->OnResponseStarted(request(), info->GetContext(),
297 response); 304 response);
298 } 305 }
299 306
300 ResourceMessageFilter* filter = GetFilter(); 307 ResourceMessageFilter* filter = GetFilter();
301 if (!filter) 308 if (!filter) {
302 return false; 309 controller->Cancel();
310 return;
311 }
303 312
304 NetLogObserver::PopulateResponseInfo(request(), response); 313 NetLogObserver::PopulateResponseInfo(request(), response);
305 response->head.encoded_data_length = request()->raw_header_size(); 314 response->head.encoded_data_length = request()->raw_header_size();
306 315
307 // If the parent handler downloaded the resource to a file, grant the child 316 // If the parent handler downloaded the resource to a file, grant the child
308 // read permissions on it. 317 // read permissions on it.
309 if (!response->head.download_file_path.empty()) { 318 if (!response->head.download_file_path.empty()) {
310 rdh_->RegisterDownloadedTempFile( 319 rdh_->RegisterDownloadedTempFile(
311 info->GetChildID(), info->GetRequestID(), 320 info->GetChildID(), info->GetRequestID(),
312 response->head.download_file_path); 321 response->head.download_file_path);
313 } 322 }
314 323
315 response->head.request_start = request()->creation_time(); 324 response->head.request_start = request()->creation_time();
316 response->head.response_start = TimeTicks::Now(); 325 response->head.response_start = TimeTicks::Now();
317 filter->Send( 326 filter->Send(
318 new ResourceMsg_ReceivedResponse(GetRequestID(), response->head)); 327 new ResourceMsg_ReceivedResponse(GetRequestID(), response->head));
319 sent_received_response_msg_ = true; 328 sent_received_response_msg_ = true;
320 329
321 if (request()->response_info().metadata.get()) { 330 if (request()->response_info().metadata.get()) {
322 std::vector<char> copy(request()->response_info().metadata->data(), 331 std::vector<char> copy(request()->response_info().metadata->data(),
323 request()->response_info().metadata->data() + 332 request()->response_info().metadata->data() +
324 request()->response_info().metadata->size()); 333 request()->response_info().metadata->size());
325 filter->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), copy)); 334 filter->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), copy));
326 } 335 }
327 336
328 inlining_helper_->OnResponseReceived(*response); 337 inlining_helper_->OnResponseReceived(*response);
329 return true; 338 controller->Resume();
330 } 339 }
331 340
332 bool AsyncResourceHandler::OnWillStart(const GURL& url, bool* defer) { 341 void AsyncResourceHandler::OnWillStart(
342 const GURL& url,
343 std::unique_ptr<ResourceController> controller) {
333 ResourceMessageFilter* filter = GetFilter(); 344 ResourceMessageFilter* filter = GetFilter();
334 if (!filter) 345 if (!filter) {
335 return false; 346 controller->Cancel();
347 return;
348 }
336 349
337 if (GetRequestInfo()->is_upload_progress_enabled() && 350 if (GetRequestInfo()->is_upload_progress_enabled() &&
338 request()->has_upload()) { 351 request()->has_upload()) {
339 upload_progress_tracker_ = base::MakeUnique<UploadProgressTracker>( 352 upload_progress_tracker_ = base::MakeUnique<UploadProgressTracker>(
340 FROM_HERE, 353 FROM_HERE,
341 base::BindRepeating(&AsyncResourceHandler::SendUploadProgress, 354 base::BindRepeating(&AsyncResourceHandler::SendUploadProgress,
342 base::Unretained(this)), 355 base::Unretained(this)),
343 request()); 356 request());
344 } 357 }
345 return true; 358 controller->Resume();
346 } 359 }
347 360
348 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, 361 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
349 int* buf_size, 362 int* buf_size,
350 int min_size) { 363 int min_size) {
364 DCHECK(!has_controller());
351 DCHECK_EQ(-1, min_size); 365 DCHECK_EQ(-1, min_size);
352 366
367 // TODO(mmenke): Should fail with ERR_INSUFFICIENT_RESOURCES here.
353 if (!CheckForSufficientResource()) 368 if (!CheckForSufficientResource())
354 return false; 369 return false;
355 370
356 // Return early if InliningHelper allocates the buffer, so that we should 371 // Return early if InliningHelper allocates the buffer, so that we should
357 // inline the data into the IPC message without allocating SharedMemory. 372 // inline the data into the IPC message without allocating SharedMemory.
358 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) 373 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size))
359 return true; 374 return true;
360 375
361 if (!EnsureResourceBufferIsInitialized()) 376 if (!EnsureResourceBufferIsInitialized())
362 return false; 377 return false;
363 378
364 DCHECK(buffer_->CanAllocate()); 379 DCHECK(buffer_->CanAllocate());
365 char* memory = buffer_->Allocate(&allocation_size_); 380 char* memory = buffer_->Allocate(&allocation_size_);
366 CHECK(memory); 381 CHECK(memory);
367 382
368 *buf = new DependentIOBuffer(buffer_.get(), memory); 383 *buf = new DependentIOBuffer(buffer_.get(), memory);
369 *buf_size = allocation_size_; 384 *buf_size = allocation_size_;
370 385
371 return true; 386 return true;
372 } 387 }
373 388
374 bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { 389 void AsyncResourceHandler::OnReadCompleted(
390 int bytes_read,
391 std::unique_ptr<ResourceController> controller) {
392 DCHECK(!has_controller());
375 DCHECK_GE(bytes_read, 0); 393 DCHECK_GE(bytes_read, 0);
376 394
377 if (!bytes_read) 395 if (!bytes_read) {
378 return true; 396 controller->Resume();
397 return;
398 }
379 399
380 ResourceMessageFilter* filter = GetFilter(); 400 ResourceMessageFilter* filter = GetFilter();
381 if (!filter) 401 if (!filter) {
382 return false; 402 controller->Cancel();
403 return;
404 }
383 405
384 int encoded_data_length = CalculateEncodedDataLengthToReport(); 406 int encoded_data_length = CalculateEncodedDataLengthToReport();
385 if (!first_chunk_read_) 407 if (!first_chunk_read_)
386 encoded_data_length -= request()->raw_header_size(); 408 encoded_data_length -= request()->raw_header_size();
387 409
388 first_chunk_read_ = true; 410 first_chunk_read_ = true;
389 411
390 // Return early if InliningHelper handled the received data. 412 // Return early if InliningHelper handled the received data.
391 if (inlining_helper_->SendInlinedDataIfApplicable( 413 if (inlining_helper_->SendInlinedDataIfApplicable(
392 bytes_read, encoded_data_length, filter, 414 bytes_read, encoded_data_length, filter, GetRequestID())) {
393 GetRequestID())) 415 controller->Resume();
394 return true; 416 return;
417 }
395 418
396 buffer_->ShrinkLastAllocation(bytes_read); 419 buffer_->ShrinkLastAllocation(bytes_read);
397 420
398 if (!sent_data_buffer_msg_) { 421 if (!sent_data_buffer_msg_) {
399 base::SharedMemoryHandle handle = base::SharedMemory::DuplicateHandle( 422 base::SharedMemoryHandle handle = base::SharedMemory::DuplicateHandle(
400 buffer_->GetSharedMemory().handle()); 423 buffer_->GetSharedMemory().handle());
401 if (!base::SharedMemory::IsHandleValid(handle)) 424 if (!base::SharedMemory::IsHandleValid(handle)) {
402 return false; 425 controller->Cancel();
426 return;
427 }
403 filter->Send(new ResourceMsg_SetDataBuffer( 428 filter->Send(new ResourceMsg_SetDataBuffer(
404 GetRequestID(), handle, buffer_->GetSharedMemory().mapped_size(), 429 GetRequestID(), handle, buffer_->GetSharedMemory().mapped_size(),
405 filter->peer_pid())); 430 filter->peer_pid()));
406 sent_data_buffer_msg_ = true; 431 sent_data_buffer_msg_ = true;
407 } 432 }
408 433
409 int data_offset = buffer_->GetLastAllocationOffset(); 434 int data_offset = buffer_->GetLastAllocationOffset();
410 435
411 filter->Send(new ResourceMsg_DataReceived(GetRequestID(), data_offset, 436 filter->Send(new ResourceMsg_DataReceived(GetRequestID(), data_offset,
412 bytes_read, encoded_data_length)); 437 bytes_read, encoded_data_length));
413 ++pending_data_count_; 438 ++pending_data_count_;
414 439
415 if (!buffer_->CanAllocate()) { 440 if (!buffer_->CanAllocate()) {
416 *defer = did_defer_ = true; 441 did_defer_ = true;
417 OnDefer(); 442 OnDefer();
443 set_controller(std::move(controller));
444 } else {
445 controller->Resume();
418 } 446 }
419
420 return true;
421 } 447 }
422 448
423 void AsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) { 449 void AsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) {
424 int encoded_data_length = CalculateEncodedDataLengthToReport(); 450 int encoded_data_length = CalculateEncodedDataLengthToReport();
425 451
426 ResourceMessageFilter* filter = GetFilter(); 452 ResourceMessageFilter* filter = GetFilter();
427 if (filter) { 453 if (filter) {
428 filter->Send(new ResourceMsg_DataDownloaded( 454 filter->Send(new ResourceMsg_DataDownloaded(
429 GetRequestID(), bytes_downloaded, encoded_data_length)); 455 GetRequestID(), bytes_downloaded, encoded_data_length));
430 } 456 }
431 } 457 }
432 458
433 void AsyncResourceHandler::OnResponseCompleted( 459 void AsyncResourceHandler::OnResponseCompleted(
434 const net::URLRequestStatus& status, 460 const net::URLRequestStatus& status,
435 bool* defer) { 461 std::unique_ptr<ResourceController> controller) {
436 ResourceMessageFilter* filter = GetFilter(); 462 ResourceMessageFilter* filter = GetFilter();
437 if (!filter) 463 if (!filter) {
464 controller->Resume();
438 return; 465 return;
466 }
439 467
440 // Ensure sending the final upload progress message here, since 468 // Ensure sending the final upload progress message here, since
441 // OnResponseCompleted can be called without OnResponseStarted on cancellation 469 // OnResponseCompleted can be called without OnResponseStarted on cancellation
442 // or error cases. 470 // or error cases.
443 if (upload_progress_tracker_) { 471 if (upload_progress_tracker_) {
444 upload_progress_tracker_->OnUploadCompleted(); 472 upload_progress_tracker_->OnUploadCompleted();
445 upload_progress_tracker_ = nullptr; 473 upload_progress_tracker_ = nullptr;
446 } 474 }
447 475
448 // If we crash here, figure out what URL the renderer was requesting. 476 // If we crash here, figure out what URL the renderer was requesting.
(...skipping 26 matching lines...) Expand all
475 request_complete_data.exists_in_cache = request()->response_info().was_cached; 503 request_complete_data.exists_in_cache = request()->response_info().was_cached;
476 request_complete_data.completion_time = TimeTicks::Now(); 504 request_complete_data.completion_time = TimeTicks::Now();
477 request_complete_data.encoded_data_length = 505 request_complete_data.encoded_data_length =
478 request()->GetTotalReceivedBytes(); 506 request()->GetTotalReceivedBytes();
479 request_complete_data.encoded_body_length = request()->GetRawBodyBytes(); 507 request_complete_data.encoded_body_length = request()->GetRawBodyBytes();
480 filter->Send( 508 filter->Send(
481 new ResourceMsg_RequestComplete(GetRequestID(), request_complete_data)); 509 new ResourceMsg_RequestComplete(GetRequestID(), request_complete_data));
482 510
483 if (status.is_success()) 511 if (status.is_success())
484 RecordHistogram(); 512 RecordHistogram();
513 controller->Resume();
485 } 514 }
486 515
487 bool AsyncResourceHandler::EnsureResourceBufferIsInitialized() { 516 bool AsyncResourceHandler::EnsureResourceBufferIsInitialized() {
488 DCHECK(has_checked_for_sufficient_resources_); 517 DCHECK(has_checked_for_sufficient_resources_);
489 518
490 if (buffer_.get() && buffer_->IsInitialized()) 519 if (buffer_.get() && buffer_->IsInitialized())
491 return true; 520 return true;
492 521
493 buffer_ = new ResourceBuffer(); 522 buffer_ = new ResourceBuffer();
494 return buffer_->Initialize(kBufferSize, 523 return buffer_->Initialize(kBufferSize,
495 kMinAllocationSize, 524 kMinAllocationSize,
496 kMaxAllocationSize); 525 kMaxAllocationSize);
497 } 526 }
498 527
499 void AsyncResourceHandler::ResumeIfDeferred() { 528 void AsyncResourceHandler::ResumeIfDeferred() {
500 if (did_defer_) { 529 if (did_defer_) {
501 did_defer_ = false; 530 did_defer_ = false;
502 request()->LogUnblocked(); 531 request()->LogUnblocked();
503 controller()->Resume(); 532 Resume();
504 } 533 }
505 } 534 }
506 535
507 void AsyncResourceHandler::OnDefer() { 536 void AsyncResourceHandler::OnDefer() {
508 request()->LogBlockedBy("AsyncResourceHandler"); 537 request()->LogBlockedBy("AsyncResourceHandler");
509 } 538 }
510 539
511 bool AsyncResourceHandler::CheckForSufficientResource() { 540 bool AsyncResourceHandler::CheckForSufficientResource() {
512 if (has_checked_for_sufficient_resources_) 541 if (has_checked_for_sufficient_resources_)
513 return true; 542 return true;
514 has_checked_for_sufficient_resources_ = true; 543 has_checked_for_sufficient_resources_ = true;
515 544
516 if (rdh_->HasSufficientResourcesForRequest(request())) 545 if (rdh_->HasSufficientResourcesForRequest(request()))
517 return true; 546 return true;
518 547
519 controller()->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES);
520 return false; 548 return false;
521 } 549 }
522 550
523 int AsyncResourceHandler::CalculateEncodedDataLengthToReport() { 551 int AsyncResourceHandler::CalculateEncodedDataLengthToReport() {
524 const auto transfer_size = request()->GetTotalReceivedBytes(); 552 const auto transfer_size = request()->GetTotalReceivedBytes();
525 const auto difference = transfer_size - reported_transfer_size_; 553 const auto difference = transfer_size - reported_transfer_size_;
526 reported_transfer_size_ = transfer_size; 554 reported_transfer_size_ = transfer_size;
527 return difference; 555 return difference;
528 } 556 }
529 557
(...skipping 26 matching lines...) Expand all
556 void AsyncResourceHandler::SendUploadProgress(int64_t current_position, 584 void AsyncResourceHandler::SendUploadProgress(int64_t current_position,
557 int64_t total_size) { 585 int64_t total_size) {
558 ResourceMessageFilter* filter = GetFilter(); 586 ResourceMessageFilter* filter = GetFilter();
559 if (!filter) 587 if (!filter)
560 return; 588 return;
561 filter->Send(new ResourceMsg_UploadProgress( 589 filter->Send(new ResourceMsg_UploadProgress(
562 GetRequestID(), current_position, total_size)); 590 GetRequestID(), current_position, total_size));
563 } 591 }
564 592
565 } // namespace content 593 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698