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

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

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

Powered by Google App Engine
This is Rietveld 408576698