summaryrefslogtreecommitdiffstats
path: root/netwerk/protocol/res/ExtensionProtocolHandler.h
diff options
context:
space:
mode:
Diffstat (limited to 'netwerk/protocol/res/ExtensionProtocolHandler.h')
-rw-r--r--netwerk/protocol/res/ExtensionProtocolHandler.h236
1 files changed, 236 insertions, 0 deletions
diff --git a/netwerk/protocol/res/ExtensionProtocolHandler.h b/netwerk/protocol/res/ExtensionProtocolHandler.h
new file mode 100644
index 0000000000..0824d7dd99
--- /dev/null
+++ b/netwerk/protocol/res/ExtensionProtocolHandler.h
@@ -0,0 +1,236 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+#ifndef ExtensionProtocolHandler_h___
+#define ExtensionProtocolHandler_h___
+
+#include "mozilla/net/NeckoParent.h"
+#include "mozilla/LazyIdleThread.h"
+#include "mozilla/Result.h"
+#include "SubstitutingProtocolHandler.h"
+
+namespace mozilla {
+namespace net {
+
+class ExtensionStreamGetter;
+
+class ExtensionProtocolHandler final
+ : public nsISubstitutingProtocolHandler,
+ public nsIProtocolHandlerWithDynamicFlags,
+ public SubstitutingProtocolHandler,
+ public nsSupportsWeakReference {
+ public:
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_NSIPROTOCOLHANDLERWITHDYNAMICFLAGS
+ NS_FORWARD_NSIPROTOCOLHANDLER(SubstitutingProtocolHandler::)
+ NS_FORWARD_NSISUBSTITUTINGPROTOCOLHANDLER(SubstitutingProtocolHandler::)
+
+ static already_AddRefed<ExtensionProtocolHandler> GetSingleton();
+
+ /**
+ * To be called in the parent process to obtain an input stream for a
+ * a web accessible resource from an unpacked WebExtension dir.
+ *
+ * @param aChildURI a moz-extension URI sent from the child that refers
+ * to a web accessible resource file in an enabled unpacked extension
+ * @param aTerminateSender out param set to true when the params are invalid
+ * and indicate the child should be terminated. If |aChildURI| is
+ * not a moz-extension URI, the child is in an invalid state and
+ * should be terminated.
+ * @return NS_OK with |aTerminateSender| set to false on success. On
+ * failure, returns an error and sets |aTerminateSender| to indicate
+ * whether or not the child process should be terminated.
+ * A moz-extension URI from the child that doesn't resolve to a
+ * resource file within the extension could be the result of a bug
+ * in the extension and doesn't result in |aTerminateSender| being
+ * set to true.
+ */
+ Result<nsCOMPtr<nsIInputStream>, nsresult> NewStream(nsIURI* aChildURI,
+ bool* aTerminateSender);
+
+ /**
+ * To be called in the parent process to obtain a file descriptor for an
+ * enabled WebExtension JAR file.
+ *
+ * @param aChildURI a moz-extension URI sent from the child that refers
+ * to a web accessible resource file in an enabled unpacked extension
+ * @param aTerminateSender out param set to true when the params are invalid
+ * and indicate the child should be terminated. If |aChildURI| is
+ * not a moz-extension URI, the child is in an invalid state and
+ * should be terminated.
+ * @param aPromise a promise that will be resolved asynchronously when the
+ * file descriptor is available.
+ * @return NS_OK with |aTerminateSender| set to false on success. On
+ * failure, returns an error and sets |aTerminateSender| to indicate
+ * whether or not the child process should be terminated.
+ * A moz-extension URI from the child that doesn't resolve to an
+ * enabled WebExtension JAR could be the result of a bug in the
+ * extension and doesn't result in |aTerminateSender| being
+ * set to true.
+ */
+ Result<Ok, nsresult> NewFD(nsIURI* aChildURI, bool* aTerminateSender,
+ NeckoParent::GetExtensionFDResolver& aResolve);
+
+ protected:
+ ~ExtensionProtocolHandler() = default;
+
+ private:
+ explicit ExtensionProtocolHandler();
+
+ [[nodiscard]] bool ResolveSpecialCases(const nsACString& aHost,
+ const nsACString& aPath,
+ const nsACString& aPathname,
+ nsACString& aResult) override;
+
+ // |result| is an inout param. On entry to this function, *result
+ // is expected to be non-null and already addrefed. This function
+ // may release the object stored in *result on entry and write
+ // a new pointer to an already addrefed channel to *result.
+ [[nodiscard]] virtual nsresult SubstituteChannel(
+ nsIURI* uri, nsILoadInfo* aLoadInfo, nsIChannel** result) override;
+
+ /**
+ * For moz-extension URI's that resolve to file or JAR URI's, replaces
+ * the provided channel with a channel that will proxy the load to the
+ * parent process. For moz-extension URI's that resolve to other types
+ * of URI's (not file or JAR), the provide channel is not replaced and
+ * NS_OK is returned.
+ *
+ * @param aURI the moz-extension URI
+ * @param aLoadInfo the loadinfo for the request
+ * @param aRetVal in/out channel param referring to the channel that
+ * might need to be substituted with a remote channel.
+ * @return NS_OK if the channel does not need to be substituted or
+ * or the replacement channel was created successfully.
+ * Otherwise returns an error.
+ */
+ Result<Ok, nsresult> SubstituteRemoteChannel(nsIURI* aURI,
+ nsILoadInfo* aLoadInfo,
+ nsIChannel** aRetVal);
+
+ /**
+ * Replaces a file channel with a remote file channel for loading a
+ * web accessible resource for an unpacked extension from the parent.
+ *
+ * @param aURI the moz-extension URI
+ * @param aLoadInfo the loadinfo for the request
+ * @param aResolvedFileSpec the resolved URI spec for the file.
+ * @param aRetVal in/out param referring to the new remote channel.
+ * The reference to the input param file channel is dropped and
+ * replaced with a reference to a new channel that remotes
+ * the file access. The new channel encapsulates a request to
+ * the parent for an IPCStream for the file.
+ */
+ void SubstituteRemoteFileChannel(nsIURI* aURI, nsILoadInfo* aLoadinfo,
+ nsACString& aResolvedFileSpec,
+ nsIChannel** aRetVal);
+
+ /**
+ * Replaces a JAR channel with a remote JAR channel for loading a
+ * an extension JAR file from the parent.
+ *
+ * @param aURI the moz-extension URI
+ * @param aLoadInfo the loadinfo for the request
+ * @param aResolvedFileSpec the resolved URI spec for the file.
+ * @param aRetVal in/out param referring to the new remote channel.
+ * The input param JAR channel is replaced with a new channel
+ * that remotes the JAR file access. The new channel encapsulates
+ * a request to the parent for the JAR file FD.
+ */
+ Result<Ok, nsresult> SubstituteRemoteJarChannel(nsIURI* aURI,
+ nsILoadInfo* aLoadinfo,
+ nsACString& aResolvedSpec,
+ nsIChannel** aRetVal);
+
+ /**
+ * Sets the aResult outparam to true if this unpacked extension load of
+ * a resource that is outside the extension dir should be allowed. This
+ * is only allowed for system extensions on Mac and Linux dev builds.
+ *
+ * @param aExtensionDir the extension directory. Argument must be an
+ * nsIFile for which Normalize() has already been called.
+ * @param aRequestedFile the requested web-accessible resource file. Argument
+ * must be an nsIFile for which Normalize() has already been called.
+ */
+ Result<bool, nsresult> AllowExternalResource(nsIFile* aExtensionDir,
+ nsIFile* aRequestedFile);
+
+ // Set the channel's content type using the provided URI's type
+ static void SetContentType(nsIURI* aURI, nsIChannel* aChannel);
+
+ // Gets a SimpleChannel that wraps the provided ExtensionStreamGetter
+ static void NewSimpleChannel(nsIURI* aURI, nsILoadInfo* aLoadinfo,
+ ExtensionStreamGetter* aStreamGetter,
+ nsIChannel** aRetVal);
+
+ // Gets a SimpleChannel that wraps the provided channel
+ static void NewSimpleChannel(nsIURI* aURI, nsILoadInfo* aLoadinfo,
+ nsIChannel* aChannel, nsIChannel** aRetVal);
+
+#if defined(XP_MACOSX)
+ /**
+ * Sets the aResult outparam to true if we are a developer build with the
+ * repo dir environment variable set and the requested file resides in the
+ * repo dir. Developer builds may load system extensions with web-accessible
+ * resources that are symlinks to files in the repo dir. This method is for
+ * checking if an unpacked resource requested by the child is from the repo.
+ * The requested file must be already Normalized(). Only compile this for
+ * Mac because the repo dir isn't always available on Linux.
+ *
+ * @param aRequestedFile the requested web-accessible resource file. Argument
+ * must be an nsIFile for which Normalize() has already been called.
+ */
+ Result<bool, nsresult> DevRepoContains(nsIFile* aRequestedFile);
+
+ // On development builds, this points to development repo. Lazily set.
+ nsCOMPtr<nsIFile> mDevRepo;
+
+ // Set to true once we've already tried to load the dev repo path,
+ // allowing for lazy initialization of |mDevRepo|.
+ bool mAlreadyCheckedDevRepo{false};
+#endif /* XP_MACOSX */
+
+#if !defined(XP_WIN)
+ /**
+ * Sets the aResult outparam to true if we are a developer build and the
+ * provided directory is within the NS_GRE_DIR directory. Developer builds
+ * may load system extensions with web-accessible resources that are symlinks
+ * to files outside of the extension dir to the repo dir. This method is for
+ * checking if an extension directory is within NS_GRE_DIR. In that case, we
+ * consider the extension a system extension and allow it to use symlinks to
+ * resources outside of the extension dir. This exception is only applied
+ * to loads for unpacked extensions in unpackaged developer builds.
+ * The requested dir must be already Normalized().
+ *
+ * @param aExtensionDir the extension directory. Argument must be an
+ * nsIFile for which Normalize() has already been called.
+ */
+ Result<bool, nsresult> AppDirContains(nsIFile* aExtensionDir);
+
+ // On development builds, cache the NS_GRE_DIR repo. Lazily set.
+ nsCOMPtr<nsIFile> mAppDir;
+
+ // Set to true once we've already read the AppDir, allowing for lazy
+ // initialization of |mAppDir|.
+ bool mAlreadyCheckedAppDir{false};
+#endif /* !defined(XP_WIN) */
+
+ // Used for opening JAR files off the main thread when we just need to
+ // obtain a file descriptor to send back to the child.
+ RefPtr<mozilla::LazyIdleThread> mFileOpenerThread;
+
+ // To allow parent IPDL actors to invoke methods on this handler when
+ // handling moz-extension requests from the child.
+ static StaticRefPtr<ExtensionProtocolHandler> sSingleton;
+
+ // Set to true when this instance of the handler must proxy loads of
+ // extension web-accessible resources to the parent process.
+ bool mUseRemoteFileChannels;
+};
+
+} // namespace net
+} // namespace mozilla
+
+#endif /* ExtensionProtocolHandler_h___ */