Chromium Code Reviews| Index: content/browser/loader/buffered_resource_handler.cc |
| diff --git a/content/browser/loader/buffered_resource_handler.cc b/content/browser/loader/buffered_resource_handler.cc |
| index 97c260baf5073ed35ff131568cbbb6384218c3b1..9e63c6707ca7887c0b1e56f60522b6930f778275 100644 |
| --- a/content/browser/loader/buffered_resource_handler.cc |
| +++ b/content/browser/loader/buffered_resource_handler.cc |
| @@ -15,6 +15,7 @@ |
| #include "content/browser/loader/certificate_resource_handler.h" |
| #include "content/browser/loader/resource_dispatcher_host_impl.h" |
| #include "content/browser/loader/resource_request_info_impl.h" |
| +#include "content/browser/loader/stream_resource_handler.h" |
| #include "content/browser/plugin_service_impl.h" |
| #include "content/public/browser/content_browser_client.h" |
| #include "content/public/browser/download_item.h" |
| @@ -310,7 +311,7 @@ bool BufferedResourceHandler::SelectNextHandler(bool* defer) { |
| info->set_is_download(true); |
| scoped_ptr<ResourceHandler> handler( |
| new CertificateResourceHandler(request())); |
| - return UseAlternateNextHandler(handler.Pass()); |
| + return UseAlternateNextHandler(handler.Pass(), std::string()); |
| } |
| if (!info->allow_download()) |
| @@ -321,10 +322,12 @@ bool BufferedResourceHandler::SelectNextHandler(bool* defer) { |
| if (net::IsSupportedMimeType(mime_type)) |
| return true; |
| + std::string payload; |
| scoped_ptr<ResourceHandler> handler( |
| - host_->MaybeInterceptAsStream(request(), response_.get())); |
| - if (handler) |
| - return UseAlternateNextHandler(handler.Pass()); |
| + host_->MaybeInterceptAsStream(request(), response_.get(), &payload)); |
| + if (handler) { |
| + return UseAlternateNextHandler(handler.Pass(), payload); |
| + } |
| #if defined(ENABLE_PLUGINS) |
| bool stale; |
| @@ -353,20 +356,23 @@ bool BufferedResourceHandler::SelectNextHandler(bool* defer) { |
| content::DownloadItem::kInvalidId, |
| scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()), |
| DownloadUrlParameters::OnStartedCallback())); |
| - return UseAlternateNextHandler(handler.Pass()); |
| + return UseAlternateNextHandler(handler.Pass(), std::string()); |
| } |
| bool BufferedResourceHandler::UseAlternateNextHandler( |
| - scoped_ptr<ResourceHandler> new_handler) { |
| - if (response_->head.headers.get() && // Can be NULL if FTP. |
| - response_->head.headers->response_code() / 100 != 2) { |
| - // The response code indicates that this is an error page, but we don't |
| - // know how to display the content. We follow Firefox here and show our |
| - // own error page instead of triggering a download. |
| - // TODO(abarth): We should abstract the response_code test, but this kind |
| - // of check is scattered throughout our codebase. |
| - request()->CancelWithError(net::ERR_INVALID_RESPONSE); |
| - return false; |
| + scoped_ptr<ResourceHandler> new_handler, |
| + const std::string& payload_for_old_handler) { |
| + if (payload_for_old_handler.empty()) { |
|
mmenke
2014/05/29 16:10:29
Suggest a short comment about this check here.
Zachary Kuznia
2014/05/29 20:42:40
After further consideration, I decided that this e
|
| + if (response_->head.headers.get() && // Can be NULL if FTP. |
| + response_->head.headers->response_code() / 100 != 2) { |
| + // The response code indicates that this is an error page, but we don't |
| + // know how to display the content. We follow Firefox here and show our |
| + // own error page instead of triggering a download. |
| + // TODO(abarth): We should abstract the response_code test, but this kind |
| + // of check is scattered throughout our codebase. |
| + request()->CancelWithError(net::ERR_INVALID_RESPONSE); |
| + return false; |
| + } |
| } |
| int request_id = GetRequestID(); |
| @@ -380,11 +386,34 @@ bool BufferedResourceHandler::UseAlternateNextHandler( |
| // which does so is CrossSiteResourceHandler. Cross-site transitions should |
| // not trigger when switching handlers. |
| DCHECK(!defer_ignored); |
| - net::URLRequestStatus status(net::URLRequestStatus::CANCELED, |
| - net::ERR_ABORTED); |
| - next_handler_->OnResponseCompleted(request_id, status, std::string(), |
| - &defer_ignored); |
| - DCHECK(!defer_ignored); |
| + if (payload_for_old_handler.empty()) { |
| + net::URLRequestStatus status(net::URLRequestStatus::CANCELED, |
| + net::ERR_ABORTED); |
| + next_handler_->OnResponseCompleted(request_id, status, std::string(), |
| + &defer_ignored); |
| + DCHECK(!defer_ignored); |
| + } else { |
| + scoped_refptr<net::IOBuffer> buf; |
| + int size = 0; |
| + |
| + next_handler_->OnWillRead(request_id, &buf, &size, |
| + payload_for_old_handler.length()); |
| + CHECK(size >= (int)payload_for_old_handler.length()); |
|
mmenke
2014/05/29 16:10:29
nit: CHECK_GE
mmenke
2014/05/29 16:10:29
C-style casts are forbidden. use static_cast.
Zachary Kuznia
2014/05/29 20:42:40
Done.
|
| + |
| + memcpy(buf->data(), payload_for_old_handler.c_str(), |
| + payload_for_old_handler.length()); |
| + |
| + defer_ignored = false; |
|
mmenke
2014/05/29 16:10:29
This isn't done on the above "next_handler_->OnRes
Zachary Kuznia
2014/05/29 20:42:40
Done.
|
| + next_handler_->OnReadCompleted(request_id, payload_for_old_handler.length(), |
| + &defer_ignored); |
| + DCHECK(!defer_ignored); |
| + |
| + defer_ignored = false; |
| + net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0); |
| + next_handler_->OnResponseCompleted(request_id, status, std::string(), |
| + &defer_ignored); |
| + DCHECK(!defer_ignored); |
| + } |
| // This is handled entirely within the new ResourceHandler, so just reset the |
| // original ResourceHandler. |