| Index: content/browser/loader/mime_sniffing_resource_handler.cc
|
| diff --git a/content/browser/loader/mime_sniffing_resource_handler.cc b/content/browser/loader/mime_sniffing_resource_handler.cc
|
| index 1c157dfb0546e9058744233c85a05ef4caffdcf7..eeb69171e54edb8a1f7fb2988948a0750829d54a 100644
|
| --- a/content/browser/loader/mime_sniffing_resource_handler.cc
|
| +++ b/content/browser/loader/mime_sniffing_resource_handler.cc
|
| @@ -276,10 +276,13 @@ bool MimeSniffingResourceHandler::ProcessState(bool* defer) {
|
| case STATE_BUFFERING:
|
| return_value = MaybeIntercept(defer);
|
| break;
|
| - case STATE_INTERCEPTION_CHECK_DONE:
|
| - return_value = ReplayResponseReceived(defer);
|
| + case STATE_NEED_TO_PREPARE_TO_USE_NEW_HANDLER:
|
| + return_value = PrepareToUseNewHandler(defer);
|
| break;
|
| - case STATE_REPLAYING_RESPONSE_RECEIVED:
|
| + case STATE_PREPARING_TO_USE_NEW_HANDLER:
|
| + return_value = ReplayReceivedResponse(defer);
|
| + break;
|
| + case STATE_REPLAYING_RECEIVED_RESPONSE:
|
| return_value = ReplayReadCompleted(defer);
|
| break;
|
| default:
|
| @@ -298,19 +301,54 @@ bool MimeSniffingResourceHandler::MaybeIntercept(bool* defer) {
|
| return false;
|
|
|
| if (!*defer)
|
| - state_ = STATE_INTERCEPTION_CHECK_DONE;
|
| + state_ = STATE_NEED_TO_PREPARE_TO_USE_NEW_HANDLER;
|
|
|
| return true;
|
| }
|
|
|
| -bool MimeSniffingResourceHandler::ReplayResponseReceived(bool* defer) {
|
| - DCHECK_EQ(STATE_INTERCEPTION_CHECK_DONE, state_);
|
| - state_ = STATE_REPLAYING_RESPONSE_RECEIVED;
|
| +bool MimeSniffingResourceHandler::PrepareToUseNewHandler(bool* defer) {
|
| + DCHECK_EQ(STATE_NEED_TO_PREPARE_TO_USE_NEW_HANDLER, state_);
|
| + state_ = STATE_PREPARING_TO_USE_NEW_HANDLER;
|
| + if (!new_handler_)
|
| + return true;
|
| +
|
| + // The InterceptingResourceHandler's OnWillStart method has already been
|
| + // called, so need to call it on the new ResourceHandler before it can be
|
| + // swapped in to take its place. Redirects will not be passed to the new
|
| + // handler.
|
| + // TODO(mmenke): If the request is cancelled while new_handler_ is
|
| + // non-NULL, the new handler will not get an OnResponseCompleted call
|
| + // before being deleted. Is that worth fixing?
|
| +
|
| + // Temporarily set NewHandler's ResourceController, so it can cancel /
|
| + // pause / resume the request, if needed. It ultimately should use
|
| + // InterceptingHandler's ResourceController, but if cancels the request,
|
| + // it shouldn't go through that ResourceController, as it would be
|
| + // calling into the controller when the controller may not think the
|
| + // ball is currently in its court.
|
| + new_handler_->SetController(this);
|
| +
|
| + return new_handler_->OnWillStart(request()->url(), defer);
|
| +}
|
| +
|
| +bool MimeSniffingResourceHandler::ReplayReceivedResponse(bool* defer) {
|
| + DCHECK_EQ(STATE_PREPARING_TO_USE_NEW_HANDLER, state_);
|
| +
|
| + // Swap in new handler, if there is one.
|
| + if (new_handler_) {
|
| + // Clear the controller.
|
| + new_handler_->SetController(nullptr);
|
| +
|
| + intercepting_handler_->UseNewHandler(std::move(new_handler_),
|
| + std::move(payload_for_old_handler_));
|
| + }
|
| +
|
| + state_ = STATE_REPLAYING_RECEIVED_RESPONSE;
|
| return next_handler_->OnResponseStarted(response_.get(), defer);
|
| }
|
|
|
| bool MimeSniffingResourceHandler::ReplayReadCompleted(bool* defer) {
|
| - DCHECK_EQ(STATE_REPLAYING_RESPONSE_RECEIVED, state_);
|
| + DCHECK_EQ(STATE_REPLAYING_RECEIVED_RESPONSE, state_);
|
|
|
| state_ = STATE_STREAMING;
|
|
|
| @@ -411,11 +449,10 @@ bool MimeSniffingResourceHandler::MaybeStartInterception(bool* defer) {
|
| return false;
|
|
|
| info->set_is_download(true);
|
| - std::unique_ptr<ResourceHandler> handler(
|
| + new_handler_ =
|
| host_->CreateResourceHandlerForDownload(request(),
|
| true, // is_content_initiated
|
| - must_download));
|
| - intercepting_handler_->UseNewHandler(std::move(handler), std::string());
|
| + must_download);
|
| return true;
|
| }
|
|
|
| @@ -452,14 +489,12 @@ bool MimeSniffingResourceHandler::CheckForPluginHandler(
|
| base::FilePath plugin_path;
|
| if (has_plugin)
|
| plugin_path = plugin.path;
|
| - std::string payload;
|
| - std::unique_ptr<ResourceHandler> handler(host_->MaybeInterceptAsStream(
|
| - plugin_path, request(), response_.get(), &payload));
|
| - if (handler) {
|
| + new_handler_ = host_->MaybeInterceptAsStream(
|
| + plugin_path, request(), response_.get(), &payload_for_old_handler_);
|
| + if (new_handler_) {
|
| if (!CheckResponseIsNotProvisional())
|
| return false;
|
| *handled_by_plugin = true;
|
| - intercepting_handler_->UseNewHandler(std::move(handler), payload);
|
| }
|
| #endif
|
| return true;
|
|
|