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/network/url_loader_impl.h" | 5 #include "content/network/url_loader_impl.h" |
6 | 6 |
7 #include "base/task_scheduler/post_task.h" | 7 #include "base/task_scheduler/post_task.h" |
8 #include "base/threading/thread_task_runner_handle.h" | 8 #include "base/threading/thread_task_runner_handle.h" |
9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
10 #include "content/common/net_adapters.h" | 10 #include "content/common/net_adapters.h" |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 if (metadata) { | 264 if (metadata) { |
265 const uint8_t* data = reinterpret_cast<const uint8_t*>(metadata->data()); | 265 const uint8_t* data = reinterpret_cast<const uint8_t*>(metadata->data()); |
266 | 266 |
267 url_loader_client_->OnReceiveCachedMetadata( | 267 url_loader_client_->OnReceiveCachedMetadata( |
268 std::vector<uint8_t>(data, data + metadata->size())); | 268 std::vector<uint8_t>(data, data + metadata->size())); |
269 } | 269 } |
270 | 270 |
271 mojo::DataPipe data_pipe(kDefaultAllocationSize); | 271 mojo::DataPipe data_pipe(kDefaultAllocationSize); |
272 | 272 |
273 response_body_stream_ = std::move(data_pipe.producer_handle); | 273 response_body_stream_ = std::move(data_pipe.producer_handle); |
274 response_body_consumer_handle_ = std::move(data_pipe.consumer_handle); | 274 url_loader_client_->OnStartLoadingResponseBody( |
| 275 std::move(data_pipe.consumer_handle)); |
275 peer_closed_handle_watcher_.Watch( | 276 peer_closed_handle_watcher_.Watch( |
276 response_body_stream_.get(), MOJO_HANDLE_SIGNAL_PEER_CLOSED, | 277 response_body_stream_.get(), MOJO_HANDLE_SIGNAL_PEER_CLOSED, |
277 base::Bind(&URLLoaderImpl::OnResponseBodyStreamClosed, | 278 base::Bind(&URLLoaderImpl::OnResponseBodyStreamClosed, |
278 base::Unretained(this))); | 279 base::Unretained(this))); |
279 peer_closed_handle_watcher_.ArmOrNotify(); | 280 peer_closed_handle_watcher_.ArmOrNotify(); |
280 | 281 |
281 writable_handle_watcher_.Watch( | 282 writable_handle_watcher_.Watch( |
282 response_body_stream_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, | 283 response_body_stream_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, |
283 base::Bind(&URLLoaderImpl::OnResponseBodyStreamReady, | 284 base::Bind(&URLLoaderImpl::OnResponseBodyStreamReady, |
284 base::Unretained(this))); | 285 base::Unretained(this))); |
(...skipping 22 matching lines...) Expand all Loading... |
307 return; | 308 return; |
308 } | 309 } |
309 | 310 |
310 CHECK_GT(static_cast<uint32_t>(std::numeric_limits<int>::max()), num_bytes); | 311 CHECK_GT(static_cast<uint32_t>(std::numeric_limits<int>::max()), num_bytes); |
311 scoped_refptr<net::IOBuffer> buf(new NetToMojoIOBuffer(pending_write_.get())); | 312 scoped_refptr<net::IOBuffer> buf(new NetToMojoIOBuffer(pending_write_.get())); |
312 int bytes_read; | 313 int bytes_read; |
313 url_request_->Read(buf.get(), static_cast<int>(num_bytes), &bytes_read); | 314 url_request_->Read(buf.get(), static_cast<int>(num_bytes), &bytes_read); |
314 if (url_request_->status().is_io_pending()) { | 315 if (url_request_->status().is_io_pending()) { |
315 // Wait for OnReadCompleted. | 316 // Wait for OnReadCompleted. |
316 } else if (url_request_->status().is_success() && bytes_read > 0) { | 317 } else if (url_request_->status().is_success() && bytes_read > 0) { |
317 SendDataPipeIfNecessary(); | |
318 DidRead(static_cast<uint32_t>(bytes_read), true); | 318 DidRead(static_cast<uint32_t>(bytes_read), true); |
319 } else { | 319 } else { |
320 NotifyCompleted(net::OK); | 320 NotifyCompleted(net::OK); |
321 writable_handle_watcher_.Cancel(); | 321 writable_handle_watcher_.Cancel(); |
322 pending_write_->Complete(0); | 322 pending_write_->Complete(0); |
323 pending_write_ = nullptr; // This closes the data pipe. | 323 pending_write_ = nullptr; // This closes the data pipe. |
324 DeleteIfNeeded(); | 324 DeleteIfNeeded(); |
325 return; | 325 return; |
326 } | 326 } |
327 } | 327 } |
(...skipping 15 matching lines...) Expand all Loading... |
343 int bytes_read) { | 343 int bytes_read) { |
344 DCHECK(url_request == url_request_.get()); | 344 DCHECK(url_request == url_request_.get()); |
345 | 345 |
346 if (!url_request->status().is_success()) { | 346 if (!url_request->status().is_success()) { |
347 writable_handle_watcher_.Cancel(); | 347 writable_handle_watcher_.Cancel(); |
348 pending_write_ = nullptr; // This closes the data pipe. | 348 pending_write_ = nullptr; // This closes the data pipe. |
349 DeleteIfNeeded(); | 349 DeleteIfNeeded(); |
350 return; | 350 return; |
351 } | 351 } |
352 | 352 |
353 SendDataPipeIfNecessary(); | |
354 | |
355 DidRead(static_cast<uint32_t>(bytes_read), false); | 353 DidRead(static_cast<uint32_t>(bytes_read), false); |
356 } | 354 } |
357 | 355 |
358 void URLLoaderImpl::NotifyCompleted(int error_code) { | 356 void URLLoaderImpl::NotifyCompleted(int error_code) { |
359 ResourceRequestCompletionStatus request_complete_data; | 357 ResourceRequestCompletionStatus request_complete_data; |
360 request_complete_data.error_code = error_code; | 358 request_complete_data.error_code = error_code; |
361 request_complete_data.exists_in_cache = | 359 request_complete_data.exists_in_cache = |
362 url_request_->response_info().was_cached; | 360 url_request_->response_info().was_cached; |
363 request_complete_data.completion_time = base::TimeTicks::Now(); | 361 request_complete_data.completion_time = base::TimeTicks::Now(); |
364 request_complete_data.encoded_data_length = | 362 request_complete_data.encoded_data_length = |
365 url_request_->GetTotalReceivedBytes(); | 363 url_request_->GetTotalReceivedBytes(); |
366 request_complete_data.encoded_body_length = url_request_->GetRawBodyBytes(); | 364 request_complete_data.encoded_body_length = url_request_->GetRawBodyBytes(); |
367 | 365 |
368 url_loader_client_->OnComplete(request_complete_data); | 366 url_loader_client_->OnComplete(request_complete_data); |
369 DeleteIfNeeded(); | 367 DeleteIfNeeded(); |
370 } | 368 } |
371 | 369 |
372 void URLLoaderImpl::SendDataPipeIfNecessary() { | |
373 if (response_body_consumer_handle_.is_valid()) { | |
374 // Send the data pipe on the first OnReadCompleted call. | |
375 url_loader_client_->OnStartLoadingResponseBody( | |
376 std::move(response_body_consumer_handle_)); | |
377 } | |
378 } | |
379 | |
380 void URLLoaderImpl::OnConnectionError() { | 370 void URLLoaderImpl::OnConnectionError() { |
381 connected_ = false; | 371 connected_ = false; |
382 DeleteIfNeeded(); | 372 DeleteIfNeeded(); |
383 } | 373 } |
384 | 374 |
385 void URLLoaderImpl::OnResponseBodyStreamClosed(MojoResult result) { | 375 void URLLoaderImpl::OnResponseBodyStreamClosed(MojoResult result) { |
386 url_request_.reset(); | 376 url_request_.reset(); |
387 response_body_stream_.reset(); | 377 response_body_stream_.reset(); |
388 pending_write_ = nullptr; | 378 pending_write_ = nullptr; |
389 DeleteIfNeeded(); | 379 DeleteIfNeeded(); |
390 } | 380 } |
391 | 381 |
392 void URLLoaderImpl::OnResponseBodyStreamReady(MojoResult result) { | 382 void URLLoaderImpl::OnResponseBodyStreamReady(MojoResult result) { |
393 // TODO: Handle a bad |result| value. | 383 // TODO: Handle a bad |result| value. |
394 DCHECK_EQ(result, MOJO_RESULT_OK); | 384 DCHECK_EQ(result, MOJO_RESULT_OK); |
395 ReadMore(); | 385 ReadMore(); |
396 } | 386 } |
397 | 387 |
398 void URLLoaderImpl::DeleteIfNeeded() { | 388 void URLLoaderImpl::DeleteIfNeeded() { |
399 bool has_data_pipe = pending_write_.get() || response_body_stream_.is_valid(); | 389 bool has_data_pipe = pending_write_.get() || response_body_stream_.is_valid(); |
400 if (!connected_ && !has_data_pipe) | 390 if (!connected_ && !has_data_pipe) |
401 delete this; | 391 delete this; |
402 } | 392 } |
403 | 393 |
404 } // namespace content | 394 } // namespace content |
OLD | NEW |