| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/common/throttling_url_loader.h" | 5 #include "content/common/throttling_url_loader.h" |
| 6 | 6 |
| 7 #include "base/single_thread_task_runner.h" |
| 8 |
| 7 namespace content { | 9 namespace content { |
| 8 | 10 |
| 11 ThrottlingURLLoader::StartInfo::StartInfo( |
| 12 mojom::URLLoaderFactory* in_url_loader_factory, |
| 13 int32_t in_routing_id, |
| 14 int32_t in_request_id, |
| 15 uint32_t in_options, |
| 16 std::unique_ptr<ResourceRequest> in_url_request, |
| 17 scoped_refptr<base::SingleThreadTaskRunner> in_task_runner) |
| 18 : url_loader_factory(in_url_loader_factory), |
| 19 routing_id(in_routing_id), |
| 20 request_id(in_request_id), |
| 21 options(in_options), |
| 22 url_request(std::move(in_url_request)), |
| 23 task_runner(std::move(in_task_runner)) {} |
| 24 |
| 25 ThrottlingURLLoader::StartInfo::~StartInfo() = default; |
| 26 |
| 27 ThrottlingURLLoader::ResponseInfo::ResponseInfo( |
| 28 const ResourceResponseHead& in_response_head, |
| 29 const base::Optional<net::SSLInfo>& in_ssl_info, |
| 30 mojom::DownloadedTempFilePtr in_downloaded_file) |
| 31 : response_head(in_response_head), |
| 32 ssl_info(in_ssl_info), |
| 33 downloaded_file(std::move(in_downloaded_file)) {} |
| 34 |
| 35 ThrottlingURLLoader::ResponseInfo::~ResponseInfo() = default; |
| 36 |
| 37 ThrottlingURLLoader::RedirectInfo::RedirectInfo( |
| 38 const net::RedirectInfo& in_redirect_info, |
| 39 const ResourceResponseHead& in_response_head) |
| 40 : redirect_info(in_redirect_info), response_head(in_response_head) {} |
| 41 |
| 42 ThrottlingURLLoader::RedirectInfo::~RedirectInfo() = default; |
| 43 |
| 44 ThrottlingURLLoader::PriorityInfo::PriorityInfo( |
| 45 net::RequestPriority in_priority, |
| 46 int32_t in_intra_priority_value) |
| 47 : priority(in_priority), intra_priority_value(in_intra_priority_value) {} |
| 48 |
| 49 ThrottlingURLLoader::PriorityInfo::~PriorityInfo() = default; |
| 50 |
| 9 // static | 51 // static |
| 10 std::unique_ptr<ThrottlingURLLoader> ThrottlingURLLoader::CreateLoaderAndStart( | 52 std::unique_ptr<ThrottlingURLLoader> ThrottlingURLLoader::CreateLoaderAndStart( |
| 11 mojom::URLLoaderFactory* factory, | 53 mojom::URLLoaderFactory* factory, |
| 12 std::vector<std::unique_ptr<URLLoaderThrottle>> throttles, | 54 std::vector<std::unique_ptr<URLLoaderThrottle>> throttles, |
| 13 int32_t routing_id, | 55 int32_t routing_id, |
| 14 int32_t request_id, | 56 int32_t request_id, |
| 15 uint32_t options, | 57 uint32_t options, |
| 16 std::unique_ptr<ResourceRequest> url_request, | 58 std::unique_ptr<ResourceRequest> url_request, |
| 17 mojom::URLLoaderClient* client) { | 59 mojom::URLLoaderClient* client, |
| 60 scoped_refptr<base::SingleThreadTaskRunner> task_runner) { |
| 18 std::unique_ptr<ThrottlingURLLoader> loader( | 61 std::unique_ptr<ThrottlingURLLoader> loader( |
| 19 new ThrottlingURLLoader(std::move(throttles), client)); | 62 new ThrottlingURLLoader(std::move(throttles), client)); |
| 20 loader->Start(factory, routing_id, request_id, options, | 63 loader->Start(factory, routing_id, request_id, options, |
| 21 std::move(url_request)); | 64 std::move(url_request), std::move(task_runner)); |
| 22 return loader; | 65 return loader; |
| 23 } | 66 } |
| 24 | 67 |
| 25 ThrottlingURLLoader::~ThrottlingURLLoader() {} | 68 ThrottlingURLLoader::~ThrottlingURLLoader() {} |
| 26 | 69 |
| 27 void ThrottlingURLLoader::FollowRedirect() { | 70 void ThrottlingURLLoader::FollowRedirect() { |
| 28 if (url_loader_) | 71 if (url_loader_) |
| 29 url_loader_->FollowRedirect(); | 72 url_loader_->FollowRedirect(); |
| 30 } | 73 } |
| 31 | 74 |
| 32 void ThrottlingURLLoader::SetPriority(net::RequestPriority priority, | 75 void ThrottlingURLLoader::SetPriority(net::RequestPriority priority, |
| 33 int32_t intra_priority_value) { | 76 int32_t intra_priority_value) { |
| 34 if (!url_loader_ && !cancelled_by_throttle_) { | 77 if (!url_loader_ && !cancelled_by_throttle_) { |
| 35 DCHECK_EQ(DEFERRED_START, deferred_stage_); | 78 DCHECK_EQ(DEFERRED_START, deferred_stage_); |
| 36 set_priority_cached_ = true; | 79 priority_info_ = |
| 37 priority_ = priority; | 80 base::MakeUnique<PriorityInfo>(priority, intra_priority_value); |
| 38 intra_priority_value_ = intra_priority_value; | |
| 39 return; | 81 return; |
| 40 } | 82 } |
| 41 | 83 |
| 42 url_loader_->SetPriority(priority, intra_priority_value); | 84 url_loader_->SetPriority(priority, intra_priority_value); |
| 43 } | 85 } |
| 44 | 86 |
| 45 ThrottlingURLLoader::ThrottlingURLLoader( | 87 ThrottlingURLLoader::ThrottlingURLLoader( |
| 46 std::vector<std::unique_ptr<URLLoaderThrottle>> throttles, | 88 std::vector<std::unique_ptr<URLLoaderThrottle>> throttles, |
| 47 mojom::URLLoaderClient* client) | 89 mojom::URLLoaderClient* client) |
| 48 : forwarding_client_(client), client_binding_(this) { | 90 : forwarding_client_(client), client_binding_(this) { |
| 49 if (throttles.size() > 0) { | 91 if (throttles.size() > 0) { |
| 50 // TODO(yzshen): Implement a URLLoaderThrottle subclass which handles a list | 92 // TODO(yzshen): Implement a URLLoaderThrottle subclass which handles a list |
| 51 // of URLLoaderThrottles. | 93 // of URLLoaderThrottles. |
| 52 CHECK_EQ(1u, throttles.size()); | 94 CHECK_EQ(1u, throttles.size()); |
| 53 throttle_ = std::move(throttles[0]); | 95 throttle_ = std::move(throttles[0]); |
| 54 throttle_->set_delegate(this); | 96 throttle_->set_delegate(this); |
| 55 } | 97 } |
| 56 } | 98 } |
| 57 | 99 |
| 58 void ThrottlingURLLoader::Start(mojom::URLLoaderFactory* factory, | 100 void ThrottlingURLLoader::Start( |
| 59 int32_t routing_id, | 101 mojom::URLLoaderFactory* factory, |
| 60 int32_t request_id, | 102 int32_t routing_id, |
| 61 uint32_t options, | 103 int32_t request_id, |
| 62 std::unique_ptr<ResourceRequest> url_request) { | 104 uint32_t options, |
| 105 std::unique_ptr<ResourceRequest> url_request, |
| 106 scoped_refptr<base::SingleThreadTaskRunner> task_runner) { |
| 63 DCHECK_EQ(DEFERRED_NONE, deferred_stage_); | 107 DCHECK_EQ(DEFERRED_NONE, deferred_stage_); |
| 64 DCHECK(!cancelled_by_throttle_); | 108 DCHECK(!cancelled_by_throttle_); |
| 65 | 109 |
| 66 if (throttle_) { | 110 if (throttle_) { |
| 67 bool deferred = false; | 111 bool deferred = false; |
| 68 throttle_->WillStartRequest(url_request->url, url_request->load_flags, | 112 throttle_->WillStartRequest(url_request->url, url_request->load_flags, |
| 69 url_request->resource_type, &deferred); | 113 url_request->resource_type, &deferred); |
| 70 if (cancelled_by_throttle_) | 114 if (cancelled_by_throttle_) |
| 71 return; | 115 return; |
| 72 | 116 |
| 73 if (deferred) { | 117 if (deferred) { |
| 74 deferred_stage_ = DEFERRED_START; | 118 deferred_stage_ = DEFERRED_START; |
| 75 url_loader_factory_ = factory; | 119 start_info_ = base::MakeUnique<StartInfo>(factory, routing_id, request_id, |
| 76 routing_id_ = routing_id; | 120 options, std::move(url_request), |
| 77 request_id_ = request_id; | 121 std::move(task_runner)); |
| 78 options_ = options; | |
| 79 url_request_ = std::move(url_request); | |
| 80 return; | 122 return; |
| 81 } | 123 } |
| 82 } | 124 } |
| 83 | 125 |
| 84 factory->CreateLoaderAndStart(mojo::MakeRequest(&url_loader_), routing_id, | 126 factory->CreateLoaderAndStart( |
| 85 request_id, options, *url_request, | 127 mojo::MakeRequest(&url_loader_), routing_id, request_id, options, |
| 86 client_binding_.CreateInterfacePtrAndBind()); | 128 *url_request, |
| 129 client_binding_.CreateInterfacePtrAndBind(std::move(task_runner))); |
| 87 } | 130 } |
| 88 | 131 |
| 89 void ThrottlingURLLoader::OnReceiveResponse( | 132 void ThrottlingURLLoader::OnReceiveResponse( |
| 90 const ResourceResponseHead& response_head, | 133 const ResourceResponseHead& response_head, |
| 91 const base::Optional<net::SSLInfo>& ssl_info, | 134 const base::Optional<net::SSLInfo>& ssl_info, |
| 92 mojom::DownloadedTempFilePtr downloaded_file) { | 135 mojom::DownloadedTempFilePtr downloaded_file) { |
| 93 DCHECK_EQ(DEFERRED_NONE, deferred_stage_); | 136 DCHECK_EQ(DEFERRED_NONE, deferred_stage_); |
| 94 DCHECK(!cancelled_by_throttle_); | 137 DCHECK(!cancelled_by_throttle_); |
| 95 | 138 |
| 96 if (throttle_) { | 139 if (throttle_) { |
| 97 bool deferred = false; | 140 bool deferred = false; |
| 98 throttle_->WillProcessResponse(&deferred); | 141 throttle_->WillProcessResponse(&deferred); |
| 99 if (cancelled_by_throttle_) | 142 if (cancelled_by_throttle_) |
| 100 return; | 143 return; |
| 101 | 144 |
| 102 if (deferred) { | 145 if (deferred) { |
| 103 deferred_stage_ = DEFERRED_RESPONSE; | 146 deferred_stage_ = DEFERRED_RESPONSE; |
| 104 response_head_ = response_head; | 147 response_info_ = base::MakeUnique<ResponseInfo>( |
| 105 ssl_info_ = ssl_info; | 148 response_head, ssl_info, std::move(downloaded_file)); |
| 106 downloaded_file_ = std::move(downloaded_file); | |
| 107 client_binding_.PauseIncomingMethodCallProcessing(); | 149 client_binding_.PauseIncomingMethodCallProcessing(); |
| 108 return; | 150 return; |
| 109 } | 151 } |
| 110 } | 152 } |
| 111 | 153 |
| 112 forwarding_client_->OnReceiveResponse(response_head, ssl_info, | 154 forwarding_client_->OnReceiveResponse(response_head, ssl_info, |
| 113 std::move(downloaded_file)); | 155 std::move(downloaded_file)); |
| 114 } | 156 } |
| 115 | 157 |
| 116 void ThrottlingURLLoader::OnReceiveRedirect( | 158 void ThrottlingURLLoader::OnReceiveRedirect( |
| 117 const net::RedirectInfo& redirect_info, | 159 const net::RedirectInfo& redirect_info, |
| 118 const ResourceResponseHead& response_head) { | 160 const ResourceResponseHead& response_head) { |
| 119 DCHECK_EQ(DEFERRED_NONE, deferred_stage_); | 161 DCHECK_EQ(DEFERRED_NONE, deferred_stage_); |
| 120 DCHECK(!cancelled_by_throttle_); | 162 DCHECK(!cancelled_by_throttle_); |
| 121 | 163 |
| 122 if (throttle_) { | 164 if (throttle_) { |
| 123 bool deferred = false; | 165 bool deferred = false; |
| 124 throttle_->WillRedirectRequest(redirect_info, &deferred); | 166 throttle_->WillRedirectRequest(redirect_info, &deferred); |
| 125 if (cancelled_by_throttle_) | 167 if (cancelled_by_throttle_) |
| 126 return; | 168 return; |
| 127 | 169 |
| 128 if (deferred) { | 170 if (deferred) { |
| 129 deferred_stage_ = DEFERRED_REDIRECT; | 171 deferred_stage_ = DEFERRED_REDIRECT; |
| 130 redirect_info_ = redirect_info; | 172 redirect_info_ = |
| 131 response_head_ = response_head; | 173 base::MakeUnique<RedirectInfo>(redirect_info, response_head); |
| 132 client_binding_.PauseIncomingMethodCallProcessing(); | 174 client_binding_.PauseIncomingMethodCallProcessing(); |
| 133 return; | 175 return; |
| 134 } | 176 } |
| 135 } | 177 } |
| 136 | 178 |
| 137 forwarding_client_->OnReceiveRedirect(redirect_info, response_head); | 179 forwarding_client_->OnReceiveRedirect(redirect_info, response_head); |
| 138 } | 180 } |
| 139 | 181 |
| 140 void ThrottlingURLLoader::OnDataDownloaded(int64_t data_len, | 182 void ThrottlingURLLoader::OnDataDownloaded(int64_t data_len, |
| 141 int64_t encoded_data_len) { | 183 int64_t encoded_data_len) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 | 247 |
| 206 forwarding_client_->OnComplete(request_complete_data); | 248 forwarding_client_->OnComplete(request_complete_data); |
| 207 } | 249 } |
| 208 | 250 |
| 209 void ThrottlingURLLoader::Resume() { | 251 void ThrottlingURLLoader::Resume() { |
| 210 if (cancelled_by_throttle_ || deferred_stage_ == DEFERRED_NONE) | 252 if (cancelled_by_throttle_ || deferred_stage_ == DEFERRED_NONE) |
| 211 return; | 253 return; |
| 212 | 254 |
| 213 switch (deferred_stage_) { | 255 switch (deferred_stage_) { |
| 214 case DEFERRED_START: { | 256 case DEFERRED_START: { |
| 215 url_loader_factory_->CreateLoaderAndStart( | 257 start_info_->url_loader_factory->CreateLoaderAndStart( |
| 216 mojo::MakeRequest(&url_loader_), routing_id_, request_id_, options_, | 258 mojo::MakeRequest(&url_loader_), start_info_->routing_id, |
| 217 *url_request_, client_binding_.CreateInterfacePtrAndBind()); | 259 start_info_->request_id, start_info_->options, |
| 260 *start_info_->url_request, |
| 261 client_binding_.CreateInterfacePtrAndBind( |
| 262 std::move(start_info_->task_runner))); |
| 218 | 263 |
| 219 if (set_priority_cached_) { | 264 if (priority_info_) { |
| 220 set_priority_cached_ = false; | 265 auto priority_info = std::move(priority_info_); |
| 221 url_loader_->SetPriority(priority_, intra_priority_value_); | 266 url_loader_->SetPriority(priority_info->priority, |
| 267 priority_info->intra_priority_value); |
| 222 } | 268 } |
| 223 break; | 269 break; |
| 224 } | 270 } |
| 225 case DEFERRED_REDIRECT: { | 271 case DEFERRED_REDIRECT: { |
| 226 client_binding_.ResumeIncomingMethodCallProcessing(); | 272 client_binding_.ResumeIncomingMethodCallProcessing(); |
| 227 forwarding_client_->OnReceiveRedirect(redirect_info_, response_head_); | 273 forwarding_client_->OnReceiveRedirect(redirect_info_->redirect_info, |
| 274 redirect_info_->response_head); |
| 228 break; | 275 break; |
| 229 } | 276 } |
| 230 case DEFERRED_RESPONSE: { | 277 case DEFERRED_RESPONSE: { |
| 231 client_binding_.ResumeIncomingMethodCallProcessing(); | 278 client_binding_.ResumeIncomingMethodCallProcessing(); |
| 232 forwarding_client_->OnReceiveResponse(response_head_, ssl_info_, | 279 forwarding_client_->OnReceiveResponse( |
| 233 std::move(downloaded_file_)); | 280 response_info_->response_head, response_info_->ssl_info, |
| 281 std::move(response_info_->downloaded_file)); |
| 234 break; | 282 break; |
| 235 } | 283 } |
| 236 default: | 284 default: |
| 237 NOTREACHED(); | 285 NOTREACHED(); |
| 238 break; | 286 break; |
| 239 } | 287 } |
| 240 deferred_stage_ = DEFERRED_NONE; | 288 deferred_stage_ = DEFERRED_NONE; |
| 241 } | 289 } |
| 242 | 290 |
| 243 } // namespace content | 291 } // namespace content |
| OLD | NEW |