| 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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 new ResourceMsg_UploadProgress(GetRequestID(), | 289 new ResourceMsg_UploadProgress(GetRequestID(), |
| 290 progress.position(), | 290 progress.position(), |
| 291 progress.size())); | 291 progress.size())); |
| 292 } | 292 } |
| 293 waiting_for_upload_progress_ack_ = true; | 293 waiting_for_upload_progress_ack_ = true; |
| 294 last_upload_ticks_ = TimeTicks::Now(); | 294 last_upload_ticks_ = TimeTicks::Now(); |
| 295 last_upload_position_ = progress.position(); | 295 last_upload_position_ = progress.position(); |
| 296 } | 296 } |
| 297 } | 297 } |
| 298 | 298 |
| 299 bool AsyncResourceHandler::OnRequestRedirected( | 299 void AsyncResourceHandler::OnRequestRedirected( |
| 300 const net::RedirectInfo& redirect_info, | 300 const net::RedirectInfo& redirect_info, |
| 301 ResourceResponse* response, | 301 ResourceResponse* response, |
| 302 bool* defer) { | 302 bool* defer_or_cancel) { |
| 303 *defer_or_cancel = did_defer_ = true; |
| 304 OnDefer(); |
| 305 |
| 303 const ResourceRequestInfoImpl* info = GetRequestInfo(); | 306 const ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 304 if (!info->filter()) | 307 if (!info->filter()) { |
| 305 return false; | 308 controller()->Cancel(); |
| 306 | 309 return; |
| 307 *defer = did_defer_ = true; | 310 } |
| 308 OnDefer(); | |
| 309 | 311 |
| 310 NetLogObserver::PopulateResponseInfo(request(), response); | 312 NetLogObserver::PopulateResponseInfo(request(), response); |
| 311 response->head.encoded_data_length = request()->GetTotalReceivedBytes(); | 313 response->head.encoded_data_length = request()->GetTotalReceivedBytes(); |
| 312 reported_transfer_size_ = 0; | 314 reported_transfer_size_ = 0; |
| 313 response->head.request_start = request()->creation_time(); | 315 response->head.request_start = request()->creation_time(); |
| 314 response->head.response_start = TimeTicks::Now(); | 316 response->head.response_start = TimeTicks::Now(); |
| 315 // TODO(davidben): Is it necessary to pass the new first party URL for | 317 // 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 | 318 // 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 | 319 // and hopefully those will eventually all be owned by the browser. It's |
| 318 // possible this is still needed while renderer-owned ones exist. | 320 // possible this is still needed while renderer-owned ones exist. |
| 319 return info->filter()->Send(new ResourceMsg_ReceivedRedirect( | 321 if (!info->filter()->Send(new ResourceMsg_ReceivedRedirect( |
| 320 GetRequestID(), redirect_info, response->head)); | 322 GetRequestID(), redirect_info, response->head))) { |
| 323 controller()->Cancel(); |
| 324 } |
| 321 } | 325 } |
| 322 | 326 |
| 323 bool AsyncResourceHandler::OnResponseStarted(ResourceResponse* response, | 327 void AsyncResourceHandler::OnResponseStarted(ResourceResponse* response, |
| 324 bool* defer) { | 328 bool* defer_or_cancel) { |
| 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 if (!info->filter()) { |
| 336 return false; | 340 controller()->Cancel(); |
| 341 *defer_or_cancel = true; |
| 342 return; |
| 343 } |
| 337 | 344 |
| 338 // We want to send a final upload progress message prior to sending the | 345 // 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 | 346 // response complete message even if we're waiting for an ack to to a |
| 340 // previous upload progress message. | 347 // previous upload progress message. |
| 341 if (info->is_upload_progress_enabled()) { | 348 if (info->is_upload_progress_enabled()) { |
| 342 waiting_for_upload_progress_ack_ = false; | 349 waiting_for_upload_progress_ack_ = false; |
| 343 ReportUploadProgress(); | 350 ReportUploadProgress(); |
| 344 } | 351 } |
| 345 | 352 |
| 346 if (rdh_->delegate()) { | 353 if (rdh_->delegate()) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 367 | 374 |
| 368 if (request()->response_info().metadata.get()) { | 375 if (request()->response_info().metadata.get()) { |
| 369 std::vector<char> copy(request()->response_info().metadata->data(), | 376 std::vector<char> copy(request()->response_info().metadata->data(), |
| 370 request()->response_info().metadata->data() + | 377 request()->response_info().metadata->data() + |
| 371 request()->response_info().metadata->size()); | 378 request()->response_info().metadata->size()); |
| 372 info->filter()->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), | 379 info->filter()->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), |
| 373 copy)); | 380 copy)); |
| 374 } | 381 } |
| 375 | 382 |
| 376 inlining_helper_->OnResponseReceived(*response); | 383 inlining_helper_->OnResponseReceived(*response); |
| 377 return true; | |
| 378 } | 384 } |
| 379 | 385 |
| 380 bool AsyncResourceHandler::OnWillStart(const GURL& url, bool* defer) { | 386 void AsyncResourceHandler::OnWillStart(const GURL& url, bool* defer_or_cancel) { |
| 381 if (GetRequestInfo()->is_upload_progress_enabled() && | 387 if (GetRequestInfo()->is_upload_progress_enabled() && |
| 382 request()->has_upload()) { | 388 request()->has_upload()) { |
| 383 ReportUploadProgress(); | 389 ReportUploadProgress(); |
| 384 progress_timer_.Start( | 390 progress_timer_.Start( |
| 385 FROM_HERE, | 391 FROM_HERE, |
| 386 base::TimeDelta::FromMilliseconds(kUploadProgressIntervalMsec), | 392 base::TimeDelta::FromMilliseconds(kUploadProgressIntervalMsec), |
| 387 this, | 393 this, |
| 388 &AsyncResourceHandler::ReportUploadProgress); | 394 &AsyncResourceHandler::ReportUploadProgress); |
| 389 } | 395 } |
| 390 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) { |
| 396 DCHECK_EQ(-1, min_size); | 401 DCHECK_EQ(-1, min_size); |
| 397 | 402 |
| 398 if (!CheckForSufficientResource()) | 403 if (!CheckForSufficientResource()) |
| 399 return false; | 404 return false; |
| 400 | 405 |
| 401 // Return early if InliningHelper allocates the buffer, so that we should | 406 // Return early if InliningHelper allocates the buffer, so that we should |
| 402 // inline the data into the IPC message without allocating SharedMemory. | 407 // inline the data into the IPC message without allocating SharedMemory. |
| 403 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) | 408 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) |
| 404 return true; | 409 return true; |
| 405 | 410 |
| 406 if (!EnsureResourceBufferIsInitialized()) | 411 if (!EnsureResourceBufferIsInitialized()) |
| 407 return false; | 412 return false; |
| 408 | 413 |
| 409 DCHECK(buffer_->CanAllocate()); | 414 DCHECK(buffer_->CanAllocate()); |
| 410 char* memory = buffer_->Allocate(&allocation_size_); | 415 char* memory = buffer_->Allocate(&allocation_size_); |
| 411 CHECK(memory); | 416 CHECK(memory); |
| 412 | 417 |
| 413 *buf = new DependentIOBuffer(buffer_.get(), memory); | 418 *buf = new DependentIOBuffer(buffer_.get(), memory); |
| 414 *buf_size = allocation_size_; | 419 *buf_size = allocation_size_; |
| 415 | 420 |
| 416 return true; | 421 return true; |
| 417 } | 422 } |
| 418 | 423 |
| 419 bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { | 424 void AsyncResourceHandler::OnReadCompleted(int bytes_read, |
| 425 bool* defer_or_cancel) { |
| 420 DCHECK_GE(bytes_read, 0); | 426 DCHECK_GE(bytes_read, 0); |
| 421 | 427 |
| 422 if (!bytes_read) | 428 if (!bytes_read) |
| 423 return true; | 429 return; |
| 424 | 430 |
| 425 ResourceMessageFilter* filter = GetFilter(); | 431 ResourceMessageFilter* filter = GetFilter(); |
| 426 if (!filter) | 432 if (!filter) { |
| 427 return false; | 433 controller()->Cancel(); |
| 434 *defer_or_cancel = true; |
| 435 return; |
| 436 } |
| 428 | 437 |
| 429 int encoded_data_length = CalculateEncodedDataLengthToReport(); | 438 int encoded_data_length = CalculateEncodedDataLengthToReport(); |
| 430 if (!first_chunk_read_) | 439 if (!first_chunk_read_) |
| 431 encoded_data_length -= request()->raw_header_size(); | 440 encoded_data_length -= request()->raw_header_size(); |
| 432 | 441 |
| 433 int encoded_body_length = CalculateEncodedBodyLengthToReport(); | 442 int encoded_body_length = CalculateEncodedBodyLengthToReport(); |
| 434 first_chunk_read_ = true; | 443 first_chunk_read_ = true; |
| 435 | 444 |
| 436 // Return early if InliningHelper handled the received data. | 445 // Return early if InliningHelper handled the received data. |
| 437 if (inlining_helper_->SendInlinedDataIfApplicable( | 446 if (inlining_helper_->SendInlinedDataIfApplicable( |
| 438 bytes_read, encoded_data_length, encoded_body_length, filter, | 447 bytes_read, encoded_data_length, encoded_body_length, filter, |
| 439 GetRequestID())) | 448 GetRequestID())) { |
| 440 return true; | 449 return; |
| 450 } |
| 441 | 451 |
| 442 buffer_->ShrinkLastAllocation(bytes_read); | 452 buffer_->ShrinkLastAllocation(bytes_read); |
| 443 | 453 |
| 444 if (!sent_data_buffer_msg_) { | 454 if (!sent_data_buffer_msg_) { |
| 445 base::SharedMemoryHandle handle = base::SharedMemory::DuplicateHandle( | 455 base::SharedMemoryHandle handle = base::SharedMemory::DuplicateHandle( |
| 446 buffer_->GetSharedMemory().handle()); | 456 buffer_->GetSharedMemory().handle()); |
| 447 if (!base::SharedMemory::IsHandleValid(handle)) | 457 if (!base::SharedMemory::IsHandleValid(handle)) { |
| 448 return false; | 458 controller()->Cancel(); |
| 459 *defer_or_cancel = true; |
| 460 return; |
| 461 } |
| 449 filter->Send(new ResourceMsg_SetDataBuffer( | 462 filter->Send(new ResourceMsg_SetDataBuffer( |
| 450 GetRequestID(), handle, buffer_->GetSharedMemory().mapped_size(), | 463 GetRequestID(), handle, buffer_->GetSharedMemory().mapped_size(), |
| 451 filter->peer_pid())); | 464 filter->peer_pid())); |
| 452 sent_data_buffer_msg_ = true; | 465 sent_data_buffer_msg_ = true; |
| 453 } | 466 } |
| 454 | 467 |
| 455 int data_offset = buffer_->GetLastAllocationOffset(); | 468 int data_offset = buffer_->GetLastAllocationOffset(); |
| 456 | 469 |
| 457 filter->Send(new ResourceMsg_DataReceived(GetRequestID(), data_offset, | 470 filter->Send(new ResourceMsg_DataReceived(GetRequestID(), data_offset, |
| 458 bytes_read, encoded_data_length, | 471 bytes_read, encoded_data_length, |
| 459 encoded_body_length)); | 472 encoded_body_length)); |
| 460 ++pending_data_count_; | 473 ++pending_data_count_; |
| 461 | 474 |
| 462 if (!buffer_->CanAllocate()) { | 475 if (!buffer_->CanAllocate()) { |
| 463 *defer = did_defer_ = true; | 476 *defer_or_cancel = did_defer_ = true; |
| 464 OnDefer(); | 477 OnDefer(); |
| 465 } | 478 } |
| 466 | |
| 467 return true; | |
| 468 } | 479 } |
| 469 | 480 |
| 470 void AsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) { | 481 void AsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) { |
| 471 int encoded_data_length = CalculateEncodedDataLengthToReport(); | 482 int encoded_data_length = CalculateEncodedDataLengthToReport(); |
| 472 | 483 |
| 473 ResourceMessageFilter* filter = GetFilter(); | 484 ResourceMessageFilter* filter = GetFilter(); |
| 474 if (filter) { | 485 if (filter) { |
| 475 filter->Send(new ResourceMsg_DataDownloaded( | 486 filter->Send(new ResourceMsg_DataDownloaded( |
| 476 GetRequestID(), bytes_downloaded, encoded_data_length)); | 487 GetRequestID(), bytes_downloaded, encoded_data_length)); |
| 477 } | 488 } |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 } else { | 598 } else { |
| 588 UMA_HISTOGRAM_CUSTOM_COUNTS( | 599 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 589 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", | 600 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", |
| 590 elapsed_time, 1, 100000, 100); | 601 elapsed_time, 1, 100000, 100); |
| 591 } | 602 } |
| 592 | 603 |
| 593 inlining_helper_->RecordHistogram(elapsed_time); | 604 inlining_helper_->RecordHistogram(elapsed_time); |
| 594 } | 605 } |
| 595 | 606 |
| 596 } // namespace content | 607 } // namespace content |
| OLD | NEW |