зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1595601: Add documentation for the external handler service. r=Gijs
Differential Revision: https://phabricator.services.mozilla.com/D52578 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
9a429b7cad
Коммит
b4b8eaa607
|
@ -12,6 +12,7 @@ categories:
|
|||
- modules/libpref
|
||||
- remote
|
||||
- services/common/services
|
||||
- uriloader
|
||||
build_doc:
|
||||
- mach
|
||||
- tools/try
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
File Handling
|
||||
=============
|
||||
|
||||
This covers how files requested for display are loaded.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
uriloader
|
||||
exthandler/docs/index
|
|
@ -0,0 +1,45 @@
|
|||
.. _uri_loader_service:
|
||||
URI Loader Service
|
||||
==================
|
||||
|
||||
As its name might suggest the URI loader service is responsible for loading URIs
|
||||
but it is also responsible for deciding how to handle that content, whether to
|
||||
display it as part of a DOM window or hand it off to something else.
|
||||
|
||||
It is generally used when loading content for display to the user, normally from
|
||||
``nsDocShell`` for display as a webpage or ``nsObjectLoadingContent`` for display inside
|
||||
a webpage's ``<object>`` tag. The normal entrypoint is throught ``nsIURILoader::OpenURI``.
|
||||
|
||||
The URI loader starts the load and registers an ``nsDocumentOpenInfo`` as a stream
|
||||
listener for the content. Once headers have been received `DispatchContent <https://searchfox.org/mozilla-central/search?q=nsDocumentOpenInfo%3A%3ADispatchContent&path=>`_
|
||||
then decides what to do with the content as it may need to be handled by something
|
||||
other than the caller. It uses a few criteria to decide this including:
|
||||
|
||||
* Content-Type header.
|
||||
* Content-Disposition header.
|
||||
* Load flags.
|
||||
|
||||
Part of this handling may include running the content through a registered stream
|
||||
converter to convert the content type from one to another. This is done through
|
||||
the `stream converter service <https://searchfox.org/mozilla-central/source/netwerk/streamconv>`_.
|
||||
When this happens a new ``nsDocumentOpenInfo`` is created to handle the new content
|
||||
in the same way as the current content.
|
||||
|
||||
The rough flow goes as follows (though note that this can vary depending on the
|
||||
flags passed to the loader service):
|
||||
|
||||
1. The caller may provide an ``nsIURIContentListener`` which can offer to handle
|
||||
the content type or a content type that we can convert the original type to).
|
||||
If so the load is passed off to the listener.
|
||||
2. Global ``nsIURIContentListener``s can be registered with the URI loader service
|
||||
so these are consulted in the same way.
|
||||
3. Global ``nsIURIContentListener`s can be registered in the category manager
|
||||
so these are consulted in the same way.
|
||||
4. Global ``nsIContentHandler``s can be registered. If one agrees to hande the
|
||||
content then the load is handed over to it.
|
||||
5. We attempt to convert the content to a different type.
|
||||
6. The load is handed over to the :ref:`External Helper App Service <external_helper_app_service>`.
|
||||
|
||||
For the most part the process ends at step 1 because nsDocShell passes a ``nsDSURIContentListener``
|
||||
for the ``nsIURIContentListener`` consulted first and it accepts most of the
|
||||
`web content types <https://searchfox.org/mozilla-central/search?q=CONTENTDLF_CATEGORIES&redirect=false>`_.
|
|
@ -0,0 +1,74 @@
|
|||
.. _external_helper_app_service:
|
||||
External Helper App Service
|
||||
===========================
|
||||
|
||||
The external helper app service is responsible for deciding how to handle an
|
||||
attempt to load come content that cannot be loaded by the browser itself.
|
||||
|
||||
Part of this involves using the Handler Service which manages the users
|
||||
preferences for what to do by default with different content.
|
||||
|
||||
When a Link is Clicked
|
||||
----------------------
|
||||
|
||||
When a link in a page is clicked (or a form submitted) ``nsDocShell`` tests
|
||||
whether the target protocol can be loaded by the browser itself, this is based
|
||||
on the preferences under ``network.protocol-handler``. When the browser cannot
|
||||
load the protocol it calls into ``nsExternalHelperAppService::LoadURI``.
|
||||
|
||||
Some validation checks are performed but ultimateley we look for a registered
|
||||
protocol handler. First the OS is queried for an app registration for the
|
||||
protocol and then the handler server is asked to fill in any user settings from
|
||||
the internal database. If there were no settings from the handler service then
|
||||
some defaults are applied in ``nsExternalHelperAppService::SetProtocolHandlerDefaults``.
|
||||
|
||||
If there is a default handler app chosen and the settings say to use it without
|
||||
asking then that happens. If not a dialog s shown asking the user what they
|
||||
want to do.
|
||||
|
||||
During a Load
|
||||
-------------
|
||||
|
||||
When content is already being loaded the :ref:`URI Loader Service <uri_loader_service>`
|
||||
determines whether the browser can handle the content or not. If not it calls
|
||||
into the external helper app server through ``nsExternalHelperAppService::DoContent``.
|
||||
|
||||
The content type of the loading content is retrieved from the channel. A file
|
||||
extension is also generated using the Content-Disposition header or if the load
|
||||
is not a HTTP POST request the file extension is generated from the requested URL.
|
||||
|
||||
We then query the MIME Service for an nsIMIMEInfo to find information about
|
||||
apps that can handle the content type or file extension based on OS and user
|
||||
settings, :ref:`see below <mime_service>` for further details. The result is
|
||||
used to create a ``nsExternalAppHandler`` which is then used as a stream listener
|
||||
for the content.
|
||||
|
||||
The MIME info object contains settings that control whether to prompt the user
|
||||
before doing anything and what the default action should be. If we need to ask
|
||||
the user then a dialog is shown offering to let users cancel the load, save the
|
||||
content to disk or send it to a registered application handler.
|
||||
|
||||
Assuming the load isn't canceled the content is streamed to disk using a background
|
||||
file saver with a target ``nsITransfer``. The ``nsITransfer`` is responsible for
|
||||
showing the download in the UI.
|
||||
|
||||
If the user opted to open the file with an application then once the transfer is
|
||||
complete then ``nsIMIMEInfo::LaunchWithFile`` is used to
|
||||
`launch the application <https://searchfox.org/mozilla-central/search?q=nsIMIMEInfo%3A%3ALaunchWithFile&path=>`_.
|
||||
|
||||
.. _mime_service:
|
||||
MIME Service
|
||||
------------
|
||||
|
||||
The MIME service is responsible for getting an ``nsIMIMEInfo`` object for a
|
||||
content type or file extension:
|
||||
|
||||
1. Fills out an ``nsIMIMEInfo`` based on OS provided information. This is platform
|
||||
specific but should try to find the default application registered to handle
|
||||
the content.
|
||||
2. Ask the handler service to fill out the ``nsIMIMEInfo`` with information held
|
||||
in browser settings. This will not overwrite a any application found from
|
||||
the OS.
|
||||
3. If one has not been found already then try to find a type description from
|
||||
a `lookup table <https://searchfox.org/mozilla-central/search?q=extraMimeEntries[]&path=>`_
|
||||
or just by appending " File" to the file extension.
|
|
@ -4,6 +4,8 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
SPHINX_TREES['docs'] = 'docs'
|
||||
|
||||
TEST_DIRS += ['tests']
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
SPHINX_TREES['/uriloader'] = 'docs'
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Firefox', 'File Handling')
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче