Coverage Report

Created: 2018-09-25 14:53

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