Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 210 allocation_size_(0), | 210 allocation_size_(0), |
| 211 did_defer_(false), | 211 did_defer_(false), |
| 212 has_checked_for_sufficient_resources_(false), | 212 has_checked_for_sufficient_resources_(false), |
| 213 sent_received_response_msg_(false), | 213 sent_received_response_msg_(false), |
| 214 sent_data_buffer_msg_(false), | 214 sent_data_buffer_msg_(false), |
| 215 inlining_helper_(new InliningHelper), | 215 inlining_helper_(new InliningHelper), |
| 216 last_upload_position_(0), | 216 last_upload_position_(0), |
| 217 waiting_for_upload_progress_ack_(false), | 217 waiting_for_upload_progress_ack_(false), |
| 218 reported_transfer_size_(0), | 218 reported_transfer_size_(0), |
| 219 reported_encoded_body_length_(0) { | 219 reported_encoded_body_length_(0) { |
| 220 DCHECK(GetRequestInfo()->requester_info().IsRenderer()); | |
|
mmenke
2016/11/17 16:27:19
include base/logging.h
horo
2016/11/17 17:50:27
Already included.
| |
| 220 InitializeResourceBufferConstants(); | 221 InitializeResourceBufferConstants(); |
| 221 } | 222 } |
| 222 | 223 |
| 223 AsyncResourceHandler::~AsyncResourceHandler() { | 224 AsyncResourceHandler::~AsyncResourceHandler() { |
| 224 if (has_checked_for_sufficient_resources_) | 225 if (has_checked_for_sufficient_resources_) |
| 225 rdh_->FinishedWithResourcesForRequest(request()); | 226 rdh_->FinishedWithResourcesForRequest(request()); |
| 226 } | 227 } |
| 227 | 228 |
| 228 bool AsyncResourceHandler::OnMessageReceived(const IPC::Message& message) { | 229 bool AsyncResourceHandler::OnMessageReceived(const IPC::Message& message) { |
| 229 bool handled = true; | 230 bool handled = true; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 254 ResumeIfDeferred(); | 255 ResumeIfDeferred(); |
| 255 } | 256 } |
| 256 } | 257 } |
| 257 | 258 |
| 258 void AsyncResourceHandler::OnUploadProgressACK(int request_id) { | 259 void AsyncResourceHandler::OnUploadProgressACK(int request_id) { |
| 259 waiting_for_upload_progress_ack_ = false; | 260 waiting_for_upload_progress_ack_ = false; |
| 260 } | 261 } |
| 261 | 262 |
| 262 void AsyncResourceHandler::ReportUploadProgress() { | 263 void AsyncResourceHandler::ReportUploadProgress() { |
| 263 DCHECK(GetRequestInfo()->is_upload_progress_enabled()); | 264 DCHECK(GetRequestInfo()->is_upload_progress_enabled()); |
| 265 DCHECK(GetRequestInfo()->requester_info().IsRenderer()); | |
|
mmenke
2016/11/17 16:27:19
Is this needed? This is constant for the lifetime
horo
2016/11/17 17:50:26
Done.
| |
| 264 if (waiting_for_upload_progress_ack_) | 266 if (waiting_for_upload_progress_ack_) |
| 265 return; // Send one progress event at a time. | 267 return; // Send one progress event at a time. |
| 266 | 268 |
| 267 net::UploadProgress progress = request()->GetUploadProgress(); | 269 net::UploadProgress progress = request()->GetUploadProgress(); |
| 268 if (!progress.size()) | 270 if (!progress.size()) |
| 269 return; // Nothing to upload. | 271 return; // Nothing to upload. |
| 270 | 272 |
| 271 if (progress.position() == last_upload_position_) | 273 if (progress.position() == last_upload_position_) |
| 272 return; // No progress made since last time. | 274 return; // No progress made since last time. |
| 273 | 275 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 293 waiting_for_upload_progress_ack_ = true; | 295 waiting_for_upload_progress_ack_ = true; |
| 294 last_upload_ticks_ = TimeTicks::Now(); | 296 last_upload_ticks_ = TimeTicks::Now(); |
| 295 last_upload_position_ = progress.position(); | 297 last_upload_position_ = progress.position(); |
| 296 } | 298 } |
| 297 } | 299 } |
| 298 | 300 |
| 299 bool AsyncResourceHandler::OnRequestRedirected( | 301 bool AsyncResourceHandler::OnRequestRedirected( |
| 300 const net::RedirectInfo& redirect_info, | 302 const net::RedirectInfo& redirect_info, |
| 301 ResourceResponse* response, | 303 ResourceResponse* response, |
| 302 bool* defer) { | 304 bool* defer) { |
| 303 const ResourceRequestInfoImpl* info = GetRequestInfo(); | 305 DCHECK(GetRequestInfo()->requester_info().IsRenderer()); |
| 304 if (!info->filter()) | 306 ResourceMessageFilter* filter = GetFilter(); |
| 307 if (!filter) | |
| 305 return false; | 308 return false; |
| 306 | 309 |
| 307 *defer = did_defer_ = true; | 310 *defer = did_defer_ = true; |
| 308 OnDefer(); | 311 OnDefer(); |
| 309 | 312 |
| 310 NetLogObserver::PopulateResponseInfo(request(), response); | 313 NetLogObserver::PopulateResponseInfo(request(), response); |
| 311 response->head.encoded_data_length = request()->GetTotalReceivedBytes(); | 314 response->head.encoded_data_length = request()->GetTotalReceivedBytes(); |
| 312 reported_transfer_size_ = 0; | 315 reported_transfer_size_ = 0; |
| 313 response->head.request_start = request()->creation_time(); | 316 response->head.request_start = request()->creation_time(); |
| 314 response->head.response_start = TimeTicks::Now(); | 317 response->head.response_start = TimeTicks::Now(); |
| 315 // TODO(davidben): Is it necessary to pass the new first party URL for | 318 // TODO(davidben): Is it necessary to pass the new first party URL for |
| 316 // cookies? The only case where it can change is top-level navigation requests | 319 // cookies? The only case where it can change is top-level navigation requests |
| 317 // and hopefully those will eventually all be owned by the browser. It's | 320 // and hopefully those will eventually all be owned by the browser. It's |
| 318 // possible this is still needed while renderer-owned ones exist. | 321 // possible this is still needed while renderer-owned ones exist. |
| 319 return info->filter()->Send(new ResourceMsg_ReceivedRedirect( | 322 return filter->Send(new ResourceMsg_ReceivedRedirect( |
| 320 GetRequestID(), redirect_info, response->head)); | 323 GetRequestID(), redirect_info, response->head)); |
| 321 } | 324 } |
| 322 | 325 |
| 323 bool AsyncResourceHandler::OnResponseStarted(ResourceResponse* response, | 326 bool AsyncResourceHandler::OnResponseStarted(ResourceResponse* response, |
| 324 bool* defer) { | 327 bool* defer) { |
| 328 DCHECK(GetRequestInfo()->requester_info().IsRenderer()); | |
| 325 // For changes to the main frame, inform the renderer of the new URL's | 329 // For changes to the main frame, inform the renderer of the new URL's |
| 326 // per-host settings before the request actually commits. This way the | 330 // per-host settings before the request actually commits. This way the |
| 327 // renderer will be able to set these precisely at the time the | 331 // renderer will be able to set these precisely at the time the |
| 328 // request commits, avoiding the possibility of e.g. zooming the old content | 332 // request commits, avoiding the possibility of e.g. zooming the old content |
| 329 // or of having to layout the new content twice. | 333 // or of having to layout the new content twice. |
| 330 | 334 |
| 331 response_started_ticks_ = base::TimeTicks::Now(); | 335 response_started_ticks_ = base::TimeTicks::Now(); |
| 332 | 336 |
| 333 progress_timer_.Stop(); | 337 progress_timer_.Stop(); |
| 334 const ResourceRequestInfoImpl* info = GetRequestInfo(); | 338 const ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 335 if (!info->filter()) | 339 ResourceMessageFilter* filter = GetFilter(); |
| 340 if (!filter) | |
| 336 return false; | 341 return false; |
| 337 | 342 |
| 338 // We want to send a final upload progress message prior to sending the | 343 // We want to send a final upload progress message prior to sending the |
| 339 // response complete message even if we're waiting for an ack to to a | 344 // response complete message even if we're waiting for an ack to to a |
| 340 // previous upload progress message. | 345 // previous upload progress message. |
| 341 if (info->is_upload_progress_enabled()) { | 346 if (info->is_upload_progress_enabled()) { |
| 342 waiting_for_upload_progress_ack_ = false; | 347 waiting_for_upload_progress_ack_ = false; |
| 343 ReportUploadProgress(); | 348 ReportUploadProgress(); |
| 344 } | 349 } |
| 345 | 350 |
| 346 if (rdh_->delegate()) { | 351 if (rdh_->delegate()) { |
| 347 rdh_->delegate()->OnResponseStarted(request(), info->GetContext(), | 352 rdh_->delegate()->OnResponseStarted(request(), info->GetContext(), |
| 348 response); | 353 response); |
| 349 } | 354 } |
| 350 | 355 |
| 351 NetLogObserver::PopulateResponseInfo(request(), response); | 356 NetLogObserver::PopulateResponseInfo(request(), response); |
| 352 response->head.encoded_data_length = request()->raw_header_size(); | 357 response->head.encoded_data_length = request()->raw_header_size(); |
| 353 | 358 |
| 354 // If the parent handler downloaded the resource to a file, grant the child | 359 // If the parent handler downloaded the resource to a file, grant the child |
| 355 // read permissions on it. | 360 // read permissions on it. |
| 356 if (!response->head.download_file_path.empty()) { | 361 if (!response->head.download_file_path.empty()) { |
| 357 rdh_->RegisterDownloadedTempFile( | 362 rdh_->RegisterDownloadedTempFile( |
| 358 info->GetChildID(), info->GetRequestID(), | 363 info->GetChildID(), info->GetRequestID(), |
| 359 response->head.download_file_path); | 364 response->head.download_file_path); |
| 360 } | 365 } |
| 361 | 366 |
| 362 response->head.request_start = request()->creation_time(); | 367 response->head.request_start = request()->creation_time(); |
| 363 response->head.response_start = TimeTicks::Now(); | 368 response->head.response_start = TimeTicks::Now(); |
| 364 info->filter()->Send(new ResourceMsg_ReceivedResponse(GetRequestID(), | 369 filter->Send( |
| 365 response->head)); | 370 new ResourceMsg_ReceivedResponse(GetRequestID(), response->head)); |
| 366 sent_received_response_msg_ = true; | 371 sent_received_response_msg_ = true; |
| 367 | 372 |
| 368 if (request()->response_info().metadata.get()) { | 373 if (request()->response_info().metadata.get()) { |
| 369 std::vector<char> copy(request()->response_info().metadata->data(), | 374 std::vector<char> copy(request()->response_info().metadata->data(), |
| 370 request()->response_info().metadata->data() + | 375 request()->response_info().metadata->data() + |
| 371 request()->response_info().metadata->size()); | 376 request()->response_info().metadata->size()); |
| 372 info->filter()->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), | 377 filter->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), copy)); |
| 373 copy)); | |
| 374 } | 378 } |
| 375 | 379 |
| 376 inlining_helper_->OnResponseReceived(*response); | 380 inlining_helper_->OnResponseReceived(*response); |
| 377 return true; | 381 return true; |
| 378 } | 382 } |
| 379 | 383 |
| 380 bool AsyncResourceHandler::OnWillStart(const GURL& url, bool* defer) { | 384 bool AsyncResourceHandler::OnWillStart(const GURL& url, bool* defer) { |
| 385 DCHECK(GetRequestInfo()->requester_info().IsRenderer()); | |
| 381 if (GetRequestInfo()->is_upload_progress_enabled() && | 386 if (GetRequestInfo()->is_upload_progress_enabled() && |
| 382 request()->has_upload()) { | 387 request()->has_upload()) { |
| 383 ReportUploadProgress(); | 388 ReportUploadProgress(); |
| 384 progress_timer_.Start( | 389 progress_timer_.Start( |
| 385 FROM_HERE, | 390 FROM_HERE, |
| 386 base::TimeDelta::FromMilliseconds(kUploadProgressIntervalMsec), | 391 base::TimeDelta::FromMilliseconds(kUploadProgressIntervalMsec), |
| 387 this, | 392 this, |
| 388 &AsyncResourceHandler::ReportUploadProgress); | 393 &AsyncResourceHandler::ReportUploadProgress); |
| 389 } | 394 } |
| 390 return true; | 395 return true; |
| 391 } | 396 } |
| 392 | 397 |
| 393 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, | 398 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
| 394 int* buf_size, | 399 int* buf_size, |
| 395 int min_size) { | 400 int min_size) { |
| 401 DCHECK(GetRequestInfo()->requester_info().IsRenderer()); | |
| 396 DCHECK_EQ(-1, min_size); | 402 DCHECK_EQ(-1, min_size); |
| 397 | 403 |
| 398 if (!CheckForSufficientResource()) | 404 if (!CheckForSufficientResource()) |
| 399 return false; | 405 return false; |
| 400 | 406 |
| 401 // Return early if InliningHelper allocates the buffer, so that we should | 407 // Return early if InliningHelper allocates the buffer, so that we should |
| 402 // inline the data into the IPC message without allocating SharedMemory. | 408 // inline the data into the IPC message without allocating SharedMemory. |
| 403 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) | 409 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) |
| 404 return true; | 410 return true; |
| 405 | 411 |
| 406 if (!EnsureResourceBufferIsInitialized()) | 412 if (!EnsureResourceBufferIsInitialized()) |
| 407 return false; | 413 return false; |
| 408 | 414 |
| 409 DCHECK(buffer_->CanAllocate()); | 415 DCHECK(buffer_->CanAllocate()); |
| 410 char* memory = buffer_->Allocate(&allocation_size_); | 416 char* memory = buffer_->Allocate(&allocation_size_); |
| 411 CHECK(memory); | 417 CHECK(memory); |
| 412 | 418 |
| 413 *buf = new DependentIOBuffer(buffer_.get(), memory); | 419 *buf = new DependentIOBuffer(buffer_.get(), memory); |
| 414 *buf_size = allocation_size_; | 420 *buf_size = allocation_size_; |
| 415 | 421 |
| 416 return true; | 422 return true; |
| 417 } | 423 } |
| 418 | 424 |
| 419 bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { | 425 bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { |
| 426 DCHECK(GetRequestInfo()->requester_info().IsRenderer()); | |
| 420 DCHECK_GE(bytes_read, 0); | 427 DCHECK_GE(bytes_read, 0); |
| 421 | 428 |
| 422 if (!bytes_read) | 429 if (!bytes_read) |
| 423 return true; | 430 return true; |
| 424 | 431 |
| 425 ResourceMessageFilter* filter = GetFilter(); | 432 ResourceMessageFilter* filter = GetFilter(); |
| 426 if (!filter) | 433 if (!filter) |
| 427 return false; | 434 return false; |
| 428 | 435 |
| 429 int encoded_data_length = CalculateEncodedDataLengthToReport(); | 436 int encoded_data_length = CalculateEncodedDataLengthToReport(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 461 | 468 |
| 462 if (!buffer_->CanAllocate()) { | 469 if (!buffer_->CanAllocate()) { |
| 463 *defer = did_defer_ = true; | 470 *defer = did_defer_ = true; |
| 464 OnDefer(); | 471 OnDefer(); |
| 465 } | 472 } |
| 466 | 473 |
| 467 return true; | 474 return true; |
| 468 } | 475 } |
| 469 | 476 |
| 470 void AsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) { | 477 void AsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) { |
| 478 DCHECK(GetRequestInfo()->requester_info().IsRenderer()); | |
| 471 int encoded_data_length = CalculateEncodedDataLengthToReport(); | 479 int encoded_data_length = CalculateEncodedDataLengthToReport(); |
| 472 | 480 |
| 473 ResourceMessageFilter* filter = GetFilter(); | 481 ResourceMessageFilter* filter = GetFilter(); |
| 474 if (filter) { | 482 if (filter) { |
| 475 filter->Send(new ResourceMsg_DataDownloaded( | 483 filter->Send(new ResourceMsg_DataDownloaded( |
| 476 GetRequestID(), bytes_downloaded, encoded_data_length)); | 484 GetRequestID(), bytes_downloaded, encoded_data_length)); |
| 477 } | 485 } |
| 478 } | 486 } |
| 479 | 487 |
| 480 void AsyncResourceHandler::OnResponseCompleted( | 488 void AsyncResourceHandler::OnResponseCompleted( |
| 481 const net::URLRequestStatus& status, | 489 const net::URLRequestStatus& status, |
| 482 bool* defer) { | 490 bool* defer) { |
| 491 DCHECK(GetRequestInfo()->requester_info().IsRenderer()); | |
| 483 const ResourceRequestInfoImpl* info = GetRequestInfo(); | 492 const ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 484 if (!info->filter()) | 493 ResourceMessageFilter* filter = GetFilter(); |
| 494 if (!filter) | |
| 485 return; | 495 return; |
| 486 | 496 |
| 487 // If we crash here, figure out what URL the renderer was requesting. | 497 // If we crash here, figure out what URL the renderer was requesting. |
| 488 // http://crbug.com/107692 | 498 // http://crbug.com/107692 |
| 489 char url_buf[128]; | 499 char url_buf[128]; |
| 490 base::strlcpy(url_buf, request()->url().spec().c_str(), arraysize(url_buf)); | 500 base::strlcpy(url_buf, request()->url().spec().c_str(), arraysize(url_buf)); |
| 491 base::debug::Alias(url_buf); | 501 base::debug::Alias(url_buf); |
| 492 | 502 |
| 493 // TODO(gavinp): Remove this CHECK when we figure out the cause of | 503 // TODO(gavinp): Remove this CHECK when we figure out the cause of |
| 494 // http://crbug.com/124680 . This check mirrors closely check in | 504 // http://crbug.com/124680 . This check mirrors closely check in |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 507 // the ERR_ABORTED error code). | 517 // the ERR_ABORTED error code). |
| 508 DCHECK(!was_ignored_by_handler || error_code == net::ERR_ABORTED); | 518 DCHECK(!was_ignored_by_handler || error_code == net::ERR_ABORTED); |
| 509 | 519 |
| 510 ResourceRequestCompletionStatus request_complete_data; | 520 ResourceRequestCompletionStatus request_complete_data; |
| 511 request_complete_data.error_code = error_code; | 521 request_complete_data.error_code = error_code; |
| 512 request_complete_data.was_ignored_by_handler = was_ignored_by_handler; | 522 request_complete_data.was_ignored_by_handler = was_ignored_by_handler; |
| 513 request_complete_data.exists_in_cache = request()->response_info().was_cached; | 523 request_complete_data.exists_in_cache = request()->response_info().was_cached; |
| 514 request_complete_data.completion_time = TimeTicks::Now(); | 524 request_complete_data.completion_time = TimeTicks::Now(); |
| 515 request_complete_data.encoded_data_length = | 525 request_complete_data.encoded_data_length = |
| 516 request()->GetTotalReceivedBytes(); | 526 request()->GetTotalReceivedBytes(); |
| 517 info->filter()->Send( | 527 filter->Send( |
| 518 new ResourceMsg_RequestComplete(GetRequestID(), request_complete_data)); | 528 new ResourceMsg_RequestComplete(GetRequestID(), request_complete_data)); |
| 519 | 529 |
| 520 if (status.is_success()) | 530 if (status.is_success()) |
| 521 RecordHistogram(); | 531 RecordHistogram(); |
| 522 } | 532 } |
| 523 | 533 |
| 524 bool AsyncResourceHandler::EnsureResourceBufferIsInitialized() { | 534 bool AsyncResourceHandler::EnsureResourceBufferIsInitialized() { |
| 525 DCHECK(has_checked_for_sufficient_resources_); | 535 DCHECK(has_checked_for_sufficient_resources_); |
| 526 | 536 |
| 527 if (buffer_.get() && buffer_->IsInitialized()) | 537 if (buffer_.get() && buffer_->IsInitialized()) |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 587 } else { | 597 } else { |
| 588 UMA_HISTOGRAM_CUSTOM_COUNTS( | 598 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 589 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", | 599 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", |
| 590 elapsed_time, 1, 100000, 100); | 600 elapsed_time, 1, 100000, 100); |
| 591 } | 601 } |
| 592 | 602 |
| 593 inlining_helper_->RecordHistogram(elapsed_time); | 603 inlining_helper_->RecordHistogram(elapsed_time); |
| 594 } | 604 } |
| 595 | 605 |
| 596 } // namespace content | 606 } // namespace content |
| OLD | NEW |