1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef ExtensionProtocolHandler_h___
7 #define ExtensionProtocolHandler_h___
9 #include "mozilla/net/NeckoParent.h"
10 #include "mozilla/LazyIdleThread.h"
11 #include "mozilla/Result.h"
12 #include "SubstitutingProtocolHandler.h"
17 class ExtensionStreamGetter
;
19 class ExtensionProtocolHandler final
: public nsISubstitutingProtocolHandler
,
20 public SubstitutingProtocolHandler
,
21 public nsSupportsWeakReference
{
23 NS_DECL_ISUPPORTS_INHERITED
24 NS_FORWARD_NSIPROTOCOLHANDLER(SubstitutingProtocolHandler::)
25 NS_FORWARD_NSISUBSTITUTINGPROTOCOLHANDLER(SubstitutingProtocolHandler::)
27 static already_AddRefed
<ExtensionProtocolHandler
> GetSingleton();
30 * To be called in the parent process to obtain an input stream for a
31 * a web accessible resource from an unpacked WebExtension dir.
33 * @param aChildURI a moz-extension URI sent from the child that refers
34 * to a web accessible resource file in an enabled unpacked extension
35 * @param aTerminateSender out param set to true when the params are invalid
36 * and indicate the child should be terminated. If |aChildURI| is
37 * not a moz-extension URI, the child is in an invalid state and
38 * should be terminated.
39 * @return NS_OK with |aTerminateSender| set to false on success. On
40 * failure, returns an error and sets |aTerminateSender| to indicate
41 * whether or not the child process should be terminated.
42 * A moz-extension URI from the child that doesn't resolve to a
43 * resource file within the extension could be the result of a bug
44 * in the extension and doesn't result in |aTerminateSender| being
47 Result
<nsCOMPtr
<nsIInputStream
>, nsresult
> NewStream(nsIURI
* aChildURI
,
48 bool* aTerminateSender
);
51 * To be called in the parent process to obtain a file descriptor for an
52 * enabled WebExtension JAR file.
54 * @param aChildURI a moz-extension URI sent from the child that refers
55 * to a web accessible resource file in an enabled unpacked extension
56 * @param aTerminateSender out param set to true when the params are invalid
57 * and indicate the child should be terminated. If |aChildURI| is
58 * not a moz-extension URI, the child is in an invalid state and
59 * should be terminated.
60 * @param aPromise a promise that will be resolved asynchronously when the
61 * file descriptor is available.
62 * @return NS_OK with |aTerminateSender| set to false on success. On
63 * failure, returns an error and sets |aTerminateSender| to indicate
64 * whether or not the child process should be terminated.
65 * A moz-extension URI from the child that doesn't resolve to an
66 * enabled WebExtension JAR could be the result of a bug in the
67 * extension and doesn't result in |aTerminateSender| being
70 Result
<Ok
, nsresult
> NewFD(nsIURI
* aChildURI
, bool* aTerminateSender
,
71 NeckoParent::GetExtensionFDResolver
& aResolve
);
74 ~ExtensionProtocolHandler() = default;
77 explicit ExtensionProtocolHandler();
79 [[nodiscard
]] bool ResolveSpecialCases(const nsACString
& aHost
,
80 const nsACString
& aPath
,
81 const nsACString
& aPathname
,
82 nsACString
& aResult
) override
;
84 // |result| is an inout param. On entry to this function, *result
85 // is expected to be non-null and already addrefed. This function
86 // may release the object stored in *result on entry and write
87 // a new pointer to an already addrefed channel to *result.
88 [[nodiscard
]] virtual nsresult
SubstituteChannel(
89 nsIURI
* uri
, nsILoadInfo
* aLoadInfo
, nsIChannel
** result
) override
;
92 * For moz-extension URI's that resolve to file or JAR URI's, replaces
93 * the provided channel with a channel that will proxy the load to the
94 * parent process. For moz-extension URI's that resolve to other types
95 * of URI's (not file or JAR), the provide channel is not replaced and
98 * @param aURI the moz-extension URI
99 * @param aLoadInfo the loadinfo for the request
100 * @param aRetVal in/out channel param referring to the channel that
101 * might need to be substituted with a remote channel.
102 * @return NS_OK if the channel does not need to be substituted or
103 * or the replacement channel was created successfully.
104 * Otherwise returns an error.
106 Result
<Ok
, nsresult
> SubstituteRemoteChannel(nsIURI
* aURI
,
107 nsILoadInfo
* aLoadInfo
,
108 nsIChannel
** aRetVal
);
111 * Replaces a file channel with a remote file channel for loading a
112 * web accessible resource for an unpacked extension from the parent.
114 * @param aURI the moz-extension URI
115 * @param aLoadInfo the loadinfo for the request
116 * @param aResolvedFileSpec the resolved URI spec for the file.
117 * @param aRetVal in/out param referring to the new remote channel.
118 * The reference to the input param file channel is dropped and
119 * replaced with a reference to a new channel that remotes
120 * the file access. The new channel encapsulates a request to
121 * the parent for an IPCStream for the file.
123 void SubstituteRemoteFileChannel(nsIURI
* aURI
, nsILoadInfo
* aLoadinfo
,
124 nsACString
& aResolvedFileSpec
,
125 nsIChannel
** aRetVal
);
128 * Replaces a JAR channel with a remote JAR channel for loading a
129 * an extension JAR file from the parent.
131 * @param aURI the moz-extension URI
132 * @param aLoadInfo the loadinfo for the request
133 * @param aResolvedFileSpec the resolved URI spec for the file.
134 * @param aRetVal in/out param referring to the new remote channel.
135 * The input param JAR channel is replaced with a new channel
136 * that remotes the JAR file access. The new channel encapsulates
137 * a request to the parent for the JAR file FD.
139 Result
<Ok
, nsresult
> SubstituteRemoteJarChannel(nsIURI
* aURI
,
140 nsILoadInfo
* aLoadinfo
,
141 nsACString
& aResolvedSpec
,
142 nsIChannel
** aRetVal
);
145 * Sets the aResult outparam to true if this unpacked extension load of
146 * a resource that is outside the extension dir should be allowed. This
147 * is only allowed for system extensions on Mac and Linux dev builds.
149 * @param aExtensionDir the extension directory. Argument must be an
150 * nsIFile for which Normalize() has already been called.
151 * @param aRequestedFile the requested web-accessible resource file. Argument
152 * must be an nsIFile for which Normalize() has already been called.
154 Result
<bool, nsresult
> AllowExternalResource(nsIFile
* aExtensionDir
,
155 nsIFile
* aRequestedFile
);
157 // Set the channel's content type using the provided URI's type
158 static void SetContentType(nsIURI
* aURI
, nsIChannel
* aChannel
);
160 // Gets a SimpleChannel that wraps the provided ExtensionStreamGetter
161 static void NewSimpleChannel(nsIURI
* aURI
, nsILoadInfo
* aLoadinfo
,
162 ExtensionStreamGetter
* aStreamGetter
,
163 nsIChannel
** aRetVal
);
165 // Gets a SimpleChannel that wraps the provided channel
166 static void NewSimpleChannel(nsIURI
* aURI
, nsILoadInfo
* aLoadinfo
,
167 nsIChannel
* aChannel
, nsIChannel
** aRetVal
);
169 #if defined(XP_MACOSX)
171 * Sets the aResult outparam to true if we are a developer build with the
172 * repo dir environment variable set and the requested file resides in the
173 * repo dir. Developer builds may load system extensions with web-accessible
174 * resources that are symlinks to files in the repo dir. This method is for
175 * checking if an unpacked resource requested by the child is from the repo.
176 * The requested file must be already Normalized(). Only compile this for
177 * Mac because the repo dir isn't always available on Linux.
179 * @param aRequestedFile the requested web-accessible resource file. Argument
180 * must be an nsIFile for which Normalize() has already been called.
182 Result
<bool, nsresult
> DevRepoContains(nsIFile
* aRequestedFile
);
184 // On development builds, this points to development repo. Lazily set.
185 nsCOMPtr
<nsIFile
> mDevRepo
;
187 // Set to true once we've already tried to load the dev repo path,
188 // allowing for lazy initialization of |mDevRepo|.
189 bool mAlreadyCheckedDevRepo
{false};
190 #endif /* XP_MACOSX */
194 * Sets the aResult outparam to true if we are a developer build and the
195 * provided directory is within the NS_GRE_DIR directory. Developer builds
196 * may load system extensions with web-accessible resources that are symlinks
197 * to files outside of the extension dir to the repo dir. This method is for
198 * checking if an extension directory is within NS_GRE_DIR. In that case, we
199 * consider the extension a system extension and allow it to use symlinks to
200 * resources outside of the extension dir. This exception is only applied
201 * to loads for unpacked extensions in unpackaged developer builds.
202 * The requested dir must be already Normalized().
204 * @param aExtensionDir the extension directory. Argument must be an
205 * nsIFile for which Normalize() has already been called.
207 Result
<bool, nsresult
> AppDirContains(nsIFile
* aExtensionDir
);
209 // On development builds, cache the NS_GRE_DIR repo. Lazily set.
210 nsCOMPtr
<nsIFile
> mAppDir
;
212 // Set to true once we've already read the AppDir, allowing for lazy
213 // initialization of |mAppDir|.
214 bool mAlreadyCheckedAppDir
{false};
215 #endif /* !defined(XP_WIN) */
217 // Used for opening JAR files off the main thread when we just need to
218 // obtain a file descriptor to send back to the child.
219 RefPtr
<mozilla::LazyIdleThread
> mFileOpenerThread
;
221 // To allow parent IPDL actors to invoke methods on this handler when
222 // handling moz-extension requests from the child.
223 static StaticRefPtr
<ExtensionProtocolHandler
> sSingleton
;
225 // Set to true when this instance of the handler must proxy loads of
226 // extension web-accessible resources to the parent process.
227 bool mUseRemoteFileChannels
;
231 } // namespace mozilla
233 #endif /* ExtensionProtocolHandler_h___ */