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