| 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 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 pending_data_count_(0), | 200 pending_data_count_(0), |
| 201 allocation_size_(0), | 201 allocation_size_(0), |
| 202 did_defer_(false), | 202 did_defer_(false), |
| 203 has_checked_for_sufficient_resources_(false), | 203 has_checked_for_sufficient_resources_(false), |
| 204 sent_received_response_msg_(false), | 204 sent_received_response_msg_(false), |
| 205 sent_data_buffer_msg_(false), | 205 sent_data_buffer_msg_(false), |
| 206 inlining_helper_(new InliningHelper), | 206 inlining_helper_(new InliningHelper), |
| 207 last_upload_position_(0), | 207 last_upload_position_(0), |
| 208 waiting_for_upload_progress_ack_(false), | 208 waiting_for_upload_progress_ack_(false), |
| 209 reported_transfer_size_(0) { | 209 reported_transfer_size_(0) { |
| 210 DCHECK(GetRequestInfo()->requester_info()->IsRenderer()); |
| 210 InitializeResourceBufferConstants(); | 211 InitializeResourceBufferConstants(); |
| 211 } | 212 } |
| 212 | 213 |
| 213 AsyncResourceHandler::~AsyncResourceHandler() { | 214 AsyncResourceHandler::~AsyncResourceHandler() { |
| 214 if (has_checked_for_sufficient_resources_) | 215 if (has_checked_for_sufficient_resources_) |
| 215 rdh_->FinishedWithResourcesForRequest(request()); | 216 rdh_->FinishedWithResourcesForRequest(request()); |
| 216 } | 217 } |
| 217 | 218 |
| 218 bool AsyncResourceHandler::OnMessageReceived(const IPC::Message& message) { | 219 bool AsyncResourceHandler::OnMessageReceived(const IPC::Message& message) { |
| 219 bool handled = true; | 220 bool handled = true; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 waiting_for_upload_progress_ack_ = true; | 284 waiting_for_upload_progress_ack_ = true; |
| 284 last_upload_ticks_ = TimeTicks::Now(); | 285 last_upload_ticks_ = TimeTicks::Now(); |
| 285 last_upload_position_ = progress.position(); | 286 last_upload_position_ = progress.position(); |
| 286 } | 287 } |
| 287 } | 288 } |
| 288 | 289 |
| 289 bool AsyncResourceHandler::OnRequestRedirected( | 290 bool AsyncResourceHandler::OnRequestRedirected( |
| 290 const net::RedirectInfo& redirect_info, | 291 const net::RedirectInfo& redirect_info, |
| 291 ResourceResponse* response, | 292 ResourceResponse* response, |
| 292 bool* defer) { | 293 bool* defer) { |
| 293 const ResourceRequestInfoImpl* info = GetRequestInfo(); | 294 ResourceMessageFilter* filter = GetFilter(); |
| 294 if (!info->filter()) | 295 if (!filter) |
| 295 return false; | 296 return false; |
| 296 | 297 |
| 297 *defer = did_defer_ = true; | 298 *defer = did_defer_ = true; |
| 298 OnDefer(); | 299 OnDefer(); |
| 299 | 300 |
| 300 NetLogObserver::PopulateResponseInfo(request(), response); | 301 NetLogObserver::PopulateResponseInfo(request(), response); |
| 301 response->head.encoded_data_length = request()->GetTotalReceivedBytes(); | 302 response->head.encoded_data_length = request()->GetTotalReceivedBytes(); |
| 302 reported_transfer_size_ = 0; | 303 reported_transfer_size_ = 0; |
| 303 response->head.request_start = request()->creation_time(); | 304 response->head.request_start = request()->creation_time(); |
| 304 response->head.response_start = TimeTicks::Now(); | 305 response->head.response_start = TimeTicks::Now(); |
| 305 // TODO(davidben): Is it necessary to pass the new first party URL for | 306 // TODO(davidben): Is it necessary to pass the new first party URL for |
| 306 // cookies? The only case where it can change is top-level navigation requests | 307 // cookies? The only case where it can change is top-level navigation requests |
| 307 // and hopefully those will eventually all be owned by the browser. It's | 308 // and hopefully those will eventually all be owned by the browser. It's |
| 308 // possible this is still needed while renderer-owned ones exist. | 309 // possible this is still needed while renderer-owned ones exist. |
| 309 return info->filter()->Send(new ResourceMsg_ReceivedRedirect( | 310 return filter->Send(new ResourceMsg_ReceivedRedirect( |
| 310 GetRequestID(), redirect_info, response->head)); | 311 GetRequestID(), redirect_info, response->head)); |
| 311 } | 312 } |
| 312 | 313 |
| 313 bool AsyncResourceHandler::OnResponseStarted(ResourceResponse* response, | 314 bool AsyncResourceHandler::OnResponseStarted(ResourceResponse* response, |
| 314 bool* defer) { | 315 bool* defer) { |
| 315 // For changes to the main frame, inform the renderer of the new URL's | 316 // For changes to the main frame, inform the renderer of the new URL's |
| 316 // per-host settings before the request actually commits. This way the | 317 // per-host settings before the request actually commits. This way the |
| 317 // renderer will be able to set these precisely at the time the | 318 // renderer will be able to set these precisely at the time the |
| 318 // request commits, avoiding the possibility of e.g. zooming the old content | 319 // request commits, avoiding the possibility of e.g. zooming the old content |
| 319 // or of having to layout the new content twice. | 320 // or of having to layout the new content twice. |
| 320 | 321 |
| 321 response_started_ticks_ = base::TimeTicks::Now(); | 322 response_started_ticks_ = base::TimeTicks::Now(); |
| 322 | 323 |
| 323 progress_timer_.Stop(); | 324 progress_timer_.Stop(); |
| 324 const ResourceRequestInfoImpl* info = GetRequestInfo(); | 325 ResourceMessageFilter* filter = GetFilter(); |
| 325 if (!info->filter()) | 326 if (!filter) |
| 326 return false; | 327 return false; |
| 327 | 328 |
| 329 const ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 328 // We want to send a final upload progress message prior to sending the | 330 // We want to send a final upload progress message prior to sending the |
| 329 // response complete message even if we're waiting for an ack to to a | 331 // response complete message even if we're waiting for an ack to to a |
| 330 // previous upload progress message. | 332 // previous upload progress message. |
| 331 if (info->is_upload_progress_enabled()) { | 333 if (info->is_upload_progress_enabled()) { |
| 332 waiting_for_upload_progress_ack_ = false; | 334 waiting_for_upload_progress_ack_ = false; |
| 333 ReportUploadProgress(); | 335 ReportUploadProgress(); |
| 334 } | 336 } |
| 335 | 337 |
| 336 if (rdh_->delegate()) { | 338 if (rdh_->delegate()) { |
| 337 rdh_->delegate()->OnResponseStarted(request(), info->GetContext(), | 339 rdh_->delegate()->OnResponseStarted(request(), info->GetContext(), |
| 338 response); | 340 response); |
| 339 } | 341 } |
| 340 | 342 |
| 341 NetLogObserver::PopulateResponseInfo(request(), response); | 343 NetLogObserver::PopulateResponseInfo(request(), response); |
| 342 response->head.encoded_data_length = request()->raw_header_size(); | 344 response->head.encoded_data_length = request()->raw_header_size(); |
| 343 | 345 |
| 344 // If the parent handler downloaded the resource to a file, grant the child | 346 // If the parent handler downloaded the resource to a file, grant the child |
| 345 // read permissions on it. | 347 // read permissions on it. |
| 346 if (!response->head.download_file_path.empty()) { | 348 if (!response->head.download_file_path.empty()) { |
| 347 rdh_->RegisterDownloadedTempFile( | 349 rdh_->RegisterDownloadedTempFile( |
| 348 info->GetChildID(), info->GetRequestID(), | 350 info->GetChildID(), info->GetRequestID(), |
| 349 response->head.download_file_path); | 351 response->head.download_file_path); |
| 350 } | 352 } |
| 351 | 353 |
| 352 response->head.request_start = request()->creation_time(); | 354 response->head.request_start = request()->creation_time(); |
| 353 response->head.response_start = TimeTicks::Now(); | 355 response->head.response_start = TimeTicks::Now(); |
| 354 info->filter()->Send(new ResourceMsg_ReceivedResponse(GetRequestID(), | 356 filter->Send( |
| 355 response->head)); | 357 new ResourceMsg_ReceivedResponse(GetRequestID(), response->head)); |
| 356 sent_received_response_msg_ = true; | 358 sent_received_response_msg_ = true; |
| 357 | 359 |
| 358 if (request()->response_info().metadata.get()) { | 360 if (request()->response_info().metadata.get()) { |
| 359 std::vector<char> copy(request()->response_info().metadata->data(), | 361 std::vector<char> copy(request()->response_info().metadata->data(), |
| 360 request()->response_info().metadata->data() + | 362 request()->response_info().metadata->data() + |
| 361 request()->response_info().metadata->size()); | 363 request()->response_info().metadata->size()); |
| 362 info->filter()->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), | 364 filter->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), copy)); |
| 363 copy)); | |
| 364 } | 365 } |
| 365 | 366 |
| 366 inlining_helper_->OnResponseReceived(*response); | 367 inlining_helper_->OnResponseReceived(*response); |
| 367 return true; | 368 return true; |
| 368 } | 369 } |
| 369 | 370 |
| 370 bool AsyncResourceHandler::OnWillStart(const GURL& url, bool* defer) { | 371 bool AsyncResourceHandler::OnWillStart(const GURL& url, bool* defer) { |
| 371 if (GetRequestInfo()->is_upload_progress_enabled() && | 372 if (GetRequestInfo()->is_upload_progress_enabled() && |
| 372 request()->has_upload()) { | 373 request()->has_upload()) { |
| 373 ReportUploadProgress(); | 374 ReportUploadProgress(); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 ResourceMessageFilter* filter = GetFilter(); | 462 ResourceMessageFilter* filter = GetFilter(); |
| 462 if (filter) { | 463 if (filter) { |
| 463 filter->Send(new ResourceMsg_DataDownloaded( | 464 filter->Send(new ResourceMsg_DataDownloaded( |
| 464 GetRequestID(), bytes_downloaded, encoded_data_length)); | 465 GetRequestID(), bytes_downloaded, encoded_data_length)); |
| 465 } | 466 } |
| 466 } | 467 } |
| 467 | 468 |
| 468 void AsyncResourceHandler::OnResponseCompleted( | 469 void AsyncResourceHandler::OnResponseCompleted( |
| 469 const net::URLRequestStatus& status, | 470 const net::URLRequestStatus& status, |
| 470 bool* defer) { | 471 bool* defer) { |
| 471 const ResourceRequestInfoImpl* info = GetRequestInfo(); | 472 ResourceMessageFilter* filter = GetFilter(); |
| 472 if (!info->filter()) | 473 if (!filter) |
| 473 return; | 474 return; |
| 474 | 475 |
| 475 // If we crash here, figure out what URL the renderer was requesting. | 476 // If we crash here, figure out what URL the renderer was requesting. |
| 476 // http://crbug.com/107692 | 477 // http://crbug.com/107692 |
| 477 char url_buf[128]; | 478 char url_buf[128]; |
| 478 base::strlcpy(url_buf, request()->url().spec().c_str(), arraysize(url_buf)); | 479 base::strlcpy(url_buf, request()->url().spec().c_str(), arraysize(url_buf)); |
| 479 base::debug::Alias(url_buf); | 480 base::debug::Alias(url_buf); |
| 480 | 481 |
| 481 // TODO(gavinp): Remove this CHECK when we figure out the cause of | 482 // TODO(gavinp): Remove this CHECK when we figure out the cause of |
| 482 // http://crbug.com/124680 . This check mirrors closely check in | 483 // http://crbug.com/124680 . This check mirrors closely check in |
| 483 // WebURLLoaderImpl::OnCompletedRequest that routes this message to a WebCore | 484 // WebURLLoaderImpl::OnCompletedRequest that routes this message to a WebCore |
| 484 // ResourceHandleInternal which asserts on its state and crashes. By crashing | 485 // ResourceHandleInternal which asserts on its state and crashes. By crashing |
| 485 // when the message is sent, we should get better crash reports. | 486 // when the message is sent, we should get better crash reports. |
| 486 CHECK(status.status() != net::URLRequestStatus::SUCCESS || | 487 CHECK(status.status() != net::URLRequestStatus::SUCCESS || |
| 487 sent_received_response_msg_); | 488 sent_received_response_msg_); |
| 488 | 489 |
| 489 int error_code = status.error(); | 490 int error_code = status.error(); |
| 491 const ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 490 bool was_ignored_by_handler = info->WasIgnoredByHandler(); | 492 bool was_ignored_by_handler = info->WasIgnoredByHandler(); |
| 491 | 493 |
| 492 DCHECK(status.status() != net::URLRequestStatus::IO_PENDING); | 494 DCHECK(status.status() != net::URLRequestStatus::IO_PENDING); |
| 493 // If this check fails, then we're in an inconsistent state because all | 495 // If this check fails, then we're in an inconsistent state because all |
| 494 // requests ignored by the handler should be canceled (which should result in | 496 // requests ignored by the handler should be canceled (which should result in |
| 495 // the ERR_ABORTED error code). | 497 // the ERR_ABORTED error code). |
| 496 DCHECK(!was_ignored_by_handler || error_code == net::ERR_ABORTED); | 498 DCHECK(!was_ignored_by_handler || error_code == net::ERR_ABORTED); |
| 497 | 499 |
| 498 ResourceRequestCompletionStatus request_complete_data; | 500 ResourceRequestCompletionStatus request_complete_data; |
| 499 request_complete_data.error_code = error_code; | 501 request_complete_data.error_code = error_code; |
| 500 request_complete_data.was_ignored_by_handler = was_ignored_by_handler; | 502 request_complete_data.was_ignored_by_handler = was_ignored_by_handler; |
| 501 request_complete_data.exists_in_cache = request()->response_info().was_cached; | 503 request_complete_data.exists_in_cache = request()->response_info().was_cached; |
| 502 request_complete_data.completion_time = TimeTicks::Now(); | 504 request_complete_data.completion_time = TimeTicks::Now(); |
| 503 request_complete_data.encoded_data_length = | 505 request_complete_data.encoded_data_length = |
| 504 request()->GetTotalReceivedBytes(); | 506 request()->GetTotalReceivedBytes(); |
| 505 request_complete_data.encoded_body_length = request()->GetRawBodyBytes(); | 507 request_complete_data.encoded_body_length = request()->GetRawBodyBytes(); |
| 506 info->filter()->Send( | 508 filter->Send( |
| 507 new ResourceMsg_RequestComplete(GetRequestID(), request_complete_data)); | 509 new ResourceMsg_RequestComplete(GetRequestID(), request_complete_data)); |
| 508 | 510 |
| 509 if (status.is_success()) | 511 if (status.is_success()) |
| 510 RecordHistogram(); | 512 RecordHistogram(); |
| 511 } | 513 } |
| 512 | 514 |
| 513 bool AsyncResourceHandler::EnsureResourceBufferIsInitialized() { | 515 bool AsyncResourceHandler::EnsureResourceBufferIsInitialized() { |
| 514 DCHECK(has_checked_for_sufficient_resources_); | 516 DCHECK(has_checked_for_sufficient_resources_); |
| 515 | 517 |
| 516 if (buffer_.get() && buffer_->IsInitialized()) | 518 if (buffer_.get() && buffer_->IsInitialized()) |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 } else { | 575 } else { |
| 574 UMA_HISTOGRAM_CUSTOM_COUNTS( | 576 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 575 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", | 577 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", |
| 576 elapsed_time, 1, 100000, 100); | 578 elapsed_time, 1, 100000, 100); |
| 577 } | 579 } |
| 578 | 580 |
| 579 inlining_helper_->RecordHistogram(elapsed_time); | 581 inlining_helper_->RecordHistogram(elapsed_time); |
| 580 } | 582 } |
| 581 | 583 |
| 582 } // namespace content | 584 } // namespace content |
| OLD | NEW |