Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/child/url_loader_client_impl.h" | 5 #include "content/child/url_loader_client_impl.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/single_thread_task_runner.h" | 8 #include "base/single_thread_task_runner.h" |
| 9 #include "content/child/resource_dispatcher.h" | 9 #include "content/child/resource_dispatcher.h" |
| 10 #include "content/child/url_response_body_consumer.h" | 10 #include "content/child/url_response_body_consumer.h" |
| 11 #include "content/common/resource_messages.h" | 11 #include "content/common/resource_messages.h" |
| 12 #include "mojo/public/cpp/bindings/associated_group.h" | 12 #include "mojo/public/cpp/bindings/associated_group.h" |
| 13 #include "net/url_request/redirect_info.h" | 13 #include "net/url_request/redirect_info.h" |
| 14 | 14 |
| 15 namespace content { | 15 namespace content { |
| 16 | 16 |
| 17 URLLoaderClientImpl::URLLoaderClientImpl( | 17 URLLoaderClientImpl::URLLoaderClientImpl( |
| 18 int request_id, | 18 int request_id, |
| 19 ResourceDispatcher* resource_dispatcher, | 19 ResourceDispatcher* resource_dispatcher, |
| 20 scoped_refptr<base::SingleThreadTaskRunner> task_runner) | 20 scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
| 21 : binding_(this), | 21 : binding_(this), |
| 22 request_id_(request_id), | 22 request_id_(request_id), |
| 23 resource_dispatcher_(resource_dispatcher), | 23 resource_dispatcher_(resource_dispatcher), |
| 24 is_destroyed_(new base::RefCountedData<bool>(false)), | |
| 24 task_runner_(std::move(task_runner)) {} | 25 task_runner_(std::move(task_runner)) {} |
| 25 | 26 |
| 26 URLLoaderClientImpl::~URLLoaderClientImpl() { | 27 URLLoaderClientImpl::~URLLoaderClientImpl() { |
| 27 if (body_consumer_) | 28 if (body_consumer_) |
| 28 body_consumer_->Cancel(); | 29 body_consumer_->Cancel(); |
| 30 is_destroyed_->data = true; | |
| 29 } | 31 } |
| 30 | 32 |
| 31 void URLLoaderClientImpl::Bind( | 33 void URLLoaderClientImpl::Bind( |
| 32 mojom::URLLoaderClientAssociatedPtrInfo* client_ptr_info, | 34 mojom::URLLoaderClientAssociatedPtrInfo* client_ptr_info, |
| 33 mojo::AssociatedGroup* associated_group) { | 35 mojo::AssociatedGroup* associated_group) { |
| 34 binding_.Bind(client_ptr_info, associated_group); | 36 binding_.Bind(client_ptr_info, associated_group); |
| 35 } | 37 } |
| 36 | 38 |
| 39 void URLLoaderClientImpl::SetDefersLoading() { | |
| 40 is_deferred_ = true; | |
| 41 if (body_consumer_) | |
| 42 body_consumer_->SetDefersLoading(); | |
| 43 } | |
| 44 | |
| 45 void URLLoaderClientImpl::UnsetDefersLoading() { | |
| 46 is_deferred_ = false; | |
| 47 } | |
| 48 | |
| 49 void URLLoaderClientImpl::FlushDeferredMessages() { | |
| 50 DCHECK(!is_deferred_); | |
| 51 std::vector<IPC::Message> messages; | |
| 52 messages.swap(deferred_messages_); | |
| 53 bool has_completion_message = false; | |
| 54 scoped_refptr<base::RefCountedData<bool>> is_destroyed = is_destroyed_; | |
| 55 size_t index = 0; | |
| 56 // First, dispatch all messages excluding the followings: | |
| 57 // - response body (dispatched by |body_consumer_|) | |
| 58 // - transfer size change (dispatched later) | |
| 59 // - completion (dispatched by |body_consumer_| or dispatched later) | |
| 60 for (index = 0; index < messages.size(); ++index) { | |
| 61 if (messages[index].type() == ResourceMsg_RequestComplete::ID) { | |
| 62 // The completion message arrives at the end of the message queue. | |
| 63 DCHECK(!has_completion_message); | |
| 64 DCHECK_EQ(index, messages.size() - 1); | |
| 65 has_completion_message = true; | |
| 66 } else { | |
| 67 Dispatch(messages[index]); | |
| 68 } | |
| 69 if (is_destroyed->data) | |
|
kinuko
2016/12/23 13:11:23
Looking into the usage, I think using WeakPtr is p
yhirano
2016/12/26 05:08:35
Done.
| |
| 70 return; | |
| 71 if (is_deferred_) { | |
| 72 deferred_messages_.insert(deferred_messages_.begin(), | |
| 73 messages.begin() + index + 1, messages.end()); | |
| 74 return; | |
| 75 } | |
| 76 } | |
| 77 | |
| 78 // Dispatch the transfer size update. | |
| 79 if (accumulated_transfer_size_diff_during_deferred_ > 0) { | |
| 80 auto transfer_size_diff = accumulated_transfer_size_diff_during_deferred_; | |
| 81 accumulated_transfer_size_diff_during_deferred_ = 0; | |
| 82 resource_dispatcher_->OnTransferSizeUpdated(request_id_, | |
| 83 transfer_size_diff); | |
| 84 if (is_destroyed->data) | |
| 85 return; | |
| 86 if (is_deferred_) { | |
| 87 deferred_messages_.insert(deferred_messages_.begin(), | |
| 88 messages.begin() + index, messages.end()); | |
|
kinuko
2016/12/23 13:11:23
I'm a little confused, we don't break the for loop
yhirano
2016/12/26 05:08:35
Oops, sorry. Fixed.
kinuko
2016/12/26 07:21:17
Thanks. Should we have a test that must have caugh
yhirano
2016/12/26 08:22:00
Done.
| |
| 89 return; | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 if (body_consumer_) { | |
| 94 // Dispatch the response body. | |
| 95 body_consumer_->UnsetDefersLoading(); | |
| 96 if (is_destroyed->data) | |
| 97 return; | |
| 98 if (is_deferred_) { | |
| 99 deferred_messages_.insert(deferred_messages_.begin(), | |
| 100 messages.begin() + index, messages.end()); | |
| 101 return; | |
| 102 } | |
| 103 } | |
| 104 | |
| 105 // Dispatch the completion message. | |
| 106 if (has_completion_message) { | |
| 107 DCHECK_GT(messages.size(), 0u); | |
| 108 DCHECK_EQ(messages.back().type(), | |
| 109 static_cast<uint32_t>(ResourceMsg_RequestComplete::ID)); | |
| 110 Dispatch(messages.back()); | |
| 111 } | |
| 112 } | |
| 113 | |
| 37 void URLLoaderClientImpl::OnReceiveResponse( | 114 void URLLoaderClientImpl::OnReceiveResponse( |
| 38 const ResourceResponseHead& response_head, | 115 const ResourceResponseHead& response_head, |
| 39 mojom::DownloadedTempFilePtr downloaded_file) { | 116 mojom::DownloadedTempFilePtr downloaded_file) { |
| 40 has_received_response_ = true; | 117 has_received_response_ = true; |
| 41 if (body_consumer_) | 118 if (body_consumer_) |
| 42 body_consumer_->Start(); | 119 body_consumer_->Start(); |
| 43 downloaded_file_ = std::move(downloaded_file); | 120 downloaded_file_ = std::move(downloaded_file); |
| 44 Dispatch(ResourceMsg_ReceivedResponse(request_id_, response_head)); | 121 Dispatch(ResourceMsg_ReceivedResponse(request_id_, response_head)); |
| 45 } | 122 } |
| 46 | 123 |
| 47 void URLLoaderClientImpl::OnReceiveRedirect( | 124 void URLLoaderClientImpl::OnReceiveRedirect( |
| 48 const net::RedirectInfo& redirect_info, | 125 const net::RedirectInfo& redirect_info, |
| 49 const ResourceResponseHead& response_head) { | 126 const ResourceResponseHead& response_head) { |
| 50 DCHECK(!has_received_response_); | 127 DCHECK(!has_received_response_); |
| 51 DCHECK(!body_consumer_); | 128 DCHECK(!body_consumer_); |
| 52 Dispatch( | 129 Dispatch( |
| 53 ResourceMsg_ReceivedRedirect(request_id_, redirect_info, response_head)); | 130 ResourceMsg_ReceivedRedirect(request_id_, redirect_info, response_head)); |
| 54 } | 131 } |
| 55 | 132 |
| 56 void URLLoaderClientImpl::OnDataDownloaded(int64_t data_len, | 133 void URLLoaderClientImpl::OnDataDownloaded(int64_t data_len, |
| 57 int64_t encoded_data_len) { | 134 int64_t encoded_data_len) { |
| 58 Dispatch(ResourceMsg_DataDownloaded(request_id_, data_len, encoded_data_len)); | 135 Dispatch(ResourceMsg_DataDownloaded(request_id_, data_len, encoded_data_len)); |
| 59 } | 136 } |
| 60 | 137 |
| 61 void URLLoaderClientImpl::OnTransferSizeUpdated(int32_t transfer_size_diff) { | 138 void URLLoaderClientImpl::OnTransferSizeUpdated(int32_t transfer_size_diff) { |
| 62 resource_dispatcher_->OnTransferSizeUpdated(request_id_, | 139 if (is_deferred_) { |
| 63 transfer_size_diff); | 140 accumulated_transfer_size_diff_during_deferred_ += transfer_size_diff; |
| 141 } else { | |
| 142 resource_dispatcher_->OnTransferSizeUpdated(request_id_, | |
| 143 transfer_size_diff); | |
| 144 } | |
| 64 } | 145 } |
| 65 | 146 |
| 66 void URLLoaderClientImpl::OnStartLoadingResponseBody( | 147 void URLLoaderClientImpl::OnStartLoadingResponseBody( |
| 67 mojo::ScopedDataPipeConsumerHandle body) { | 148 mojo::ScopedDataPipeConsumerHandle body) { |
| 68 DCHECK(!body_consumer_); | 149 DCHECK(!body_consumer_); |
| 69 body_consumer_ = new URLResponseBodyConsumer( | 150 body_consumer_ = new URLResponseBodyConsumer( |
| 70 request_id_, resource_dispatcher_, std::move(body), task_runner_); | 151 request_id_, resource_dispatcher_, std::move(body), task_runner_); |
| 71 if (has_received_response_) | 152 if (has_received_response_) |
| 72 body_consumer_->Start(); | 153 body_consumer_->Start(); |
| 154 if (is_deferred_) | |
| 155 body_consumer_->SetDefersLoading(); | |
| 73 } | 156 } |
| 74 | 157 |
| 75 void URLLoaderClientImpl::OnComplete( | 158 void URLLoaderClientImpl::OnComplete( |
| 76 const ResourceRequestCompletionStatus& status) { | 159 const ResourceRequestCompletionStatus& status) { |
| 77 if (!body_consumer_) { | 160 if (!body_consumer_) { |
| 78 Dispatch(ResourceMsg_RequestComplete(request_id_, status)); | 161 Dispatch(ResourceMsg_RequestComplete(request_id_, status)); |
| 79 return; | 162 return; |
| 80 } | 163 } |
| 81 body_consumer_->OnComplete(status); | 164 body_consumer_->OnComplete(status); |
| 82 } | 165 } |
| 83 | 166 |
| 84 void URLLoaderClientImpl::Dispatch(const IPC::Message& message) { | 167 void URLLoaderClientImpl::Dispatch(const IPC::Message& message) { |
| 85 resource_dispatcher_->OnMessageReceived(message); | 168 if (is_deferred_) { |
| 169 deferred_messages_.push_back(message); | |
| 170 } else if (deferred_messages_.size() > 0) { | |
| 171 deferred_messages_.push_back(message); | |
| 172 FlushDeferredMessages(); | |
| 173 } else { | |
| 174 resource_dispatcher_->OnMessageReceived(message); | |
|
kinuko
2016/12/23 13:11:23
At this point couldn't we directly call ResourceDi
yhirano
2016/12/26 05:08:35
ResourceDispatcher::DispatchMessage is a private m
kinuko
2016/12/26 07:21:17
But eventually we plan to get rid of OnMessageRece
yhirano
2016/12/26 08:22:00
Done.
| |
| 175 } | |
| 86 } | 176 } |
| 87 | 177 |
| 88 } // namespace content | 178 } // namespace content |
| OLD | NEW |