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

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

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

Powered by Google App Engine
This is Rietveld 408576698