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

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

Issue 2526983002: Refactor ResourceHandler API. (Closed)
Patch Set: Response to comments Created 3 years, 10 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(
285 GetRequestID(), redirect_info, response->head)); 283 GetRequestID(), redirect_info, response->head))) {
284 OnDefer(std::move(controller));
285 } else {
286 controller->Cancel();
287 }
286 } 288 }
287 289
288 bool AsyncResourceHandler::OnResponseStarted(ResourceResponse* response, 290 void AsyncResourceHandler::OnResponseStarted(
289 bool* defer) { 291 ResourceResponse* response,
292 std::unique_ptr<ResourceController> controller) {
290 // For changes to the main frame, inform the renderer of the new URL's 293 // 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 294 // per-host settings before the request actually commits. This way the
292 // renderer will be able to set these precisely at the time the 295 // 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 296 // request commits, avoiding the possibility of e.g. zooming the old content
294 // or of having to layout the new content twice. 297 // or of having to layout the new content twice.
298 DCHECK(!has_controller());
295 299
296 response_started_ticks_ = base::TimeTicks::Now(); 300 response_started_ticks_ = base::TimeTicks::Now();
297 301
298 // We want to send a final upload progress message prior to sending the 302 // 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 303 // response complete message even if we're waiting for an ack to to a
300 // previous upload progress message. 304 // previous upload progress message.
301 if (upload_progress_tracker_) { 305 if (upload_progress_tracker_) {
302 upload_progress_tracker_->OnUploadCompleted(); 306 upload_progress_tracker_->OnUploadCompleted();
303 upload_progress_tracker_ = nullptr; 307 upload_progress_tracker_ = nullptr;
304 } 308 }
305 309
306 const ResourceRequestInfoImpl* info = GetRequestInfo(); 310 const ResourceRequestInfoImpl* info = GetRequestInfo();
307 if (rdh_->delegate()) { 311 if (rdh_->delegate()) {
308 rdh_->delegate()->OnResponseStarted(request(), info->GetContext(), 312 rdh_->delegate()->OnResponseStarted(request(), info->GetContext(),
309 response); 313 response);
310 } 314 }
311 315
312 ResourceMessageFilter* filter = GetFilter(); 316 ResourceMessageFilter* filter = GetFilter();
313 if (!filter) 317 if (!filter) {
314 return false; 318 controller->Cancel();
319 return;
320 }
315 321
316 NetLogObserver::PopulateResponseInfo(request(), response); 322 NetLogObserver::PopulateResponseInfo(request(), response);
317 response->head.encoded_data_length = request()->raw_header_size(); 323 response->head.encoded_data_length = request()->raw_header_size();
318 324
319 // If the parent handler downloaded the resource to a file, grant the child 325 // If the parent handler downloaded the resource to a file, grant the child
320 // read permissions on it. 326 // read permissions on it.
321 if (!response->head.download_file_path.empty()) { 327 if (!response->head.download_file_path.empty()) {
322 rdh_->RegisterDownloadedTempFile( 328 rdh_->RegisterDownloadedTempFile(
323 info->GetChildID(), info->GetRequestID(), 329 info->GetChildID(), info->GetRequestID(),
324 response->head.download_file_path); 330 response->head.download_file_path);
325 } 331 }
326 332
327 response->head.request_start = request()->creation_time(); 333 response->head.request_start = request()->creation_time();
328 response->head.response_start = TimeTicks::Now(); 334 response->head.response_start = TimeTicks::Now();
329 filter->Send( 335 filter->Send(
330 new ResourceMsg_ReceivedResponse(GetRequestID(), response->head)); 336 new ResourceMsg_ReceivedResponse(GetRequestID(), response->head));
331 sent_received_response_msg_ = true; 337 sent_received_response_msg_ = true;
332 338
333 if (request()->response_info().metadata.get()) { 339 if (request()->response_info().metadata.get()) {
334 std::vector<char> copy(request()->response_info().metadata->data(), 340 std::vector<char> copy(request()->response_info().metadata->data(),
335 request()->response_info().metadata->data() + 341 request()->response_info().metadata->data() +
336 request()->response_info().metadata->size()); 342 request()->response_info().metadata->size());
337 filter->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), copy)); 343 filter->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), copy));
338 } 344 }
339 345
340 inlining_helper_->OnResponseReceived(*response); 346 inlining_helper_->OnResponseReceived(*response);
341 return true; 347 controller->Resume();
342 } 348 }
343 349
344 bool AsyncResourceHandler::OnWillStart(const GURL& url, bool* defer) { 350 void AsyncResourceHandler::OnWillStart(
351 const GURL& url,
352 std::unique_ptr<ResourceController> controller) {
345 ResourceMessageFilter* filter = GetFilter(); 353 ResourceMessageFilter* filter = GetFilter();
346 if (!filter) 354 if (!filter) {
347 return false; 355 controller->Cancel();
356 return;
357 }
348 358
349 if (GetRequestInfo()->is_upload_progress_enabled() && 359 if (GetRequestInfo()->is_upload_progress_enabled() &&
350 request()->has_upload()) { 360 request()->has_upload()) {
351 upload_progress_tracker_ = base::MakeUnique<UploadProgressTracker>( 361 upload_progress_tracker_ = base::MakeUnique<UploadProgressTracker>(
352 FROM_HERE, 362 FROM_HERE,
353 base::BindRepeating(&AsyncResourceHandler::SendUploadProgress, 363 base::BindRepeating(&AsyncResourceHandler::SendUploadProgress,
354 base::Unretained(this)), 364 base::Unretained(this)),
355 request()); 365 request());
356 } 366 }
357 return true; 367 controller->Resume();
358 } 368 }
359 369
360 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, 370 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
361 int* buf_size, 371 int* buf_size,
362 int min_size) { 372 int min_size) {
373 DCHECK(!has_controller());
363 DCHECK_EQ(-1, min_size); 374 DCHECK_EQ(-1, min_size);
364 375
376 // TODO(mmenke): Should fail with ERR_INSUFFICIENT_RESOURCES here.
365 if (!CheckForSufficientResource()) 377 if (!CheckForSufficientResource())
366 return false; 378 return false;
367 379
368 // Return early if InliningHelper allocates the buffer, so that we should 380 // Return early if InliningHelper allocates the buffer, so that we should
369 // inline the data into the IPC message without allocating SharedMemory. 381 // inline the data into the IPC message without allocating SharedMemory.
370 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) 382 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size))
371 return true; 383 return true;
372 384
373 if (!EnsureResourceBufferIsInitialized()) 385 if (!EnsureResourceBufferIsInitialized())
374 return false; 386 return false;
375 387
376 DCHECK(buffer_->CanAllocate()); 388 DCHECK(buffer_->CanAllocate());
377 char* memory = buffer_->Allocate(&allocation_size_); 389 char* memory = buffer_->Allocate(&allocation_size_);
378 CHECK(memory); 390 CHECK(memory);
379 391
380 *buf = new DependentIOBuffer(buffer_.get(), memory); 392 *buf = new DependentIOBuffer(buffer_.get(), memory);
381 *buf_size = allocation_size_; 393 *buf_size = allocation_size_;
382 394
383 return true; 395 return true;
384 } 396 }
385 397
386 bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { 398 void AsyncResourceHandler::OnReadCompleted(
399 int bytes_read,
400 std::unique_ptr<ResourceController> controller) {
401 DCHECK(!has_controller());
387 DCHECK_GE(bytes_read, 0); 402 DCHECK_GE(bytes_read, 0);
388 403
389 if (!bytes_read) 404 if (!bytes_read) {
390 return true; 405 controller->Resume();
406 return;
407 }
391 408
392 ResourceMessageFilter* filter = GetFilter(); 409 ResourceMessageFilter* filter = GetFilter();
393 if (!filter) 410 if (!filter) {
394 return false; 411 controller->Cancel();
412 return;
413 }
395 414
396 int encoded_data_length = CalculateEncodedDataLengthToReport(); 415 int encoded_data_length = CalculateEncodedDataLengthToReport();
397 if (!first_chunk_read_) 416 if (!first_chunk_read_)
398 encoded_data_length -= request()->raw_header_size(); 417 encoded_data_length -= request()->raw_header_size();
399 418
400 first_chunk_read_ = true; 419 first_chunk_read_ = true;
401 420
402 // Return early if InliningHelper handled the received data. 421 // Return early if InliningHelper handled the received data.
403 if (inlining_helper_->SendInlinedDataIfApplicable( 422 if (inlining_helper_->SendInlinedDataIfApplicable(
404 bytes_read, encoded_data_length, filter, 423 bytes_read, encoded_data_length, filter, GetRequestID())) {
405 GetRequestID())) 424 controller->Resume();
406 return true; 425 return;
426 }
407 427
408 buffer_->ShrinkLastAllocation(bytes_read); 428 buffer_->ShrinkLastAllocation(bytes_read);
409 429
410 total_read_body_bytes_ += bytes_read; 430 total_read_body_bytes_ += bytes_read;
411 431
412 if (!sent_data_buffer_msg_) { 432 if (!sent_data_buffer_msg_) {
413 base::SharedMemoryHandle handle = base::SharedMemory::DuplicateHandle( 433 base::SharedMemoryHandle handle = base::SharedMemory::DuplicateHandle(
414 buffer_->GetSharedMemory().handle()); 434 buffer_->GetSharedMemory().handle());
415 if (!base::SharedMemory::IsHandleValid(handle)) 435 if (!base::SharedMemory::IsHandleValid(handle)) {
416 return false; 436 controller->Cancel();
437 return;
438 }
417 filter->Send(new ResourceMsg_SetDataBuffer( 439 filter->Send(new ResourceMsg_SetDataBuffer(
418 GetRequestID(), handle, buffer_->GetSharedMemory().mapped_size(), 440 GetRequestID(), handle, buffer_->GetSharedMemory().mapped_size(),
419 filter->peer_pid())); 441 filter->peer_pid()));
420 sent_data_buffer_msg_ = true; 442 sent_data_buffer_msg_ = true;
421 } 443 }
422 444
423 int data_offset = buffer_->GetLastAllocationOffset(); 445 int data_offset = buffer_->GetLastAllocationOffset();
424 446
425 filter->Send(new ResourceMsg_DataReceived(GetRequestID(), data_offset, 447 filter->Send(new ResourceMsg_DataReceived(GetRequestID(), data_offset,
426 bytes_read, encoded_data_length)); 448 bytes_read, encoded_data_length));
427 ++pending_data_count_; 449 ++pending_data_count_;
428 450
429 if (!buffer_->CanAllocate()) { 451 if (!buffer_->CanAllocate()) {
430 *defer = did_defer_ = true; 452 OnDefer(std::move(controller));
431 OnDefer(); 453 } else {
454 controller->Resume();
432 } 455 }
433
434 return true;
435 } 456 }
436 457
437 void AsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) { 458 void AsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) {
438 int encoded_data_length = CalculateEncodedDataLengthToReport(); 459 int encoded_data_length = CalculateEncodedDataLengthToReport();
439 460
440 ResourceMessageFilter* filter = GetFilter(); 461 ResourceMessageFilter* filter = GetFilter();
441 if (filter) { 462 if (filter) {
442 filter->Send(new ResourceMsg_DataDownloaded( 463 filter->Send(new ResourceMsg_DataDownloaded(
443 GetRequestID(), bytes_downloaded, encoded_data_length)); 464 GetRequestID(), bytes_downloaded, encoded_data_length));
444 } 465 }
445 } 466 }
446 467
447 void AsyncResourceHandler::OnResponseCompleted( 468 void AsyncResourceHandler::OnResponseCompleted(
448 const net::URLRequestStatus& status, 469 const net::URLRequestStatus& status,
449 bool* defer) { 470 std::unique_ptr<ResourceController> controller) {
450 ResourceMessageFilter* filter = GetFilter(); 471 ResourceMessageFilter* filter = GetFilter();
451 if (!filter) 472 if (!filter) {
473 controller->Resume();
452 return; 474 return;
475 }
453 476
454 // Ensure sending the final upload progress message here, since 477 // Ensure sending the final upload progress message here, since
455 // OnResponseCompleted can be called without OnResponseStarted on cancellation 478 // OnResponseCompleted can be called without OnResponseStarted on cancellation
456 // or error cases. 479 // or error cases.
457 if (upload_progress_tracker_) { 480 if (upload_progress_tracker_) {
458 upload_progress_tracker_->OnUploadCompleted(); 481 upload_progress_tracker_->OnUploadCompleted();
459 upload_progress_tracker_ = nullptr; 482 upload_progress_tracker_ = nullptr;
460 } 483 }
461 484
462 // If we crash here, figure out what URL the renderer was requesting. 485 // 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; 512 request_complete_data.exists_in_cache = request()->response_info().was_cached;
490 request_complete_data.completion_time = TimeTicks::Now(); 513 request_complete_data.completion_time = TimeTicks::Now();
491 request_complete_data.encoded_data_length = 514 request_complete_data.encoded_data_length =
492 request()->GetTotalReceivedBytes(); 515 request()->GetTotalReceivedBytes();
493 request_complete_data.encoded_body_length = request()->GetRawBodyBytes(); 516 request_complete_data.encoded_body_length = request()->GetRawBodyBytes();
494 filter->Send( 517 filter->Send(
495 new ResourceMsg_RequestComplete(GetRequestID(), request_complete_data)); 518 new ResourceMsg_RequestComplete(GetRequestID(), request_complete_data));
496 519
497 if (status.is_success()) 520 if (status.is_success())
498 RecordHistogram(); 521 RecordHistogram();
522 controller->Resume();
499 } 523 }
500 524
501 bool AsyncResourceHandler::EnsureResourceBufferIsInitialized() { 525 bool AsyncResourceHandler::EnsureResourceBufferIsInitialized() {
502 DCHECK(has_checked_for_sufficient_resources_); 526 DCHECK(has_checked_for_sufficient_resources_);
503 527
504 if (buffer_.get() && buffer_->IsInitialized()) 528 if (buffer_.get() && buffer_->IsInitialized())
505 return true; 529 return true;
506 530
507 buffer_ = new ResourceBuffer(); 531 buffer_ = new ResourceBuffer();
508 return buffer_->Initialize(kBufferSize, 532 return buffer_->Initialize(kBufferSize,
509 kMinAllocationSize, 533 kMinAllocationSize,
510 kMaxAllocationSize); 534 kMaxAllocationSize);
511 } 535 }
512 536
513 void AsyncResourceHandler::ResumeIfDeferred() { 537 void AsyncResourceHandler::ResumeIfDeferred() {
514 if (did_defer_) { 538 if (has_controller()) {
515 did_defer_ = false;
516 request()->LogUnblocked(); 539 request()->LogUnblocked();
517 controller()->Resume(); 540 Resume();
518 } 541 }
519 } 542 }
520 543
521 void AsyncResourceHandler::OnDefer() { 544 void AsyncResourceHandler::OnDefer(
545 std::unique_ptr<ResourceController> controller) {
546 HoldController(std::move(controller));
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
« no previous file with comments | « content/browser/loader/async_resource_handler.h ('k') | content/browser/loader/detachable_resource_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698