Commit a59e1cce authored by Matt Falkenhagen's avatar Matt Falkenhagen Committed by Commit Bot

service worker: Add extensions check when ServiceWorkerOnUI is on.

The thread ServiceWorkerContextCore lives on (the "core thread")
will move from the IO thread to the UI thread. This CL makes the
check for extensions work when the feature is enabled.

Bug: 824858
Change-Id: I6f9054bc3d77b8261b7e832e97f6cc71e2b3013d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1763651Reviewed-by: default avatarIstiaque Ahmed <lazyboy@chromium.org>
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#689724}
parent 4b395568
...@@ -2342,7 +2342,7 @@ bool ChromeContentBrowserClient::AllowServiceWorkerOnIO( ...@@ -2342,7 +2342,7 @@ bool ChromeContentBrowserClient::AllowServiceWorkerOnIO(
// to the TabSpecificContentSettings, since the service worker is blocked // to the TabSpecificContentSettings, since the service worker is blocked
// because of the extension, rather than because of the user's content // because of the extension, rather than because of the user's content
// settings. // settings.
if (!ChromeContentBrowserClientExtensionsPart::AllowServiceWorker( if (!ChromeContentBrowserClientExtensionsPart::AllowServiceWorkerOnIO(
scope, first_party_url, script_url, context)) { scope, first_party_url, script_url, context)) {
return false; return false;
} }
...@@ -2384,9 +2384,16 @@ bool ChromeContentBrowserClient::AllowServiceWorkerOnUI( ...@@ -2384,9 +2384,16 @@ bool ChromeContentBrowserClient::AllowServiceWorkerOnUI(
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
#if BUILDFLAG(ENABLE_EXTENSIONS) #if BUILDFLAG(ENABLE_EXTENSIONS)
// TODO(crbug.com/824858): Implement the extensions service worker check on // Check if this is an extension-related service worker, and, if so, if it's
// the UI thread. // allowed (this can return false if, e.g., the extension is disabled).
return false; // If it's not allowed, return immediately. We deliberately do *not* report
// to the TabSpecificContentSettings, since the service worker is blocked
// because of the extension, rather than because of the user's content
// settings.
if (!ChromeContentBrowserClientExtensionsPart::AllowServiceWorkerOnUI(
scope, first_party_url, script_url, context)) {
return false;
}
#endif #endif
Profile* profile = Profile::FromBrowserContext(context); Profile* profile = Profile::FromBrowserContext(context);
......
...@@ -165,6 +165,37 @@ bool HasEffectiveUrl(content::BrowserContext* browser_context, ...@@ -165,6 +165,37 @@ bool HasEffectiveUrl(content::BrowserContext* browser_context,
Profile::FromBrowserContext(browser_context), url) != url; Profile::FromBrowserContext(browser_context), url) != url;
} }
bool AllowServiceWorker(const GURL& scope,
const GURL& script_url,
const Extension* extension) {
// Don't allow a service worker for an extension url with no extension (this
// could happen in the case of, e.g., an unloaded extension).
if (!extension)
return false;
// If an extension doesn't have a service worker-based background script, it
// can register a service worker at any scope.
if (!extensions::BackgroundInfo::IsServiceWorkerBased(extension))
return true;
// If the script_url parameter is an empty string, allow it. The
// infrastructure will call this function at times when the script url is
// unknown, but it is always known at registration, so this is OK.
if (script_url.is_empty())
return true;
// An extension with a service worked-based background script can register a
// service worker at any scope other than the root scope.
if (scope != extension->url())
return true;
// If an extension is service-worker based, only the script specified in the
// manifest can be registered at the root scope.
const std::string& sw_script =
extensions::BackgroundInfo::GetBackgroundServiceWorkerScript(extension);
return script_url == extension->GetResourceURL(sw_script);
}
} // namespace } // namespace
ChromeContentBrowserClientExtensionsPart:: ChromeContentBrowserClientExtensionsPart::
...@@ -531,7 +562,7 @@ bool ChromeContentBrowserClientExtensionsPart:: ...@@ -531,7 +562,7 @@ bool ChromeContentBrowserClientExtensionsPart::
} }
// static // static
bool ChromeContentBrowserClientExtensionsPart::AllowServiceWorker( bool ChromeContentBrowserClientExtensionsPart::AllowServiceWorkerOnIO(
const GURL& scope, const GURL& scope,
const GURL& first_party_url, const GURL& first_party_url,
const GURL& script_url, const GURL& script_url,
...@@ -544,32 +575,23 @@ bool ChromeContentBrowserClientExtensionsPart::AllowServiceWorker( ...@@ -544,32 +575,23 @@ bool ChromeContentBrowserClientExtensionsPart::AllowServiceWorker(
InfoMap* extension_info_map = io_data->GetExtensionInfoMap(); InfoMap* extension_info_map = io_data->GetExtensionInfoMap();
const Extension* extension = const Extension* extension =
extension_info_map->extensions().GetExtensionOrAppByURL(first_party_url); extension_info_map->extensions().GetExtensionOrAppByURL(first_party_url);
// Don't allow a service worker for an extension url with no extension (this return AllowServiceWorker(scope, script_url, extension);
// could happen in the case of, e.g., an unloaded extension). }
if (!extension)
return false;
// If an extension doesn't have a service worker-based background script, it
// can register a service worker at any scope.
if (!extensions::BackgroundInfo::IsServiceWorkerBased(extension))
return true;
// If the script_url parameter is an empty string, allow it. The
// infrastructure will call this function at times when the script url is
// unknown, but it is always known at registration, so this is OK.
if (script_url.is_empty())
return true;
// An extension with a service worked-based background script can register a // static
// service worker at any scope other than the root scope. bool ChromeContentBrowserClientExtensionsPart::AllowServiceWorkerOnUI(
if (scope != extension->url()) const GURL& scope,
const GURL& first_party_url,
const GURL& script_url,
content::BrowserContext* context) {
// We only care about extension urls.
if (!first_party_url.SchemeIs(kExtensionScheme))
return true; return true;
// If an extension is service-worker based, only the script specified in the const Extension* extension = ExtensionRegistry::Get(context)
// manifest can be registered at the root scope. ->enabled_extensions()
const std::string& sw_script = .GetExtensionOrAppByURL(first_party_url);
extensions::BackgroundInfo::GetBackgroundServiceWorkerScript(extension); return AllowServiceWorker(scope, script_url, extension);
return script_url == extension->GetResourceURL(sw_script);
} }
// static // static
......
...@@ -68,10 +68,15 @@ class ChromeContentBrowserClientExtensionsPart ...@@ -68,10 +68,15 @@ class ChromeContentBrowserClientExtensionsPart
content::SiteInstance* site_instance, content::SiteInstance* site_instance,
const GURL& current_url, const GURL& current_url,
const GURL& new_url); const GURL& new_url);
static bool AllowServiceWorker(const GURL& scope, // TODO(crbug.com/824858): Remove the OnIO method.
const GURL& first_party_url, static bool AllowServiceWorkerOnIO(const GURL& scope,
const GURL& script_url, const GURL& first_party_url,
content::ResourceContext* context); const GURL& script_url,
content::ResourceContext* context);
static bool AllowServiceWorkerOnUI(const GURL& scope,
const GURL& first_party_url,
const GURL& script_url,
content::BrowserContext* context);
static void OverrideNavigationParams( static void OverrideNavigationParams(
content::SiteInstance* site_instance, content::SiteInstance* site_instance,
ui::PageTransition* transition, ui::PageTransition* transition,
......
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