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 11 matching lines...) Expand all Loading... | |
| 22 #include "content/browser/loader/resource_dispatcher_host_impl.h" | 22 #include "content/browser/loader/resource_dispatcher_host_impl.h" |
| 23 #include "content/browser/loader/resource_message_filter.h" | 23 #include "content/browser/loader/resource_message_filter.h" |
| 24 #include "content/browser/loader/resource_request_info_impl.h" | 24 #include "content/browser/loader/resource_request_info_impl.h" |
| 25 #include "content/browser/resource_context_impl.h" | 25 #include "content/browser/resource_context_impl.h" |
| 26 #include "content/common/resource_messages.h" | 26 #include "content/common/resource_messages.h" |
| 27 #include "content/common/resource_request_completion_status.h" | 27 #include "content/common/resource_request_completion_status.h" |
| 28 #include "content/common/view_messages.h" | 28 #include "content/common/view_messages.h" |
| 29 #include "content/public/browser/resource_dispatcher_host_delegate.h" | 29 #include "content/public/browser/resource_dispatcher_host_delegate.h" |
| 30 #include "content/public/common/content_features.h" | 30 #include "content/public/common/content_features.h" |
| 31 #include "content/public/common/resource_response.h" | 31 #include "content/public/common/resource_response.h" |
| 32 #include "mojo/message_pump/handle_watcher.h" | |
| 33 #include "mojo/public/cpp/system/data_pipe.h" | |
| 32 #include "net/base/io_buffer.h" | 34 #include "net/base/io_buffer.h" |
| 33 #include "net/base/load_flags.h" | 35 #include "net/base/load_flags.h" |
| 34 #include "net/log/net_log.h" | 36 #include "net/log/net_log.h" |
| 35 #include "net/url_request/redirect_info.h" | 37 #include "net/url_request/redirect_info.h" |
| 36 | 38 |
| 37 using base::TimeDelta; | 39 using base::TimeDelta; |
| 38 using base::TimeTicks; | 40 using base::TimeTicks; |
| 39 | 41 |
| 40 namespace content { | 42 namespace content { |
| 41 namespace { | 43 namespace { |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 184 public: | 186 public: |
| 185 DependentIOBuffer(ResourceBuffer* backing, char* memory) | 187 DependentIOBuffer(ResourceBuffer* backing, char* memory) |
| 186 : net::WrappedIOBuffer(memory), | 188 : net::WrappedIOBuffer(memory), |
| 187 backing_(backing) { | 189 backing_(backing) { |
| 188 } | 190 } |
| 189 private: | 191 private: |
| 190 ~DependentIOBuffer() override {} | 192 ~DependentIOBuffer() override {} |
| 191 scoped_refptr<ResourceBuffer> backing_; | 193 scoped_refptr<ResourceBuffer> backing_; |
| 192 }; | 194 }; |
| 193 | 195 |
| 194 AsyncResourceHandler::AsyncResourceHandler( | 196 // This class is used when the resource is being loaded via mojo. This class |
| 195 net::URLRequest* request, | 197 // uses mojo data pipe instead of shared memory transferred via ChromeIPC. |
| 196 ResourceDispatcherHostImpl* rdh) | 198 class AsyncResourceHandler::MojoHelper final { |
|
mmenke
2016/05/24 20:01:35
Long term, is the plan to merge this into AsyncRes
yhirano
2016/05/25 12:47:05
Yes, our plan is replacing ChromeIPC with mojo.
| |
| 199 public: | |
| 200 explicit MojoHelper(AsyncResourceHandler* owner) : owner_(owner) {} | |
| 201 // Called from AsyncResourceHandler::OnWillRead. | |
| 202 bool OnWillRead(scoped_refptr<net::IOBuffer>* buf, | |
| 203 int* buf_size, | |
| 204 int min_size) { | |
| 205 void* buffer = nullptr; | |
| 206 uint32_t available = 0; | |
| 207 if (!writer_.is_valid()) { | |
| 208 MojoCreateDataPipeOptions options; | |
| 209 options.struct_size = sizeof(MojoCreateDataPipeOptions); | |
| 210 options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; | |
| 211 options.element_num_bytes = 1; | |
| 212 options.capacity_num_bytes = kMaxAllocationSize; | |
| 213 mojo::DataPipe data_pipe(options); | |
| 214 | |
| 215 writer_ = std::move(data_pipe.producer_handle); | |
| 216 ResourceMessageFilter* filter = owner_->GetRequestInfo()->filter(); | |
| 217 if (filter) { | |
| 218 filter->OnStartLoadingResponseBodyWithMojo( | |
| 219 owner_->GetRequestInfo()->GetGlobalRequestID(), | |
| 220 std::move(data_pipe.consumer_handle)); | |
| 221 } | |
| 222 } | |
| 223 if (!writer_.is_valid()) { | |
| 224 owner_->controller()->CancelWithError(net::ERR_FAILED); | |
| 225 return false; | |
| 226 } | |
| 227 | |
| 228 MojoResult result = mojo::BeginWriteDataRaw( | |
| 229 writer_.get(), &buffer, &available, MOJO_WRITE_DATA_FLAG_NONE); | |
| 230 // Note that SHOULD_WAIT should be handled in OnReadCompleted. | |
| 231 if (result == MOJO_RESULT_OK) { | |
| 232 *buf = new net::WrappedIOBuffer(static_cast<const char*>(buffer)); | |
| 233 *buf_size = available; | |
| 234 return true; | |
| 235 } | |
| 236 return false; | |
|
mmenke
2016/05/24 20:01:35
This case is currently a fatal error?
yhirano
2016/05/25 12:47:05
Done.
| |
| 237 } | |
| 238 | |
| 239 // Called from AsyncResourceHandler::OnReadCompleted. | |
| 240 bool OnReadCompleted(int bytes_read, bool* defer) { | |
| 241 MojoResult result = mojo::EndWriteDataRaw(writer_.get(), bytes_read); | |
| 242 if (result != MOJO_RESULT_OK) | |
| 243 return false; | |
| 244 void* buffer = nullptr; | |
| 245 uint32_t available = 0; | |
| 246 // To see if the handle is still writable. | |
| 247 result = mojo::BeginWriteDataRaw(writer_.get(), &buffer, &available, | |
| 248 MOJO_WRITE_DATA_FLAG_NONE); | |
| 249 if (result == MOJO_RESULT_SHOULD_WAIT || | |
| 250 (result == MOJO_RESULT_OK && available == 0)) { | |
| 251 *defer = owner_->did_defer_ = true; | |
| 252 owner_->OnDefer(); | |
| 253 handle_watcher_.Start( | |
| 254 writer_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE, | |
| 255 base::Bind(&MojoHelper::OnWritable, base::Unretained(this))); | |
| 256 } | |
| 257 if (result == MOJO_RESULT_OK) | |
| 258 mojo::EndWriteDataRaw(writer_.get(), 0); | |
| 259 return true; | |
| 260 } | |
| 261 | |
| 262 private: | |
| 263 void OnWritable(MojoResult result) { owner_->ResumeIfDeferred(); } | |
| 264 | |
| 265 mojo::ScopedDataPipeProducerHandle writer_; | |
| 266 mojo::common::HandleWatcher handle_watcher_; | |
| 267 AsyncResourceHandler* owner_; | |
| 268 | |
| 269 DISALLOW_COPY_AND_ASSIGN(MojoHelper); | |
| 270 }; | |
| 271 | |
| 272 AsyncResourceHandler::AsyncResourceHandler(net::URLRequest* request, | |
| 273 ResourceDispatcherHostImpl* rdh, | |
| 274 bool using_mojo_data_handle) | |
| 197 : ResourceHandler(request), | 275 : ResourceHandler(request), |
| 198 ResourceMessageDelegate(request), | 276 ResourceMessageDelegate(request), |
| 199 rdh_(rdh), | 277 rdh_(rdh), |
| 200 pending_data_count_(0), | 278 pending_data_count_(0), |
| 201 allocation_size_(0), | 279 allocation_size_(0), |
| 202 did_defer_(false), | 280 did_defer_(false), |
| 203 has_checked_for_sufficient_resources_(false), | 281 has_checked_for_sufficient_resources_(false), |
| 204 sent_received_response_msg_(false), | 282 sent_received_response_msg_(false), |
| 205 sent_data_buffer_msg_(false), | 283 sent_data_buffer_msg_(false), |
| 206 inlining_helper_(new InliningHelper), | 284 inlining_helper_(new InliningHelper), |
| 207 last_upload_position_(0), | 285 last_upload_position_(0), |
| 208 waiting_for_upload_progress_ack_(false), | 286 waiting_for_upload_progress_ack_(false), |
| 209 reported_transfer_size_(0) { | 287 reported_transfer_size_(0), |
| 288 mojo_helper_(using_mojo_data_handle ? new MojoHelper(this) : nullptr) { | |
| 210 InitializeResourceBufferConstants(); | 289 InitializeResourceBufferConstants(); |
| 211 } | 290 } |
| 212 | 291 |
| 213 AsyncResourceHandler::~AsyncResourceHandler() { | 292 AsyncResourceHandler::~AsyncResourceHandler() { |
| 214 if (has_checked_for_sufficient_resources_) | 293 if (has_checked_for_sufficient_resources_) |
| 215 rdh_->FinishedWithResourcesForRequest(request()); | 294 rdh_->FinishedWithResourcesForRequest(request()); |
| 216 } | 295 } |
| 217 | 296 |
| 218 bool AsyncResourceHandler::OnMessageReceived(const IPC::Message& message) { | 297 bool AsyncResourceHandler::OnMessageReceived(const IPC::Message& message) { |
| 219 bool handled = true; | 298 bool handled = true; |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 389 } | 468 } |
| 390 | 469 |
| 391 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, | 470 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
| 392 int* buf_size, | 471 int* buf_size, |
| 393 int min_size) { | 472 int min_size) { |
| 394 DCHECK_EQ(-1, min_size); | 473 DCHECK_EQ(-1, min_size); |
| 395 | 474 |
| 396 if (!CheckForSufficientResource()) | 475 if (!CheckForSufficientResource()) |
| 397 return false; | 476 return false; |
| 398 | 477 |
| 478 if (mojo_helper_) | |
| 479 return mojo_helper_->OnWillRead(buf, buf_size, min_size); | |
| 480 | |
| 399 // Return early if InliningHelper allocates the buffer, so that we should | 481 // Return early if InliningHelper allocates the buffer, so that we should |
| 400 // inline the data into the IPC message without allocating SharedMemory. | 482 // inline the data into the IPC message without allocating SharedMemory. |
| 401 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) | 483 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) |
| 402 return true; | 484 return true; |
| 403 | 485 |
| 404 if (!EnsureResourceBufferIsInitialized()) | 486 if (!EnsureResourceBufferIsInitialized()) |
| 405 return false; | 487 return false; |
| 406 | 488 |
| 407 DCHECK(buffer_->CanAllocate()); | 489 DCHECK(buffer_->CanAllocate()); |
| 408 char* memory = buffer_->Allocate(&allocation_size_); | 490 char* memory = buffer_->Allocate(&allocation_size_); |
| 409 CHECK(memory); | 491 CHECK(memory); |
| 410 | 492 |
| 411 *buf = new DependentIOBuffer(buffer_.get(), memory); | 493 *buf = new DependentIOBuffer(buffer_.get(), memory); |
| 412 *buf_size = allocation_size_; | 494 *buf_size = allocation_size_; |
| 413 | 495 |
| 414 return true; | 496 return true; |
| 415 } | 497 } |
| 416 | 498 |
| 417 bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { | 499 bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { |
| 418 DCHECK_GE(bytes_read, 0); | 500 DCHECK_GE(bytes_read, 0); |
| 419 | 501 |
| 420 if (!bytes_read) | 502 if (!bytes_read) |
| 421 return true; | 503 return true; |
| 422 | 504 |
| 505 if (mojo_helper_) | |
| 506 return mojo_helper_->OnReadCompleted(bytes_read, defer); | |
| 507 | |
| 423 ResourceMessageFilter* filter = GetFilter(); | 508 ResourceMessageFilter* filter = GetFilter(); |
| 424 if (!filter) | 509 if (!filter) |
| 425 return false; | 510 return false; |
| 426 | 511 |
| 427 int encoded_data_length = CalculateEncodedDataLengthToReport(); | 512 int encoded_data_length = CalculateEncodedDataLengthToReport(); |
| 428 | 513 |
| 429 // Return early if InliningHelper handled the received data. | 514 // Return early if InliningHelper handled the received data. |
| 430 if (inlining_helper_->SendInlinedDataIfApplicable( | 515 if (inlining_helper_->SendInlinedDataIfApplicable( |
| 431 bytes_read, encoded_data_length, filter, GetRequestID())) | 516 bytes_read, encoded_data_length, filter, GetRequestID())) |
| 432 return true; | 517 return true; |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 461 void AsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) { | 546 void AsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) { |
| 462 int encoded_data_length = CalculateEncodedDataLengthToReport(); | 547 int encoded_data_length = CalculateEncodedDataLengthToReport(); |
| 463 | 548 |
| 464 ResourceMessageFilter* filter = GetFilter(); | 549 ResourceMessageFilter* filter = GetFilter(); |
| 465 if (filter) { | 550 if (filter) { |
| 466 filter->Send(new ResourceMsg_DataDownloaded( | 551 filter->Send(new ResourceMsg_DataDownloaded( |
| 467 GetRequestID(), bytes_downloaded, encoded_data_length)); | 552 GetRequestID(), bytes_downloaded, encoded_data_length)); |
| 468 } | 553 } |
| 469 } | 554 } |
| 470 | 555 |
| 471 void AsyncResourceHandler::OnResponseCompleted( | 556 void AsyncResourceHandler::OnResponseCompleted( |
|
mmenke
2016/05/24 20:01:35
There's no mojo response completed successfully or
yhirano
2016/05/25 12:47:05
There is. In PS25, ResourceMessageFilter traps IPC
| |
| 472 const net::URLRequestStatus& status, | 557 const net::URLRequestStatus& status, |
| 473 const std::string& security_info, | 558 const std::string& security_info, |
| 474 bool* defer) { | 559 bool* defer) { |
| 475 const ResourceRequestInfoImpl* info = GetRequestInfo(); | 560 const ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 476 if (!info->filter()) | 561 if (!info->filter()) |
| 477 return; | 562 return; |
| 478 | 563 |
| 479 // If we crash here, figure out what URL the renderer was requesting. | 564 // If we crash here, figure out what URL the renderer was requesting. |
| 480 // http://crbug.com/107692 | 565 // http://crbug.com/107692 |
| 481 char url_buf[128]; | 566 char url_buf[128]; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 587 } else { | 672 } else { |
| 588 UMA_HISTOGRAM_CUSTOM_COUNTS( | 673 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 589 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", | 674 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", |
| 590 elapsed_time, 1, 100000, 100); | 675 elapsed_time, 1, 100000, 100); |
| 591 } | 676 } |
| 592 | 677 |
| 593 inlining_helper_->RecordHistogram(elapsed_time); | 678 inlining_helper_->RecordHistogram(elapsed_time); |
| 594 } | 679 } |
| 595 | 680 |
| 596 } // namespace content | 681 } // namespace content |
| OLD | NEW |