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

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

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

Powered by Google App Engine
This is Rietveld 408576698