The custom handlers component provides a way to register custom protocol handlers for specific URL schemes. This is part of the implementation of the System state and capabilities defined in the HTML spec. Specifically, it implements the interface NavigatorContentUtils from which the Navigator object derives.
These handlers may be used to translate the http request's URL so that it is redirected to the appropriated service (e.g. email, apps) or a different http(s) site.
All the component's code is intended to be run by the Browser process, in the UI thread.
The component addresses the security and privacy considerations described in the HTML spec.
A protocol handler is only valid if it passes all protocol handler parameters normalization steps. These security and privacy checks are:
The handler's url must be HTTP or HTTPS; ‘chrome-extension’ schemes may be allowed depending on the security level
.
Ensure the handler's url fulfills the potentially trustworthy criteria defined in the Secure Context spec. This logic is implemented by the IsUrlPotentiallyTrustworthy
in the //services/network
module.
The protocol being handled must be on the safelisted scheme described in the spec. The IsValidCustomHandlerScheme
function in blink
implements this check.
Chromium defines a hierarchy of security levels to relax the restrictions imposed by the spec and allow the implementation of certain features. Being strict
the default behavior and the one defined in the spec, there are levels for allowing untrusted-origins and schemes not listed in the mentioned safelist defined in the spec.
For instance, on order to make possible for extensions to register their own pages as handlers, the chrome-extension
scheme is also allowed when security level is blink::ProtocolHandlerSecurityLevel::kExtensionFeatures
.
It's also worth mentioned that Chromium defines its own kProtocolSafelist
that includes some additional decentralized schemes that are not being explicitly defined in the mentioned.
Browser +--------------------------------------------------------------------+ | //components/custom_handlers | | | | +------------------------------------------+ | | | RegisterProtocolHandlerPermissionRequest | | | +------------------------------------------+ | | / \ | | +-----------------+ | | | | ProtocolHandler | <-------------+ | | | +-----------------+ | | | | / \ | | | | | | | | | | | | | | | | | | | +-------------------------+ | | | | | ProtocolHandlerRegistry | <--------+ | | | +-------------------------+ | | | | / \ | | | | | | | | | | | | | +--------------------------------------------------------------------+ | | | | | | +--------------------------------------------------------------------+ | //chrome | | | | | | | | | | +--------------------------------+ | +---------+ | +--------------------------+ | | ProtocolHandlerRegistryFactory | <----- | Browser | ----------------> | PermissionRequestManager | | +--------------------------------+ +---------+ | +--------------------------+ | / \ | | | | +--------------------------------------------------------------------+ | +--------------------------------------------------------------------+ | //content | | | | | | +-----------------+ +---------------------+ | | | WebContentsImpl | ---------> | WebContentsDelegate | | | +-----------------+ +---------------------+ | | / \ | | | | | | | | | | | +-------------------------+ +---------------------+ | | | RenderFrameHostDelegate | <--------- | RenderFrameHostImpl | | | +-------------------------+ +---------------------+ | | | | | | | +--------------------------------------------------------------------+ | | +--------------------------------------------------------------------------------------------------------+ Renderer | | +--------------------------------------------------------------------+ | //blink | | | V | | +-----------------------+ +------------------------------+ | | | NavigatorContentUtils | ----> | mojom::blink::LocalFrameHost | | | +-----------------------+ +------------------------------+ | | | +--------------------------------------------------------------------+
Here is a summary of the core responsibilities of the classes and interfaces:
It‘s the class responsible of the security and privacy validation mentioned before, and eventually of the http request’s URL translation, using the protocol handler's url spec.
This class is implemented as a KeyedService
which means it is attached to a BrowserContext
.
The registry holds different kind of protocol handlers lists, depending on their source during the registration: user or internal policies. The registry also provides an API to selectively ignore protocol handlers, which are managed in an independent list.
There are also some predefined-handlers, which are automatically registered by the registry factory during the service's initialization.
Finally there is a list of the default handlers for each protocol.
All the protocol handlers managed by the registry are stored in the user preference storage, based on the user profile (the Browser Context) used to initialize the keyed service. This makes possible to guarantee the persistence of the protocol handlers state.
It implements the blink's blink::URLLoaderThrottle
interface to manage the http request. It holds a pointer to a ProtocolHandlerRegistry instance to performs the URL translation if there is a custom handler for the protocol used for the request.
RegisterProtocolHandlerPermissionRequest
It implements the PermissionRequest
interface to manage user authorization for the requests issued by the Navigator object's registerProtocolHandler()
method. An instance of this class holds a pointer to a ProtocolHandlerRegistry instance and a ProtocolHandler reference to be registered.
It performs the handler registration of granted, or adds it to the ignored list if denied.