| 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/browser/loader/mojo_async_resource_handler.h" | 5 #include "content/browser/loader/mojo_async_resource_handler.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include "content/browser/loader/resource_controller.h" | 21 #include "content/browser/loader/resource_controller.h" |
| 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_request_info_impl.h" | 23 #include "content/browser/loader/resource_request_info_impl.h" |
| 24 #include "content/browser/loader/resource_scheduler.h" | 24 #include "content/browser/loader/resource_scheduler.h" |
| 25 #include "content/browser/loader/upload_progress_tracker.h" | 25 #include "content/browser/loader/upload_progress_tracker.h" |
| 26 #include "content/common/resource_request_completion_status.h" | 26 #include "content/common/resource_request_completion_status.h" |
| 27 #include "content/public/browser/global_request_id.h" | 27 #include "content/public/browser/global_request_id.h" |
| 28 #include "content/public/common/resource_response.h" | 28 #include "content/public/common/resource_response.h" |
| 29 #include "mojo/public/c/system/data_pipe.h" | 29 #include "mojo/public/c/system/data_pipe.h" |
| 30 #include "mojo/public/cpp/bindings/message.h" | 30 #include "mojo/public/cpp/bindings/message.h" |
| 31 #include "net/base/io_buffer.h" |
| 31 #include "net/base/mime_sniffer.h" | 32 #include "net/base/mime_sniffer.h" |
| 32 #include "net/base/net_errors.h" | |
| 33 #include "net/url_request/redirect_info.h" | 33 #include "net/url_request/redirect_info.h" |
| 34 | 34 |
| 35 namespace content { | 35 namespace content { |
| 36 namespace { | 36 namespace { |
| 37 | 37 |
| 38 int g_allocation_size = MojoAsyncResourceHandler::kDefaultAllocationSize; | 38 int g_allocation_size = MojoAsyncResourceHandler::kDefaultAllocationSize; |
| 39 | 39 |
| 40 // MimeTypeResourceHandler *implicitly* requires that the buffer size | 40 // MimeTypeResourceHandler *implicitly* requires that the buffer size |
| 41 // returned from OnWillRead should be larger than certain size. | 41 // returned from OnWillRead should be larger than certain size. |
| 42 // TODO(yhirano): Fix MimeTypeResourceHandler. | 42 // TODO(yhirano): Fix MimeTypeResourceHandler. |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 base::Unretained(this))); | 220 base::Unretained(this))); |
| 221 } | 221 } |
| 222 | 222 |
| 223 controller->Resume(); | 223 controller->Resume(); |
| 224 } | 224 } |
| 225 | 225 |
| 226 void MojoAsyncResourceHandler::OnWillRead( | 226 void MojoAsyncResourceHandler::OnWillRead( |
| 227 scoped_refptr<net::IOBuffer>* buf, | 227 scoped_refptr<net::IOBuffer>* buf, |
| 228 int* buf_size, | 228 int* buf_size, |
| 229 std::unique_ptr<ResourceController> controller) { | 229 std::unique_ptr<ResourceController> controller) { |
| 230 // |buffer_| is set to nullptr on successful read completion (Except for the | |
| 231 // final 0-byte read, so this DCHECK will also catch OnWillRead being called | |
| 232 // after OnReadCompelted(0)). | |
| 233 DCHECK(!buffer_); | |
| 234 DCHECK_EQ(0u, buffer_offset_); | |
| 235 | |
| 236 if (!CheckForSufficientResource()) { | 230 if (!CheckForSufficientResource()) { |
| 237 controller->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES); | 231 controller->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES); |
| 238 return; | 232 return; |
| 239 } | 233 } |
| 240 | 234 |
| 241 bool first_call = false; | |
| 242 if (!shared_writer_) { | 235 if (!shared_writer_) { |
| 243 first_call = true; | |
| 244 MojoCreateDataPipeOptions options; | 236 MojoCreateDataPipeOptions options; |
| 245 options.struct_size = sizeof(MojoCreateDataPipeOptions); | 237 options.struct_size = sizeof(MojoCreateDataPipeOptions); |
| 246 options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; | 238 options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; |
| 247 options.element_num_bytes = 1; | 239 options.element_num_bytes = 1; |
| 248 options.capacity_num_bytes = g_allocation_size; | 240 options.capacity_num_bytes = g_allocation_size; |
| 249 mojo::DataPipe data_pipe(options); | 241 mojo::DataPipe data_pipe(options); |
| 250 | 242 |
| 251 DCHECK(data_pipe.producer_handle.is_valid()); | 243 DCHECK(data_pipe.producer_handle.is_valid()); |
| 252 DCHECK(data_pipe.consumer_handle.is_valid()); | 244 DCHECK(data_pipe.consumer_handle.is_valid()); |
| 253 | 245 |
| 254 response_body_consumer_handle_ = std::move(data_pipe.consumer_handle); | 246 response_body_consumer_handle_ = std::move(data_pipe.consumer_handle); |
| 255 shared_writer_ = new SharedWriter(std::move(data_pipe.producer_handle)); | 247 shared_writer_ = new SharedWriter(std::move(data_pipe.producer_handle)); |
| 256 handle_watcher_.Watch(shared_writer_->writer(), MOJO_HANDLE_SIGNAL_WRITABLE, | 248 handle_watcher_.Watch(shared_writer_->writer(), MOJO_HANDLE_SIGNAL_WRITABLE, |
| 257 base::Bind(&MojoAsyncResourceHandler::OnWritable, | 249 base::Bind(&MojoAsyncResourceHandler::OnWritable, |
| 258 base::Unretained(this))); | 250 base::Unretained(this))); |
| 259 handle_watcher_.ArmOrNotify(); | 251 handle_watcher_.ArmOrNotify(); |
| 260 } | |
| 261 | 252 |
| 262 bool defer = false; | 253 bool defer = false; |
| 263 if (!AllocateWriterIOBuffer(&buffer_, &defer)) { | 254 scoped_refptr<net::IOBufferWithSize> buffer; |
| 264 controller->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES); | 255 if (!AllocateWriterIOBuffer(&buffer, &defer)) { |
| 265 return; | |
| 266 } | |
| 267 | |
| 268 if (defer) { | |
| 269 DCHECK(!buffer_); | |
| 270 parent_buffer_ = buf; | |
| 271 parent_buffer_size_ = buf_size; | |
| 272 HoldController(std::move(controller)); | |
| 273 request()->LogBlockedBy("MojoAsyncResourceHandler"); | |
| 274 did_defer_on_will_read_ = true; | |
| 275 return; | |
| 276 } | |
| 277 | |
| 278 // The first call to OnWillRead must return a buffer of at least | |
| 279 // kMinAllocationSize. If the Mojo buffer is too small, need to allocate an | |
| 280 // intermediary buffer. | |
| 281 if (first_call && static_cast<size_t>(buffer_->size()) < kMinAllocationSize) { | |
| 282 // The allocated buffer is too small, so need to create an intermediary one. | |
| 283 if (EndWrite(0) != MOJO_RESULT_OK) { | |
| 284 controller->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES); | 256 controller->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES); |
| 285 return; | 257 return; |
| 286 } | 258 } |
| 259 if (!defer) { |
| 260 if (static_cast<size_t>(buffer->size()) >= kMinAllocationSize) { |
| 261 *buf = buffer_ = buffer; |
| 262 *buf_size = buffer_->size(); |
| 263 controller->Resume(); |
| 264 return; |
| 265 } |
| 266 |
| 267 // The allocated buffer is too small. |
| 268 if (EndWrite(0) != MOJO_RESULT_OK) { |
| 269 controller->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES); |
| 270 return; |
| 271 } |
| 272 } |
| 287 DCHECK(!is_using_io_buffer_not_from_writer_); | 273 DCHECK(!is_using_io_buffer_not_from_writer_); |
| 288 is_using_io_buffer_not_from_writer_ = true; | 274 is_using_io_buffer_not_from_writer_ = true; |
| 289 buffer_ = new net::IOBufferWithSize(kMinAllocationSize); | 275 buffer_ = new net::IOBufferWithSize(kMinAllocationSize); |
| 290 } | 276 } |
| 291 | 277 |
| 278 DCHECK_EQ(0u, buffer_offset_); |
| 292 *buf = buffer_; | 279 *buf = buffer_; |
| 293 *buf_size = buffer_->size(); | 280 *buf_size = buffer_->size(); |
| 294 controller->Resume(); | 281 controller->Resume(); |
| 295 } | 282 } |
| 296 | 283 |
| 297 void MojoAsyncResourceHandler::OnReadCompleted( | 284 void MojoAsyncResourceHandler::OnReadCompleted( |
| 298 int bytes_read, | 285 int bytes_read, |
| 299 std::unique_ptr<ResourceController> controller) { | 286 std::unique_ptr<ResourceController> controller) { |
| 300 DCHECK(!has_controller()); | 287 DCHECK(!has_controller()); |
| 301 DCHECK_GE(bytes_read, 0); | 288 DCHECK_GE(bytes_read, 0); |
| 302 DCHECK(buffer_); | 289 DCHECK(buffer_); |
| 303 | 290 |
| 304 if (bytes_read == 0) { | 291 if (!bytes_read) { |
| 305 // Note that |buffer_| is not cleared here, which will cause a DCHECK on | |
| 306 // subsequent OnWillRead calls. | |
| 307 controller->Resume(); | 292 controller->Resume(); |
| 308 return; | 293 return; |
| 309 } | 294 } |
| 310 | 295 |
| 311 const ResourceRequestInfoImpl* info = GetRequestInfo(); | 296 const ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 312 if (info->ShouldReportRawHeaders()) { | 297 if (info->ShouldReportRawHeaders()) { |
| 313 auto transfer_size_diff = CalculateRecentlyReceivedBytes(); | 298 auto transfer_size_diff = CalculateRecentlyReceivedBytes(); |
| 314 if (transfer_size_diff > 0) | 299 if (transfer_size_diff > 0) |
| 315 url_loader_client_->OnTransferSizeUpdated(transfer_size_diff); | 300 url_loader_client_->OnTransferSizeUpdated(transfer_size_diff); |
| 316 } | 301 } |
| 317 | 302 |
| 318 if (response_body_consumer_handle_.is_valid()) { | 303 if (response_body_consumer_handle_.is_valid()) { |
| 319 // Send the data pipe on the first OnReadCompleted call. | 304 // Send the data pipe on the first OnReadCompleted call. |
| 320 url_loader_client_->OnStartLoadingResponseBody( | 305 url_loader_client_->OnStartLoadingResponseBody( |
| 321 std::move(response_body_consumer_handle_)); | 306 std::move(response_body_consumer_handle_)); |
| 322 response_body_consumer_handle_.reset(); | 307 response_body_consumer_handle_.reset(); |
| 323 } | 308 } |
| 324 | 309 |
| 325 if (is_using_io_buffer_not_from_writer_) { | 310 if (is_using_io_buffer_not_from_writer_) { |
| 326 // Couldn't allocate a large enough buffer on the data pipe in OnWillRead. | 311 // Couldn't allocate a buffer on the data pipe in OnWillRead. |
| 327 DCHECK_EQ(0u, buffer_bytes_read_); | 312 DCHECK_EQ(0u, buffer_bytes_read_); |
| 328 buffer_bytes_read_ = bytes_read; | 313 buffer_bytes_read_ = bytes_read; |
| 329 bool defer = false; | 314 bool defer = false; |
| 330 if (!CopyReadDataToDataPipe(&defer)) { | 315 if (!CopyReadDataToDataPipe(&defer)) { |
| 331 controller->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES); | 316 controller->Cancel(); |
| 332 return; | 317 return; |
| 333 } | 318 } |
| 334 if (defer) { | 319 if (defer) { |
| 335 request()->LogBlockedBy("MojoAsyncResourceHandler"); | 320 request()->LogBlockedBy("MojoAsyncResourceHandler"); |
| 336 did_defer_on_writing_ = true; | 321 did_defer_on_writing_ = true; |
| 337 HoldController(std::move(controller)); | 322 HoldController(std::move(controller)); |
| 338 return; | 323 return; |
| 339 } | 324 } |
| 340 controller->Resume(); | 325 controller->Resume(); |
| 341 return; | 326 return; |
| 342 } | 327 } |
| 343 | 328 |
| 344 if (EndWrite(bytes_read) != MOJO_RESULT_OK) { | 329 if (EndWrite(bytes_read) != MOJO_RESULT_OK) { |
| 345 controller->Cancel(); | 330 controller->Cancel(); |
| 346 return; | 331 return; |
| 347 } | 332 } |
| 333 // Allocate a buffer for the next OnWillRead call here, because OnWillRead |
| 334 // doesn't have |defer| parameter. |
| 335 bool defer = false; |
| 336 if (!AllocateWriterIOBuffer(&buffer_, &defer)) { |
| 337 controller->Cancel(); |
| 338 return; |
| 339 } |
| 340 if (defer) { |
| 341 request()->LogBlockedBy("MojoAsyncResourceHandler"); |
| 342 did_defer_on_writing_ = true; |
| 343 HoldController(std::move(controller)); |
| 344 return; |
| 345 } |
| 348 | 346 |
| 349 buffer_ = nullptr; | |
| 350 controller->Resume(); | 347 controller->Resume(); |
| 351 } | 348 } |
| 352 | 349 |
| 353 void MojoAsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) { | 350 void MojoAsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) { |
| 354 url_loader_client_->OnDataDownloaded(bytes_downloaded, | 351 url_loader_client_->OnDataDownloaded(bytes_downloaded, |
| 355 CalculateRecentlyReceivedBytes()); | 352 CalculateRecentlyReceivedBytes()); |
| 356 } | 353 } |
| 357 | 354 |
| 358 void MojoAsyncResourceHandler::FollowRedirect() { | 355 void MojoAsyncResourceHandler::FollowRedirect() { |
| 359 if (!request()->status().is_success()) { | 356 if (!request()->status().is_success()) { |
| 360 DVLOG(1) << "FollowRedirect for invalid request"; | 357 DVLOG(1) << "FollowRedirect for invalid request"; |
| 361 return; | 358 return; |
| 362 } | 359 } |
| 363 if (!did_defer_on_redirect_) { | 360 if (!did_defer_on_redirect_) { |
| 364 DVLOG(1) << "Malformed FollowRedirect request"; | 361 DVLOG(1) << "Malformed FollowRedirect request"; |
| 365 ReportBadMessage("Malformed FollowRedirect request"); | 362 ReportBadMessage("Malformed FollowRedirect request"); |
| 366 return; | 363 return; |
| 367 } | 364 } |
| 368 | 365 |
| 369 DCHECK(!did_defer_on_will_read_); | |
| 370 DCHECK(!did_defer_on_writing_); | 366 DCHECK(!did_defer_on_writing_); |
| 371 did_defer_on_redirect_ = false; | 367 did_defer_on_redirect_ = false; |
| 372 request()->LogUnblocked(); | 368 request()->LogUnblocked(); |
| 373 Resume(); | 369 Resume(); |
| 374 } | 370 } |
| 375 | 371 |
| 376 void MojoAsyncResourceHandler::SetPriority(net::RequestPriority priority, | 372 void MojoAsyncResourceHandler::SetPriority(net::RequestPriority priority, |
| 377 int32_t intra_priority_value) { | 373 int32_t intra_priority_value) { |
| 378 ResourceDispatcherHostImpl::Get()->scheduler()->ReprioritizeRequest( | 374 ResourceDispatcherHostImpl::Get()->scheduler()->ReprioritizeRequest( |
| 379 request(), priority, intra_priority_value); | 375 request(), priority, intra_priority_value); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 request_complete_data.completion_time = base::TimeTicks::Now(); | 447 request_complete_data.completion_time = base::TimeTicks::Now(); |
| 452 request_complete_data.encoded_data_length = | 448 request_complete_data.encoded_data_length = |
| 453 request()->GetTotalReceivedBytes(); | 449 request()->GetTotalReceivedBytes(); |
| 454 request_complete_data.encoded_body_length = request()->GetRawBodyBytes(); | 450 request_complete_data.encoded_body_length = request()->GetRawBodyBytes(); |
| 455 | 451 |
| 456 url_loader_client_->OnComplete(request_complete_data); | 452 url_loader_client_->OnComplete(request_complete_data); |
| 457 controller->Resume(); | 453 controller->Resume(); |
| 458 } | 454 } |
| 459 | 455 |
| 460 bool MojoAsyncResourceHandler::CopyReadDataToDataPipe(bool* defer) { | 456 bool MojoAsyncResourceHandler::CopyReadDataToDataPipe(bool* defer) { |
| 461 while (buffer_bytes_read_ > 0) { | 457 while (true) { |
| 462 scoped_refptr<net::IOBufferWithSize> dest; | 458 scoped_refptr<net::IOBufferWithSize> dest; |
| 463 if (!AllocateWriterIOBuffer(&dest, defer)) | 459 if (!AllocateWriterIOBuffer(&dest, defer)) |
| 464 return false; | 460 return false; |
| 465 if (*defer) | 461 if (*defer) |
| 466 return true; | 462 return true; |
| 463 if (buffer_bytes_read_ == 0) { |
| 464 // All bytes are copied. Save the buffer for the next OnWillRead call. |
| 465 buffer_ = std::move(dest); |
| 466 return true; |
| 467 } |
| 467 | 468 |
| 468 size_t copied_size = | 469 size_t copied_size = |
| 469 std::min(buffer_bytes_read_, static_cast<size_t>(dest->size())); | 470 std::min(buffer_bytes_read_, static_cast<size_t>(dest->size())); |
| 470 memcpy(dest->data(), buffer_->data() + buffer_offset_, copied_size); | 471 memcpy(dest->data(), buffer_->data() + buffer_offset_, copied_size); |
| 471 buffer_offset_ += copied_size; | 472 buffer_offset_ += copied_size; |
| 472 buffer_bytes_read_ -= copied_size; | 473 buffer_bytes_read_ -= copied_size; |
| 473 if (EndWrite(copied_size) != MOJO_RESULT_OK) | 474 if (EndWrite(copied_size) != MOJO_RESULT_OK) |
| 474 return false; | 475 return false; |
| 476 |
| 477 if (buffer_bytes_read_ == 0) { |
| 478 // All bytes are copied. |
| 479 buffer_offset_ = 0; |
| 480 is_using_io_buffer_not_from_writer_ = false; |
| 481 } |
| 475 } | 482 } |
| 476 | |
| 477 // All bytes are copied. | |
| 478 buffer_ = nullptr; | |
| 479 buffer_offset_ = 0; | |
| 480 is_using_io_buffer_not_from_writer_ = false; | |
| 481 return true; | |
| 482 } | 483 } |
| 483 | 484 |
| 484 bool MojoAsyncResourceHandler::AllocateWriterIOBuffer( | 485 bool MojoAsyncResourceHandler::AllocateWriterIOBuffer( |
| 485 scoped_refptr<net::IOBufferWithSize>* buf, | 486 scoped_refptr<net::IOBufferWithSize>* buf, |
| 486 bool* defer) { | 487 bool* defer) { |
| 487 void* data = nullptr; | 488 void* data = nullptr; |
| 488 uint32_t available = 0; | 489 uint32_t available = 0; |
| 489 MojoResult result = BeginWrite(&data, &available); | 490 MojoResult result = BeginWrite(&data, &available); |
| 490 if (result == MOJO_RESULT_SHOULD_WAIT) { | 491 if (result == MOJO_RESULT_SHOULD_WAIT) { |
| 491 *defer = true; | 492 *defer = true; |
| 492 return true; | 493 return true; |
| 493 } | 494 } |
| 494 if (result != MOJO_RESULT_OK) | 495 if (result != MOJO_RESULT_OK) |
| 495 return false; | 496 return false; |
| 496 DCHECK_GT(available, 0u); | |
| 497 *buf = new WriterIOBuffer(shared_writer_, data, available); | 497 *buf = new WriterIOBuffer(shared_writer_, data, available); |
| 498 return true; | 498 return true; |
| 499 } | 499 } |
| 500 | 500 |
| 501 bool MojoAsyncResourceHandler::CheckForSufficientResource() { | 501 bool MojoAsyncResourceHandler::CheckForSufficientResource() { |
| 502 if (has_checked_for_sufficient_resources_) | 502 if (has_checked_for_sufficient_resources_) |
| 503 return true; | 503 return true; |
| 504 has_checked_for_sufficient_resources_ = true; | 504 has_checked_for_sufficient_resources_ = true; |
| 505 | 505 |
| 506 if (rdh_->HasSufficientResourcesForRequest(request())) | 506 if (rdh_->HasSufficientResourcesForRequest(request())) |
| 507 return true; | 507 return true; |
| 508 | 508 |
| 509 return false; | 509 return false; |
| 510 } | 510 } |
| 511 | 511 |
| 512 void MojoAsyncResourceHandler::OnWritable(MojoResult result) { | 512 void MojoAsyncResourceHandler::OnWritable(MojoResult result) { |
| 513 if (did_defer_on_will_read_) { | |
| 514 DCHECK(has_controller()); | |
| 515 DCHECK(!did_defer_on_writing_); | |
| 516 DCHECK(!did_defer_on_redirect_); | |
| 517 | |
| 518 did_defer_on_will_read_ = false; | |
| 519 | |
| 520 scoped_refptr<net::IOBuffer>* parent_buffer = parent_buffer_; | |
| 521 parent_buffer_ = nullptr; | |
| 522 int* parent_buffer_size = parent_buffer_size_; | |
| 523 parent_buffer_size_ = nullptr; | |
| 524 OnWillRead(parent_buffer, parent_buffer_size, ReleaseController()); | |
| 525 return; | |
| 526 } | |
| 527 | |
| 528 if (!did_defer_on_writing_) | 513 if (!did_defer_on_writing_) |
| 529 return; | 514 return; |
| 530 DCHECK(has_controller()); | 515 DCHECK(has_controller()); |
| 531 DCHECK(!did_defer_on_redirect_); | 516 DCHECK(!did_defer_on_redirect_); |
| 532 did_defer_on_writing_ = false; | 517 did_defer_on_writing_ = false; |
| 533 | 518 |
| 534 DCHECK(is_using_io_buffer_not_from_writer_); | 519 if (is_using_io_buffer_not_from_writer_) { |
| 535 // |buffer_| is set to a net::IOBufferWithSize. Write the buffer contents | 520 // |buffer_| is set to a net::IOBufferWithSize. Write the buffer contents |
| 536 // to the data pipe. | 521 // to the data pipe. |
| 537 DCHECK_GT(buffer_bytes_read_, 0u); | 522 DCHECK_GT(buffer_bytes_read_, 0u); |
| 538 if (!CopyReadDataToDataPipe(&did_defer_on_writing_)) { | 523 if (!CopyReadDataToDataPipe(&did_defer_on_writing_)) { |
| 539 CancelWithError(net::ERR_INSUFFICIENT_RESOURCES); | 524 CancelWithError(net::ERR_FAILED); |
| 540 return; | 525 return; |
| 526 } |
| 527 } else { |
| 528 // Allocate a buffer for the next OnWillRead call here. |
| 529 if (!AllocateWriterIOBuffer(&buffer_, &did_defer_on_writing_)) { |
| 530 CancelWithError(net::ERR_FAILED); |
| 531 return; |
| 532 } |
| 541 } | 533 } |
| 542 | 534 |
| 543 if (did_defer_on_writing_) { | 535 if (did_defer_on_writing_) { |
| 544 // Continue waiting. | 536 // Continue waiting. |
| 545 return; | 537 return; |
| 546 } | 538 } |
| 547 request()->LogUnblocked(); | 539 request()->LogUnblocked(); |
| 548 Resume(); | 540 Resume(); |
| 549 } | 541 } |
| 550 | 542 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 base::Bind(&MojoAsyncResourceHandler::OnUploadProgressACK, | 584 base::Bind(&MojoAsyncResourceHandler::OnUploadProgressACK, |
| 593 weak_factory_.GetWeakPtr())); | 585 weak_factory_.GetWeakPtr())); |
| 594 } | 586 } |
| 595 | 587 |
| 596 void MojoAsyncResourceHandler::OnUploadProgressACK() { | 588 void MojoAsyncResourceHandler::OnUploadProgressACK() { |
| 597 if (upload_progress_tracker_) | 589 if (upload_progress_tracker_) |
| 598 upload_progress_tracker_->OnAckReceived(); | 590 upload_progress_tracker_->OnAckReceived(); |
| 599 } | 591 } |
| 600 | 592 |
| 601 } // namespace content | 593 } // namespace content |
| OLD | NEW |