Commit 6edb6488 authored by zork@chromium.org's avatar zork@chromium.org

Forward MIME types to BrowserPlugin when a viewer is specified.

When the mime_type_handler key is available in an extension, this creates a
BrowserPlugin and gives the ID of it to the background page.

BUG=368514

Review URL: https://codereview.chromium.org/263513004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@276841 0039d316-1c4b-4281-b951-d872f2087c98
parent 03bbb697
...@@ -61,6 +61,7 @@ void StreamsPrivateAPI::ExecuteMimeTypeHandler( ...@@ -61,6 +61,7 @@ void StreamsPrivateAPI::ExecuteMimeTypeHandler(
const std::string& extension_id, const std::string& extension_id,
content::WebContents* web_contents, content::WebContents* web_contents,
scoped_ptr<content::StreamHandle> stream, scoped_ptr<content::StreamHandle> stream,
const std::string& view_id,
int64 expected_content_size) { int64 expected_content_size) {
// Create the event's arguments value. // Create the event's arguments value.
streams_private::StreamInfo info; streams_private::StreamInfo info;
...@@ -69,6 +70,10 @@ void StreamsPrivateAPI::ExecuteMimeTypeHandler( ...@@ -69,6 +70,10 @@ void StreamsPrivateAPI::ExecuteMimeTypeHandler(
info.stream_url = stream->GetURL().spec(); info.stream_url = stream->GetURL().spec();
info.tab_id = ExtensionTabUtil::GetTabId(web_contents); info.tab_id = ExtensionTabUtil::GetTabId(web_contents);
if (!view_id.empty()) {
info.view_id.reset(new std::string(view_id));
}
int size = -1; int size = -1;
if (expected_content_size <= INT_MAX) if (expected_content_size <= INT_MAX)
size = expected_content_size; size = expected_content_size;
......
...@@ -30,9 +30,15 @@ class StreamsPrivateAPI : public BrowserContextKeyedAPI, ...@@ -30,9 +30,15 @@ class StreamsPrivateAPI : public BrowserContextKeyedAPI,
explicit StreamsPrivateAPI(content::BrowserContext* context); explicit StreamsPrivateAPI(content::BrowserContext* context);
virtual ~StreamsPrivateAPI(); virtual ~StreamsPrivateAPI();
// Send the onExecuteMimeTypeHandler event to |extension_id|.
// |web_contents| is used to determine the tabId where the document is being
// opened. The data for the document will be readable from |stream|, and
// should be |expected_content_size| bytes long. If the viewer is being opened
// in a BrowserPlugin, specify a non-empty |view_id| of the plugin.
void ExecuteMimeTypeHandler(const std::string& extension_id, void ExecuteMimeTypeHandler(const std::string& extension_id,
content::WebContents* web_contents, content::WebContents* web_contents,
scoped_ptr<content::StreamHandle> stream, scoped_ptr<content::StreamHandle> stream,
const std::string& view_id,
int64 expected_content_size); int64 expected_content_size);
void AbortStream(const std::string& extension_id, void AbortStream(const std::string& extension_id,
......
...@@ -6,11 +6,13 @@ ...@@ -6,11 +6,13 @@
#include "base/lazy_instance.h" #include "base/lazy_instance.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/plugin_manager.h" #include "chrome/browser/extensions/plugin_manager.h"
#include "chrome/browser/plugins/chrome_plugin_service_filter.h" #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/api/plugins/plugins_handler.h" #include "chrome/common/extensions/api/plugins/plugins_handler.h"
#include "chrome/common/extensions/manifest_handlers/mime_types_handler.h"
#include "content/public/browser/plugin_service.h" #include "content/public/browser/plugin_service.h"
#include "content/public/common/pepper_plugin_info.h" #include "content/public/common/pepper_plugin_info.h"
#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry.h"
...@@ -77,6 +79,13 @@ void PluginManager::OnExtensionLoaded(content::BrowserContext* browser_context, ...@@ -77,6 +79,13 @@ void PluginManager::OnExtensionLoaded(content::BrowserContext* browser_context,
UpdatePluginListWithNaClModules(); UpdatePluginListWithNaClModules();
} }
const MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension);
if (handler && !handler->handler_url().empty()) {
plugins_or_nacl_changed = true;
RegisterMimeTypeHandler(handler->extension_id());
UpdatePluginListWithNaClModules();
}
if (plugins_or_nacl_changed) if (plugins_or_nacl_changed)
PluginService::GetInstance()->PurgePluginListCache(profile_, false); PluginService::GetInstance()->PurgePluginListCache(profile_, false);
} }
...@@ -111,6 +120,12 @@ void PluginManager::OnExtensionUnloaded( ...@@ -111,6 +120,12 @@ void PluginManager::OnExtensionUnloaded(
UpdatePluginListWithNaClModules(); UpdatePluginListWithNaClModules();
} }
const MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension);
if (handler && !handler->handler_url().empty()) {
plugins_or_nacl_changed = true;
UnregisterMimeTypeHandler(handler->extension_id());
}
if (plugins_or_nacl_changed) if (plugins_or_nacl_changed)
PluginService::GetInstance()->PurgePluginListCache(profile_, false); PluginService::GetInstance()->PurgePluginListCache(profile_, false);
} }
...@@ -172,6 +187,45 @@ void PluginManager::UpdatePluginListWithNaClModules() { ...@@ -172,6 +187,45 @@ void PluginManager::UpdatePluginListWithNaClModules() {
break; break;
} }
} }
for (std::set<std::string>::iterator ix =
mime_type_handler_extension_ids_.begin();
ix != mime_type_handler_extension_ids_.end(); ++ix) {
const std::string& extension_id = *ix;
const Extension* extension =
profile_->GetExtensionService()->GetExtensionById(extension_id, false);
const MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension);
if (handler && !handler->handler_url().empty()) {
PluginService::GetInstance()->UnregisterInternalPlugin(
base::FilePath::FromUTF8Unsafe(extension_id));
content::WebPluginInfo info;
info.type = content::WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN;
info.name = base::UTF8ToUTF16(extension_id);
info.path = base::FilePath::FromUTF8Unsafe(extension_id);
for (std::set<std::string>::const_iterator mime_type =
handler->mime_type_set().begin();
mime_type != handler->mime_type_set().end(); ++mime_type) {
content::WebPluginMimeType mime_type_info;
mime_type_info.mime_type = *mime_type;
info.mime_types.push_back(mime_type_info);
}
PluginService::GetInstance()->RefreshPlugins();
PluginService::GetInstance()->RegisterInternalPlugin(info, true);
}
}
}
void PluginManager::RegisterMimeTypeHandler(const std::string& extension_id) {
mime_type_handler_extension_ids_.insert(extension_id);
}
void PluginManager::UnregisterMimeTypeHandler(const std::string& extension_id) {
mime_type_handler_extension_ids_.erase(extension_id);
PluginService::GetInstance()->UnregisterInternalPlugin(
base::FilePath::FromUTF8Unsafe(extension_id));
} }
NaClModuleInfo::List::iterator PluginManager::FindNaClModule(const GURL& url) { NaClModuleInfo::List::iterator PluginManager::FindNaClModule(const GURL& url) {
......
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
#ifndef CHROME_BROWSER_EXTENSIONS_PLUGIN_MANAGER_H_ #ifndef CHROME_BROWSER_EXTENSIONS_PLUGIN_MANAGER_H_
#define CHROME_BROWSER_EXTENSIONS_PLUGIN_MANAGER_H_ #define CHROME_BROWSER_EXTENSIONS_PLUGIN_MANAGER_H_
#include <set>
#include <string>
#include "base/scoped_observer.h" #include "base/scoped_observer.h"
#include "chrome/common/extensions/manifest_handlers/nacl_modules_handler.h" #include "chrome/common/extensions/manifest_handlers/nacl_modules_handler.h"
#include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/browser_context_keyed_api_factory.h"
...@@ -41,6 +44,9 @@ class PluginManager : public BrowserContextKeyedAPI, ...@@ -41,6 +44,9 @@ class PluginManager : public BrowserContextKeyedAPI,
void RegisterNaClModule(const NaClModuleInfo& info); void RegisterNaClModule(const NaClModuleInfo& info);
void UnregisterNaClModule(const NaClModuleInfo& info); void UnregisterNaClModule(const NaClModuleInfo& info);
void RegisterMimeTypeHandler(const std::string& extension_id);
void UnregisterMimeTypeHandler(const std::string& extension_id);
// Call UpdatePluginListWithNaClModules() after registering or unregistering // Call UpdatePluginListWithNaClModules() after registering or unregistering
// a NaCl module to see those changes reflected in the PluginList. // a NaCl module to see those changes reflected in the PluginList.
void UpdatePluginListWithNaClModules(); void UpdatePluginListWithNaClModules();
...@@ -61,6 +67,10 @@ class PluginManager : public BrowserContextKeyedAPI, ...@@ -61,6 +67,10 @@ class PluginManager : public BrowserContextKeyedAPI,
extensions::NaClModuleInfo::List nacl_module_list_; extensions::NaClModuleInfo::List nacl_module_list_;
// The set of extensions that are registered as the handler for at least one
// MIME type.
std::set<std::string> mime_type_handler_extension_ids_;
Profile* profile_; Profile* profile_;
// Listen to extension load, unloaded notifications. // Listen to extension load, unloaded notifications.
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <vector> #include <vector>
#include "base/base64.h" #include "base/base64.h"
#include "base/guid.h"
#include "base/logging.h" #include "base/logging.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chrome_notification_types.h"
...@@ -156,23 +157,12 @@ void UpdatePrerenderNetworkBytesCallback(int render_process_id, ...@@ -156,23 +157,12 @@ void UpdatePrerenderNetworkBytesCallback(int render_process_id,
} }
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
// Goes through the extension's file browser handlers and checks if there is one
// that can handle the |mime_type|.
// |extension| must not be NULL.
bool ExtensionCanHandleMimeType(const Extension* extension,
const std::string& mime_type) {
MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension);
if (!handler)
return false;
return handler->CanHandleMIMEType(mime_type);
}
void SendExecuteMimeTypeHandlerEvent(scoped_ptr<content::StreamHandle> stream, void SendExecuteMimeTypeHandlerEvent(scoped_ptr<content::StreamHandle> stream,
int64 expected_content_size, int64 expected_content_size,
int render_process_id, int render_process_id,
int render_view_id, int render_view_id,
const std::string& extension_id) { const std::string& extension_id,
const std::string& view_id) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
content::WebContents* web_contents = content::WebContents* web_contents =
...@@ -196,7 +186,8 @@ void SendExecuteMimeTypeHandlerEvent(scoped_ptr<content::StreamHandle> stream, ...@@ -196,7 +186,8 @@ void SendExecuteMimeTypeHandlerEvent(scoped_ptr<content::StreamHandle> stream,
if (!streams_private) if (!streams_private)
return; return;
streams_private->ExecuteMimeTypeHandler( streams_private->ExecuteMimeTypeHandler(
extension_id, web_contents, stream.Pass(), expected_content_size); extension_id, web_contents, stream.Pass(), view_id,
expected_content_size);
} }
void LaunchURL(const GURL& url, int render_process_id, int render_view_id, void LaunchURL(const GURL& url, int render_process_id, int render_view_id,
...@@ -264,6 +255,7 @@ ChromeResourceDispatcherHostDelegate::ChromeResourceDispatcherHostDelegate( ...@@ -264,6 +255,7 @@ ChromeResourceDispatcherHostDelegate::ChromeResourceDispatcherHostDelegate(
} }
ChromeResourceDispatcherHostDelegate::~ChromeResourceDispatcherHostDelegate() { ChromeResourceDispatcherHostDelegate::~ChromeResourceDispatcherHostDelegate() {
CHECK(stream_target_info_.empty());
} }
bool ChromeResourceDispatcherHostDelegate::ShouldBeginRequest( bool ChromeResourceDispatcherHostDelegate::ShouldBeginRequest(
...@@ -549,14 +541,14 @@ bool ChromeResourceDispatcherHostDelegate::ShouldForceDownloadResource( ...@@ -549,14 +541,14 @@ bool ChromeResourceDispatcherHostDelegate::ShouldForceDownloadResource(
} }
bool ChromeResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream( bool ChromeResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream(
content::ResourceContext* resource_context, net::URLRequest* request,
const GURL& url,
const std::string& mime_type, const std::string& mime_type,
GURL* origin, GURL* origin,
std::string* target_id) { std::string* payload) {
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
ProfileIOData* io_data = ProfileIOData* io_data =
ProfileIOData::FromResourceContext(resource_context); ProfileIOData::FromResourceContext(info->GetContext());
bool profile_is_off_the_record = io_data->IsOffTheRecord(); bool profile_is_off_the_record = io_data->IsOffTheRecord();
const scoped_refptr<const extensions::InfoMap> extension_info_map( const scoped_refptr<const extensions::InfoMap> extension_info_map(
io_data->GetExtensionInfoMap()); io_data->GetExtensionInfoMap());
...@@ -575,9 +567,17 @@ bool ChromeResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream( ...@@ -575,9 +567,17 @@ bool ChromeResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream(
continue; continue;
} }
if (ExtensionCanHandleMimeType(extension, mime_type)) { MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension);
if (handler && handler->CanHandleMIMEType(mime_type)) {
StreamTargetInfo target_info;
*origin = Extension::GetBaseURLFromExtensionId(extension_id); *origin = Extension::GetBaseURLFromExtensionId(extension_id);
*target_id = extension_id; target_info.extension_id = extension_id;
if (!handler->handler_url().empty()) {
target_info.view_id = base::GenerateGUID();
*payload = origin->spec() + handler->handler_url() +
"?id=" + target_info.view_id;
}
stream_target_info_[request] = target_info;
return true; return true;
} }
} }
...@@ -586,18 +586,20 @@ bool ChromeResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream( ...@@ -586,18 +586,20 @@ bool ChromeResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream(
} }
void ChromeResourceDispatcherHostDelegate::OnStreamCreated( void ChromeResourceDispatcherHostDelegate::OnStreamCreated(
content::ResourceContext* resource_context, net::URLRequest* request,
int render_process_id, scoped_ptr<content::StreamHandle> stream) {
int render_view_id,
const std::string& target_id,
scoped_ptr<content::StreamHandle> stream,
int64 expected_content_size) {
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
std::map<net::URLRequest*, StreamTargetInfo>::iterator ix =
stream_target_info_.find(request);
CHECK(ix != stream_target_info_.end());
content::BrowserThread::PostTask( content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE, content::BrowserThread::UI, FROM_HERE,
base::Bind(&SendExecuteMimeTypeHandlerEvent, base::Passed(&stream), base::Bind(&SendExecuteMimeTypeHandlerEvent, base::Passed(&stream),
expected_content_size, render_process_id, render_view_id, request->GetExpectedContentSize(),
target_id)); info->GetChildID(), info->GetRouteID(),
ix->second.extension_id, ix->second.view_id));
stream_target_info_.erase(request);
#endif #endif
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_RENDERER_HOST_CHROME_RESOURCE_DISPATCHER_HOST_DELEGATE_H_ #ifndef CHROME_BROWSER_RENDERER_HOST_CHROME_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
#define CHROME_BROWSER_RENDERER_HOST_CHROME_RESOURCE_DISPATCHER_HOST_DELEGATE_H_ #define CHROME_BROWSER_RENDERER_HOST_CHROME_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
#include <map>
#include <set> #include <set>
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
...@@ -70,18 +71,13 @@ class ChromeResourceDispatcherHostDelegate ...@@ -70,18 +71,13 @@ class ChromeResourceDispatcherHostDelegate
virtual bool ShouldForceDownloadResource( virtual bool ShouldForceDownloadResource(
const GURL& url, const std::string& mime_type) OVERRIDE; const GURL& url, const std::string& mime_type) OVERRIDE;
virtual bool ShouldInterceptResourceAsStream( virtual bool ShouldInterceptResourceAsStream(
content::ResourceContext* resource_context, net::URLRequest* request,
const GURL& url,
const std::string& mime_type, const std::string& mime_type,
GURL* origin, GURL* origin,
std::string* target_id) OVERRIDE; std::string* payload) OVERRIDE;
virtual void OnStreamCreated( virtual void OnStreamCreated(
content::ResourceContext* resource_context, net::URLRequest* request,
int render_process_id, scoped_ptr<content::StreamHandle> stream) OVERRIDE;
int render_view_id,
const std::string& target_id,
scoped_ptr<content::StreamHandle> stream,
int64 expected_content_size) OVERRIDE;
virtual void OnResponseStarted( virtual void OnResponseStarted(
net::URLRequest* request, net::URLRequest* request,
content::ResourceContext* resource_context, content::ResourceContext* resource_context,
...@@ -100,6 +96,11 @@ class ChromeResourceDispatcherHostDelegate ...@@ -100,6 +96,11 @@ class ChromeResourceDispatcherHostDelegate
ExternalProtocolHandler::Delegate* delegate); ExternalProtocolHandler::Delegate* delegate);
private: private:
struct StreamTargetInfo {
std::string extension_id;
std::string view_id;
};
void AppendStandardResourceThrottles( void AppendStandardResourceThrottles(
net::URLRequest* request, net::URLRequest* request,
content::ResourceContext* resource_context, content::ResourceContext* resource_context,
...@@ -118,6 +119,7 @@ class ChromeResourceDispatcherHostDelegate ...@@ -118,6 +119,7 @@ class ChromeResourceDispatcherHostDelegate
scoped_refptr<SafeBrowsingService> safe_browsing_; scoped_refptr<SafeBrowsingService> safe_browsing_;
scoped_refptr<extensions::UserScriptListener> user_script_listener_; scoped_refptr<extensions::UserScriptListener> user_script_listener_;
prerender::PrerenderTracker* prerender_tracker_; prerender::PrerenderTracker* prerender_tracker_;
std::map<net::URLRequest*, StreamTargetInfo> stream_target_info_;
DISALLOW_COPY_AND_ASSIGN(ChromeResourceDispatcherHostDelegate); DISALLOW_COPY_AND_ASSIGN(ChromeResourceDispatcherHostDelegate);
}; };
......
...@@ -18,6 +18,10 @@ namespace streamsPrivate { ...@@ -18,6 +18,10 @@ namespace streamsPrivate {
// a tab, it will be -1. // a tab, it will be -1.
long tabId; long tabId;
// The ID of the view that will render the stream, if the viewer was opened
// in a plugin.
DOMString? viewId;
// The amount of data the Stream should contain, if known. If there is no // The amount of data the Stream should contain, if known. If there is no
// information on the size it will be -1. // information on the size it will be -1.
long expectedContentSize; long expectedContentSize;
......
...@@ -41,6 +41,8 @@ class MimeTypesHandler { ...@@ -41,6 +41,8 @@ class MimeTypesHandler {
// The URL that will be used to handle MIME type requests. // The URL that will be used to handle MIME type requests.
const std::string handler_url() const { return handler_url_; } const std::string handler_url() const { return handler_url_; }
const std::set<std::string>& mime_type_set() const { return mime_type_set_; }
private: private:
// The id for the extension this action belongs to (as defined in the // The id for the extension this action belongs to (as defined in the
// extension manifest). // extension manifest).
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "content/browser/loader/certificate_resource_handler.h" #include "content/browser/loader/certificate_resource_handler.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_request_info_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/browser/plugin_service_impl.h"
#include "content/public/browser/content_browser_client.h" #include "content/public/browser/content_browser_client.h"
#include "content/public/browser/download_item.h" #include "content/public/browser/download_item.h"
...@@ -305,7 +306,7 @@ bool BufferedResourceHandler::SelectNextHandler(bool* defer) { ...@@ -305,7 +306,7 @@ bool BufferedResourceHandler::SelectNextHandler(bool* defer) {
info->set_is_download(true); info->set_is_download(true);
scoped_ptr<ResourceHandler> handler( scoped_ptr<ResourceHandler> handler(
new CertificateResourceHandler(request())); new CertificateResourceHandler(request()));
return UseAlternateNextHandler(handler.Pass()); return UseAlternateNextHandler(handler.Pass(), std::string());
} }
if (!info->allow_download()) if (!info->allow_download())
...@@ -316,10 +317,12 @@ bool BufferedResourceHandler::SelectNextHandler(bool* defer) { ...@@ -316,10 +317,12 @@ bool BufferedResourceHandler::SelectNextHandler(bool* defer) {
if (net::IsSupportedMimeType(mime_type)) if (net::IsSupportedMimeType(mime_type))
return true; return true;
std::string payload;
scoped_ptr<ResourceHandler> handler( scoped_ptr<ResourceHandler> handler(
host_->MaybeInterceptAsStream(request(), response_.get())); host_->MaybeInterceptAsStream(request(), response_.get(), &payload));
if (handler) if (handler) {
return UseAlternateNextHandler(handler.Pass()); return UseAlternateNextHandler(handler.Pass(), payload);
}
#if defined(ENABLE_PLUGINS) #if defined(ENABLE_PLUGINS)
bool stale; bool stale;
...@@ -348,11 +351,12 @@ bool BufferedResourceHandler::SelectNextHandler(bool* defer) { ...@@ -348,11 +351,12 @@ bool BufferedResourceHandler::SelectNextHandler(bool* defer) {
content::DownloadItem::kInvalidId, content::DownloadItem::kInvalidId,
scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()), scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()),
DownloadUrlParameters::OnStartedCallback())); DownloadUrlParameters::OnStartedCallback()));
return UseAlternateNextHandler(handler.Pass()); return UseAlternateNextHandler(handler.Pass(), std::string());
} }
bool BufferedResourceHandler::UseAlternateNextHandler( bool BufferedResourceHandler::UseAlternateNextHandler(
scoped_ptr<ResourceHandler> new_handler) { scoped_ptr<ResourceHandler> new_handler,
const std::string& payload_for_old_handler) {
if (response_->head.headers.get() && // Can be NULL if FTP. if (response_->head.headers.get() && // Can be NULL if FTP.
response_->head.headers->response_code() / 100 != 2) { response_->head.headers->response_code() / 100 != 2) {
// The response code indicates that this is an error page, but we don't // The response code indicates that this is an error page, but we don't
...@@ -373,10 +377,29 @@ bool BufferedResourceHandler::UseAlternateNextHandler( ...@@ -373,10 +377,29 @@ bool BufferedResourceHandler::UseAlternateNextHandler(
// which does so is CrossSiteResourceHandler. Cross-site transitions should // which does so is CrossSiteResourceHandler. Cross-site transitions should
// not trigger when switching handlers. // not trigger when switching handlers.
DCHECK(!defer_ignored); DCHECK(!defer_ignored);
net::URLRequestStatus status(net::URLRequestStatus::CANCELED, if (payload_for_old_handler.empty()) {
net::ERR_ABORTED); net::URLRequestStatus status(net::URLRequestStatus::CANCELED,
next_handler_->OnResponseCompleted(status, std::string(), &defer_ignored); net::ERR_ABORTED);
DCHECK(!defer_ignored); next_handler_->OnResponseCompleted(status, std::string(), &defer_ignored);
DCHECK(!defer_ignored);
} else {
scoped_refptr<net::IOBuffer> buf;
int size = 0;
next_handler_->OnWillRead(&buf, &size, payload_for_old_handler.length());
CHECK_GE(size, static_cast<int>(payload_for_old_handler.length()));
memcpy(buf->data(), payload_for_old_handler.c_str(),
payload_for_old_handler.length());
next_handler_->OnReadCompleted(payload_for_old_handler.length(),
&defer_ignored);
DCHECK(!defer_ignored);
net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
next_handler_->OnResponseCompleted(status, std::string(), &defer_ignored);
DCHECK(!defer_ignored);
}
// This is handled entirely within the new ResourceHandler, so just reset the // This is handled entirely within the new ResourceHandler, so just reset the
// original ResourceHandler. // original ResourceHandler.
......
...@@ -54,7 +54,8 @@ class BufferedResourceHandler ...@@ -54,7 +54,8 @@ class BufferedResourceHandler
bool ShouldSniffContent(); bool ShouldSniffContent();
bool DetermineMimeType(); bool DetermineMimeType();
bool SelectNextHandler(bool* defer); bool SelectNextHandler(bool* defer);
bool UseAlternateNextHandler(scoped_ptr<ResourceHandler> handler); bool UseAlternateNextHandler(scoped_ptr<ResourceHandler> handler,
const std::string& payload_for_old_handler);
bool ReplayReadCompleted(bool* defer); bool ReplayReadCompleted(bool* defer);
void CallReplayReadCompleted(); void CallReplayReadCompleted();
......
...@@ -608,18 +608,17 @@ ResourceDispatcherHostImpl::CreateResourceHandlerForDownload( ...@@ -608,18 +608,17 @@ ResourceDispatcherHostImpl::CreateResourceHandlerForDownload(
scoped_ptr<ResourceHandler> scoped_ptr<ResourceHandler>
ResourceDispatcherHostImpl::MaybeInterceptAsStream(net::URLRequest* request, ResourceDispatcherHostImpl::MaybeInterceptAsStream(net::URLRequest* request,
ResourceResponse* response) { ResourceResponse* response,
std::string* payload) {
ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request); ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request);
const std::string& mime_type = response->head.mime_type; const std::string& mime_type = response->head.mime_type;
GURL origin; GURL origin;
std::string target_id;
if (!delegate_ || if (!delegate_ ||
!delegate_->ShouldInterceptResourceAsStream(info->GetContext(), !delegate_->ShouldInterceptResourceAsStream(request,
request->url(),
mime_type, mime_type,
&origin, &origin,
&target_id)) { payload)) {
return scoped_ptr<ResourceHandler>(); return scoped_ptr<ResourceHandler>();
} }
...@@ -633,15 +632,11 @@ ResourceDispatcherHostImpl::MaybeInterceptAsStream(net::URLRequest* request, ...@@ -633,15 +632,11 @@ ResourceDispatcherHostImpl::MaybeInterceptAsStream(net::URLRequest* request,
info->set_is_stream(true); info->set_is_stream(true);
delegate_->OnStreamCreated( delegate_->OnStreamCreated(
info->GetContext(), request,
info->GetChildID(),
info->GetRouteID(),
target_id,
handler->stream()->CreateHandle( handler->stream()->CreateHandle(
request->url(), request->url(),
mime_type, mime_type,
response->head.headers), response->head.headers));
request->GetExpectedContentSize());
return handler.PassAs<ResourceHandler>(); return handler.PassAs<ResourceHandler>();
} }
......
...@@ -210,10 +210,13 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl ...@@ -210,10 +210,13 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
const DownloadUrlParameters::OnStartedCallback& started_cb); const DownloadUrlParameters::OnStartedCallback& started_cb);
// Must be called after the ResourceRequestInfo has been created // Must be called after the ResourceRequestInfo has been created
// and associated with the request. // and associated with the request. If |payload| is set to a non-empty value,
// the value will be sent to the old resource handler instead of cancelling
// it, except on HTTP errors.
scoped_ptr<ResourceHandler> MaybeInterceptAsStream( scoped_ptr<ResourceHandler> MaybeInterceptAsStream(
net::URLRequest* request, net::URLRequest* request,
ResourceResponse* response); ResourceResponse* response,
std::string* payload);
void ClearSSLClientAuthHandlerForRequest(net::URLRequest* request); void ClearSSLClientAuthHandlerForRequest(net::URLRequest* request);
......
...@@ -61,21 +61,16 @@ bool ResourceDispatcherHostDelegate::ShouldForceDownloadResource( ...@@ -61,21 +61,16 @@ bool ResourceDispatcherHostDelegate::ShouldForceDownloadResource(
} }
bool ResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream( bool ResourceDispatcherHostDelegate::ShouldInterceptResourceAsStream(
content::ResourceContext* resource_context, net::URLRequest* request,
const GURL& url,
const std::string& mime_type, const std::string& mime_type,
GURL* origin, GURL* origin,
std::string* target_id) { std::string* payload) {
return false; return false;
} }
void ResourceDispatcherHostDelegate::OnStreamCreated( void ResourceDispatcherHostDelegate::OnStreamCreated(
content::ResourceContext* resource_context, net::URLRequest* request,
int render_process_id, scoped_ptr<content::StreamHandle> stream) {
int render_view_id,
const std::string& target_id,
scoped_ptr<StreamHandle> stream,
int64 expected_content_size) {
} }
void ResourceDispatcherHostDelegate::OnResponseStarted( void ResourceDispatcherHostDelegate::OnResponseStarted(
......
...@@ -96,32 +96,28 @@ class CONTENT_EXPORT ResourceDispatcherHostDelegate { ...@@ -96,32 +96,28 @@ class CONTENT_EXPORT ResourceDispatcherHostDelegate {
virtual bool ShouldForceDownloadResource( virtual bool ShouldForceDownloadResource(
const GURL& url, const std::string& mime_type); const GURL& url, const std::string& mime_type);
// Returns true and sets |origin| and |target_id| if a Stream should be // Returns true and sets |origin| if a Stream should be created for the
// created for the resource. // resource.
// If true is returned, a new Stream will be created and OnStreamCreated() // If true is returned, a new Stream will be created and OnStreamCreated()
// will be called with // will be called with
// - the |target_id| returned by this function
// - a StreamHandle instance for the Stream. The handle contains the URL for // - a StreamHandle instance for the Stream. The handle contains the URL for
// reading the Stream etc. // reading the Stream etc.
// The Stream's origin will be set to |origin|. // The Stream's origin will be set to |origin|.
//
// If the stream will be rendered in a BrowserPlugin, |payload| will contain
// the data that should be given to the old ResourceHandler to forward to the
// renderer process.
virtual bool ShouldInterceptResourceAsStream( virtual bool ShouldInterceptResourceAsStream(
content::ResourceContext* resource_context, net::URLRequest* request,
const GURL& url,
const std::string& mime_type, const std::string& mime_type,
GURL* origin, GURL* origin,
std::string* target_id); std::string* payload);
// Informs the delegate that a Stream was created. |target_id| will be filled // Informs the delegate that a Stream was created. The Stream can be read from
// with the parameter returned by ShouldInterceptResourceAsStream(). The // the blob URL of the Stream, but can only be read once.
// Stream can be read from the blob URL of the Stream, but can only be read
// once.
virtual void OnStreamCreated( virtual void OnStreamCreated(
content::ResourceContext* resource_context, net::URLRequest* request,
int render_process_id, scoped_ptr<content::StreamHandle> stream);
int render_view_id,
const std::string& target_id,
scoped_ptr<StreamHandle> stream,
int64 expected_content_size);
// Informs the delegate that a response has started. // Informs the delegate that a response has started.
virtual void OnResponseStarted( virtual void OnResponseStarted(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment