Index: chrome/browser/extensions/extension_protocols.cc |
diff --git a/chrome/browser/extensions/extension_protocols.cc b/chrome/browser/extensions/extension_protocols.cc |
index b0da9b0321838ef93d5fb5c7c1345af550ca7917..b65e3e24389d010302af1aa7b7db19b4a3a787a0 100644 |
--- a/chrome/browser/extensions/extension_protocols.cc |
+++ b/chrome/browser/extensions/extension_protocols.cc |
@@ -26,6 +26,7 @@ |
#include "chrome/common/extensions/extension_file_util.h" |
#include "chrome/common/extensions/incognito_handler.h" |
#include "chrome/common/extensions/manifest_handlers/icons_handler.h" |
+#include "chrome/common/extensions/manifest_handlers/shared_module_info.h" |
#include "chrome/common/extensions/manifest_url_handler.h" |
#include "chrome/common/extensions/web_accessible_resources_handler.h" |
#include "chrome/common/url_constants.h" |
@@ -45,6 +46,7 @@ |
using content::ResourceRequestInfo; |
using extensions::Extension; |
+using extensions::SharedModuleInfo; |
namespace { |
@@ -205,14 +207,13 @@ class URLRequestExtensionJob : public net::URLRequestFileJob { |
net::NetworkDelegate* network_delegate, |
const std::string& extension_id, |
const base::FilePath& directory_path, |
+ const base::FilePath& relative_path, |
const std::string& content_security_policy, |
bool send_cors_header) |
: net::URLRequestFileJob(request, network_delegate, base::FilePath()), |
// TODO(tc): Move all of these files into resources.pak so we don't break |
// when updating on Linux. |
- resource_(extension_id, directory_path, |
- extension_file_util::ExtensionURLToRelativeFilePath( |
- request->url())), |
+ resource_(extension_id, directory_path, relative_path), |
weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
response_info_.headers = BuildHttpHeaders(content_security_policy, |
send_cors_header); |
@@ -388,7 +389,7 @@ net::URLRequestJob* |
ExtensionProtocolHandler::MaybeCreateJob( |
net::URLRequest* request, net::NetworkDelegate* network_delegate) const { |
// chrome-extension://extension-id/resource/path.js |
- const std::string& extension_id = request->url().host(); |
+ std::string extension_id = request->url().host(); |
const Extension* extension = |
extension_info_map_->extensions().GetByID(extension_id); |
@@ -462,10 +463,50 @@ ExtensionProtocolHandler::MaybeCreateJob( |
} |
} |
+ relative_path = |
+ extension_file_util::ExtensionURLToRelativeFilePath(request->url()); |
+ |
+ if (SharedModuleInfo::IsImportedPath(path)) { |
+ std::string new_extension_id; |
+ std::string new_relative_path; |
+ SharedModuleInfo::ParseImportedPath(path, &new_extension_id, |
+ &new_relative_path); |
+ const Extension* new_extension = |
+ extension_info_map_->extensions().GetByID(new_extension_id); |
+ |
+ bool first_party_in_import = false; |
+ // NB: This first_party_for_cookies call is not for security, it is only |
+ // used so an exported extension can limit the visible surface to the |
+ // extension that imports it, more or less constituting its API. |
+ const std::string& first_party_path = |
+ request->first_party_for_cookies().path(); |
+ if (SharedModuleInfo::IsImportedPath(first_party_path)) { |
+ std::string first_party_id; |
+ std::string dummy; |
+ SharedModuleInfo::ParseImportedPath(first_party_path, &first_party_id, |
+ &dummy); |
+ if (first_party_id == new_extension_id) { |
+ first_party_in_import = true; |
+ } |
+ } |
+ |
+ if (SharedModuleInfo::ImportsExtensionById(extension, new_extension_id) && |
+ new_extension && |
+ (first_party_in_import || |
+ SharedModuleInfo::IsExportAllowed(new_extension, new_relative_path))) { |
+ directory_path = new_extension->path(); |
+ extension_id = new_extension_id; |
+ relative_path = base::FilePath(new_relative_path); |
+ } else { |
+ return NULL; |
+ } |
+ } |
+ |
return new URLRequestExtensionJob(request, |
network_delegate, |
extension_id, |
directory_path, |
+ relative_path, |
content_security_policy, |
send_cors_header); |
} |