Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(511)

Side by Side Diff: content/network/url_loader_impl.cc

Issue 2919413003: Fix network service hanging with empty bodies. (Closed)
Patch Set: review comments Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/network/url_loader_impl.h ('k') | content/network/url_loader_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « content/network/url_loader_impl.h ('k') | content/network/url_loader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698