| Index: content/browser/loader/mojo_async_resource_handler.cc
|
| diff --git a/content/browser/loader/mojo_async_resource_handler.cc b/content/browser/loader/mojo_async_resource_handler.cc
|
| index 6d5a9d7c4a08f396856ebee72852a861a6a3eb21..8936346e86d7d70e424a5240098e562f2cb1b1fe 100644
|
| --- a/content/browser/loader/mojo_async_resource_handler.cc
|
| +++ b/content/browser/loader/mojo_async_resource_handler.cc
|
| @@ -20,6 +20,7 @@
|
| #include "content/public/browser/resource_dispatcher_host_delegate.h"
|
| #include "content/public/common/resource_response.h"
|
| #include "mojo/public/c/system/data_pipe.h"
|
| +#include "mojo/public/cpp/bindings/message.h"
|
| #include "mojo/public/cpp/system/data_pipe.h"
|
| #include "net/base/io_buffer.h"
|
| #include "net/base/load_flags.h"
|
| @@ -127,8 +128,24 @@ bool MojoAsyncResourceHandler::OnRequestRedirected(
|
| const net::RedirectInfo& redirect_info,
|
| ResourceResponse* response,
|
| bool* defer) {
|
| - // Not implemented.
|
| - return false;
|
| + // Unlike OnResponseStarted, OnRequestRedirected will NOT be preceded by
|
| + // OnWillRead.
|
| + DCHECK(!shared_writer_);
|
| +
|
| + *defer = true;
|
| + request()->LogBlockedBy("MojoAsyncResourceHandler");
|
| + did_defer_on_redirect_ = true;
|
| +
|
| + NetLogObserver::PopulateResponseInfo(request(), response);
|
| + response->head.encoded_data_length = request()->GetTotalReceivedBytes();
|
| + response->head.request_start = request()->creation_time();
|
| + response->head.response_start = base::TimeTicks::Now();
|
| + // TODO(davidben): Is it necessary to pass the new first party URL for
|
| + // cookies? The only case where it can change is top-level navigation requests
|
| + // and hopefully those will eventually all be owned by the browser. It's
|
| + // possible this is still needed while renderer-owned ones exist.
|
| + url_loader_client_->OnReceiveRedirect(redirect_info, response->head);
|
| + return true;
|
| }
|
|
|
| bool MojoAsyncResourceHandler::OnResponseStarted(ResourceResponse* response,
|
| @@ -218,8 +235,10 @@ bool MojoAsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
|
| buffer_bytes_read_ = bytes_read;
|
| if (!CopyReadDataToDataPipe(defer))
|
| return false;
|
| - if (*defer)
|
| - OnDefer();
|
| + if (*defer) {
|
| + request()->LogBlockedBy("MojoAsyncResourceHandler");
|
| + did_defer_on_writing_ = true;
|
| + }
|
| return true;
|
| }
|
|
|
| @@ -229,8 +248,10 @@ bool MojoAsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
|
| // doesn't have |defer| parameter.
|
| if (!AllocateWriterIOBuffer(&buffer_, defer))
|
| return false;
|
| - if (*defer)
|
| - OnDefer();
|
| + if (*defer) {
|
| + request()->LogBlockedBy("MojoAsyncResourceHandler");
|
| + did_defer_on_writing_ = true;
|
| + }
|
| return true;
|
| }
|
|
|
| @@ -245,11 +266,24 @@ void MojoAsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) {
|
| }
|
|
|
| void MojoAsyncResourceHandler::FollowRedirect() {
|
| - NOTIMPLEMENTED();
|
| + if (!request()->status().is_success()) {
|
| + DVLOG(1) << "FollowRedirect for invalid request";
|
| + return;
|
| + }
|
| + if (!did_defer_on_redirect_) {
|
| + DVLOG(1) << "Malformed FollowRedirect request";
|
| + ReportBadMessage("Malformed FollowRedirect request");
|
| + return;
|
| + }
|
| +
|
| + DCHECK(!did_defer_on_writing_);
|
| + did_defer_on_redirect_ = false;
|
| + request()->LogUnblocked();
|
| + controller()->Resume();
|
| }
|
|
|
| -void MojoAsyncResourceHandler::ResumeForTesting() {
|
| - Resume();
|
| +void MojoAsyncResourceHandler::OnWritableForTesting() {
|
| + OnWritable(MOJO_RESULT_OK);
|
| }
|
|
|
| void MojoAsyncResourceHandler::SetAllocationSizeForTesting(size_t size) {
|
| @@ -351,28 +385,41 @@ bool MojoAsyncResourceHandler::AllocateWriterIOBuffer(
|
| return true;
|
| }
|
|
|
| -void MojoAsyncResourceHandler::Resume() {
|
| - if (!did_defer_)
|
| +bool MojoAsyncResourceHandler::CheckForSufficientResource() {
|
| + if (has_checked_for_sufficient_resources_)
|
| + return true;
|
| + has_checked_for_sufficient_resources_ = true;
|
| +
|
| + if (rdh_->HasSufficientResourcesForRequest(request()))
|
| + return true;
|
| +
|
| + controller()->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES);
|
| + return false;
|
| +}
|
| +
|
| +void MojoAsyncResourceHandler::OnWritable(MojoResult result) {
|
| + if (!did_defer_on_writing_)
|
| return;
|
| - did_defer_ = false;
|
| + DCHECK(!did_defer_on_redirect_);
|
| + did_defer_on_writing_ = false;
|
|
|
| if (is_using_io_buffer_not_from_writer_) {
|
| // |buffer_| is set to a net::IOBufferWithSize. Write the buffer contents
|
| // to the data pipe.
|
| DCHECK_GT(buffer_bytes_read_, 0u);
|
| - if (!CopyReadDataToDataPipe(&did_defer_)) {
|
| + if (!CopyReadDataToDataPipe(&did_defer_on_writing_)) {
|
| controller()->CancelWithError(net::ERR_FAILED);
|
| return;
|
| }
|
| } else {
|
| // Allocate a buffer for the next OnWillRead call here.
|
| - if (!AllocateWriterIOBuffer(&buffer_, &did_defer_)) {
|
| + if (!AllocateWriterIOBuffer(&buffer_, &did_defer_on_writing_)) {
|
| controller()->CancelWithError(net::ERR_FAILED);
|
| return;
|
| }
|
| }
|
|
|
| - if (did_defer_) {
|
| + if (did_defer_on_writing_) {
|
| // Continue waiting.
|
| return;
|
| }
|
| @@ -380,31 +427,14 @@ void MojoAsyncResourceHandler::Resume() {
|
| controller()->Resume();
|
| }
|
|
|
| -void MojoAsyncResourceHandler::OnDefer() {
|
| - request()->LogBlockedBy("MojoAsyncResourceHandler");
|
| - did_defer_ = true;
|
| -}
|
| -
|
| -bool MojoAsyncResourceHandler::CheckForSufficientResource() {
|
| - if (has_checked_for_sufficient_resources_)
|
| - return true;
|
| - has_checked_for_sufficient_resources_ = true;
|
| -
|
| - if (rdh_->HasSufficientResourcesForRequest(request()))
|
| - return true;
|
| -
|
| - controller()->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES);
|
| - return false;
|
| -}
|
| -
|
| -void MojoAsyncResourceHandler::OnWritable(MojoResult unused) {
|
| - Resume();
|
| -}
|
| -
|
| void MojoAsyncResourceHandler::Cancel() {
|
| const ResourceRequestInfoImpl* info = GetRequestInfo();
|
| ResourceDispatcherHostImpl::Get()->CancelRequestFromRenderer(
|
| GlobalRequestID(info->GetChildID(), info->GetRequestID()));
|
| }
|
|
|
| +void MojoAsyncResourceHandler::ReportBadMessage(const std::string& error) {
|
| + mojo::ReportBadMessage(error);
|
| +}
|
| +
|
| } // namespace content
|
|
|