Bug 1700051: part 26) Correct typo in comment of `mozInlineSpellWordUtil::BuildSoftTe...
[gecko.git] / dom / fetch / InternalRequest.h
bloba526089fe2e7a544dd3eecea9d3b6d4026fc7ccf
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_InternalRequest_h
8 #define mozilla_dom_InternalRequest_h
10 #include "mozilla/dom/HeadersBinding.h"
11 #include "mozilla/dom/InternalHeaders.h"
12 #include "mozilla/dom/RequestBinding.h"
13 #include "mozilla/dom/SafeRefPtr.h"
14 #include "mozilla/LoadTainting.h"
15 #include "mozilla/UniquePtr.h"
17 #include "nsIChannelEventSink.h"
18 #include "nsIInputStream.h"
19 #include "nsISupportsImpl.h"
20 #ifdef DEBUG
21 # include "nsIURLParser.h"
22 # include "nsNetCID.h"
23 # include "nsServiceManagerUtils.h"
24 #endif
26 namespace mozilla {
28 namespace ipc {
29 class PrincipalInfo;
30 } // namespace ipc
32 namespace dom {
35 * The mapping of RequestDestination and nsContentPolicyType is currently as the
36 * following.
38 * RequestDestination| nsContentPolicyType
39 * ------------------+--------------------
40 * "audio" | TYPE_INTERNAL_AUDIO
41 * "audioworklet" | TYPE_INTERNAL_AUDIOWORKLET
42 * "document" | TYPE_DOCUMENT
43 * "embed" | TYPE_INTERNAL_EMBED
44 * "font" | TYPE_FONT, TYPE_INTERNAL_FONT_PRELOAD
45 * "frame" | TYPE_INTERNAL_FRAME
46 * "iframe" | TYPE_SUBDOCUMENT, TYPE_INTERNAL_IFRAME
47 * "image" | TYPE_INTERNAL_IMAGE, TYPE_INTERNAL_IMAGE_PRELOAD,
48 * | TYPE_IMAGE, TYPE_INTERNAL_IMAGE_FAVICON, TYPE_IMAGESET
49 * "manifest" | TYPE_WEB_MANIFEST
50 * "object" | TYPE_INTERNAL_OBJECT, TYPE_OBJECT
51 * "paintworklet" | TYPE_INTERNAL_PAINTWORKLET
52 * "report" | TYPE_CSP_REPORT
53 * "script" | TYPE_INTERNAL_SCRIPT, TYPE_INTERNAL_SCRIPT_PRELOAD,
54 * | TYPE_INTERNAL_MODULE, TYPE_INTERNAL_MODULE_PRELOAD,
55 * | TYPE_SCRIPT,
56 * | TYPE_INTERNAL_SERVICE_WORKER,
57 * | TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS,
58 * | TYPE_INTERNAL_CHROMEUTILS_COMPILED_SCRIPT
59 * | TYPE_INTERNAL_FRAME_MESSAGEMANAGER_SCRIPT
60 * "sharedworker" | TYPE_INTERNAL_SHARED_WORKER
61 * "serviceworker" | The spec lists this as a valid value for the enum,
62 * | however it is impossible to observe a request with this
63 * | destination value.
64 * "style" | TYPE_INTERNAL_STYLESHEET,
65 * | TYPE_INTERNAL_STYLESHEET_PRELOAD,
66 * | TYPE_STYLESHEET
67 * "track" | TYPE_INTERNAL_TRACK
68 * "video" | TYPE_INTERNAL_VIDEO
69 * "worker" | TYPE_INTERNAL_WORKER
70 * "xslt" | TYPE_XSLT
71 * "" | Default for everything else.
75 class IPCInternalRequest;
76 class Request;
78 #define kFETCH_CLIENT_REFERRER_STR "about:client"
79 class InternalRequest final : public AtomicSafeRefCounted<InternalRequest> {
80 friend class Request;
82 public:
83 MOZ_DECLARE_REFCOUNTED_TYPENAME(InternalRequest)
84 InternalRequest(const nsACString& aURL, const nsACString& aFragment);
85 InternalRequest(const nsACString& aURL, const nsACString& aFragment,
86 const nsACString& aMethod,
87 already_AddRefed<InternalHeaders> aHeaders,
88 RequestCache aCacheMode, RequestMode aMode,
89 RequestRedirect aRequestRedirect,
90 RequestCredentials aRequestCredentials,
91 const nsAString& aReferrer, ReferrerPolicy aReferrerPolicy,
92 nsContentPolicyType aContentPolicyType,
93 const nsAString& aIntegrity);
95 explicit InternalRequest(const IPCInternalRequest& aIPCRequest);
97 SafeRefPtr<InternalRequest> Clone();
99 void GetMethod(nsCString& aMethod) const { aMethod.Assign(mMethod); }
101 void SetMethod(const nsACString& aMethod) { mMethod.Assign(aMethod); }
103 bool HasSimpleMethod() const {
104 return mMethod.LowerCaseEqualsASCII("get") ||
105 mMethod.LowerCaseEqualsASCII("post") ||
106 mMethod.LowerCaseEqualsASCII("head");
108 // GetURL should get the request's current url with fragment. A request has
109 // an associated current url. It is a pointer to the last fetch URL in
110 // request's url list.
111 void GetURL(nsACString& aURL) const {
112 aURL.Assign(GetURLWithoutFragment());
113 if (GetFragment().IsEmpty()) {
114 return;
116 aURL.AppendLiteral("#");
117 aURL.Append(GetFragment());
120 const nsCString& GetURLWithoutFragment() const {
121 MOZ_RELEASE_ASSERT(!mURLList.IsEmpty(),
122 "Internal Request's urlList should not be empty.");
124 return mURLList.LastElement();
127 // A safe guard for ensuring that request's URL is only allowed to be set in a
128 // sw internal redirect.
129 void SetURLForInternalRedirect(const uint32_t aFlag, const nsACString& aURL,
130 const nsACString& aFragment) {
131 // Only check in debug build to prevent it from being used unexpectedly.
132 MOZ_ASSERT(aFlag & nsIChannelEventSink::REDIRECT_INTERNAL);
134 return SetURL(aURL, aFragment);
137 // AddURL should append the url into url list.
138 // Normally we strip the fragment from the URL in Request::Constructor and
139 // pass the fragment as the second argument into it.
140 // If a fragment is present in the URL it must be stripped and passed in
141 // separately.
142 void AddURL(const nsACString& aURL, const nsACString& aFragment) {
143 MOZ_ASSERT(!aURL.IsEmpty());
144 MOZ_ASSERT(!aURL.Contains('#'));
146 mURLList.AppendElement(aURL);
148 mFragment.Assign(aFragment);
150 // Get the URL list without their fragments.
151 void GetURLListWithoutFragment(nsTArray<nsCString>& aURLList) {
152 aURLList.Assign(mURLList);
154 void GetReferrer(nsAString& aReferrer) const { aReferrer.Assign(mReferrer); }
156 void SetReferrer(const nsAString& aReferrer) {
157 #ifdef DEBUG
158 bool validReferrer = false;
159 if (aReferrer.IsEmpty() ||
160 aReferrer.EqualsLiteral(kFETCH_CLIENT_REFERRER_STR)) {
161 validReferrer = true;
162 } else {
163 nsCOMPtr<nsIURLParser> parser = do_GetService(NS_STDURLPARSER_CONTRACTID);
164 if (!parser) {
165 NS_WARNING("Could not get parser to validate URL!");
166 } else {
167 uint32_t schemePos;
168 int32_t schemeLen;
169 uint32_t authorityPos;
170 int32_t authorityLen;
171 uint32_t pathPos;
172 int32_t pathLen;
174 NS_ConvertUTF16toUTF8 ref(aReferrer);
175 nsresult rv =
176 parser->ParseURL(ref.get(), ref.Length(), &schemePos, &schemeLen,
177 &authorityPos, &authorityLen, &pathPos, &pathLen);
178 if (NS_FAILED(rv)) {
179 NS_WARNING("Invalid referrer URL!");
180 } else if (schemeLen < 0 || authorityLen < 0) {
181 NS_WARNING("Invalid referrer URL!");
182 } else {
183 validReferrer = true;
188 MOZ_ASSERT(validReferrer);
189 #endif
191 mReferrer.Assign(aReferrer);
194 ReferrerPolicy ReferrerPolicy_() const { return mReferrerPolicy; }
196 void SetReferrerPolicy(ReferrerPolicy aReferrerPolicy) {
197 mReferrerPolicy = aReferrerPolicy;
200 ReferrerPolicy GetEnvironmentReferrerPolicy() const {
201 return mEnvironmentReferrerPolicy;
204 void SetEnvironmentReferrerPolicy(ReferrerPolicy aReferrerPolicy) {
205 mEnvironmentReferrerPolicy = aReferrerPolicy;
208 bool SkipServiceWorker() const { return mSkipServiceWorker; }
210 void SetSkipServiceWorker() { mSkipServiceWorker = true; }
212 bool IsSynchronous() const { return mSynchronous; }
214 RequestMode Mode() const { return mMode; }
216 void SetMode(RequestMode aMode) { mMode = aMode; }
218 RequestCredentials GetCredentialsMode() const { return mCredentialsMode; }
220 void SetCredentialsMode(RequestCredentials aCredentialsMode) {
221 mCredentialsMode = aCredentialsMode;
224 LoadTainting GetResponseTainting() const { return mResponseTainting; }
226 void MaybeIncreaseResponseTainting(LoadTainting aTainting) {
227 if (aTainting > mResponseTainting) {
228 mResponseTainting = aTainting;
232 RequestCache GetCacheMode() const { return mCacheMode; }
234 void SetCacheMode(RequestCache aCacheMode) { mCacheMode = aCacheMode; }
236 RequestRedirect GetRedirectMode() const { return mRedirectMode; }
238 void SetRedirectMode(RequestRedirect aRedirectMode) {
239 mRedirectMode = aRedirectMode;
242 const nsString& GetIntegrity() const { return mIntegrity; }
244 void SetIntegrity(const nsAString& aIntegrity) {
245 mIntegrity.Assign(aIntegrity);
248 bool MozErrors() const { return mMozErrors; }
250 void SetMozErrors() { mMozErrors = true; }
252 const nsCString& GetFragment() const { return mFragment; }
254 nsContentPolicyType ContentPolicyType() const { return mContentPolicyType; }
255 void SetContentPolicyType(nsContentPolicyType aContentPolicyType);
257 void OverrideContentPolicyType(nsContentPolicyType aContentPolicyType);
259 RequestDestination Destination() const {
260 return MapContentPolicyTypeToRequestDestination(mContentPolicyType);
263 bool UnsafeRequest() const { return mUnsafeRequest; }
265 void SetUnsafeRequest() { mUnsafeRequest = true; }
267 InternalHeaders* Headers() const { return mHeaders; }
269 void SetHeaders(InternalHeaders* aHeaders) {
270 MOZ_ASSERT(aHeaders);
271 mHeaders = aHeaders;
274 void SetBody(nsIInputStream* aStream, int64_t aBodyLength) {
275 // A request's body may not be reset once set.
276 MOZ_ASSERT_IF(aStream, !mBodyStream);
277 mBodyStream = aStream;
278 mBodyLength = aBodyLength;
281 // Will return the original stream!
282 // Use a tee or copy if you don't want to erase the original.
283 void GetBody(nsIInputStream** aStream, int64_t* aBodyLength = nullptr) const {
284 nsCOMPtr<nsIInputStream> s = mBodyStream;
285 s.forget(aStream);
287 if (aBodyLength) {
288 *aBodyLength = mBodyLength;
292 void SetBodyBlobURISpec(nsACString& aBlobURISpec) {
293 mBodyBlobURISpec = aBlobURISpec;
296 const nsACString& BodyBlobURISpec() const { return mBodyBlobURISpec; }
298 void SetBodyLocalPath(nsAString& aLocalPath) { mBodyLocalPath = aLocalPath; }
300 const nsAString& BodyLocalPath() const { return mBodyLocalPath; }
302 // The global is used as the client for the new object.
303 SafeRefPtr<InternalRequest> GetRequestConstructorCopy(
304 nsIGlobalObject* aGlobal, ErrorResult& aRv) const;
306 bool IsNavigationRequest() const;
308 bool IsWorkerRequest() const;
310 bool IsClientRequest() const;
312 void MaybeSkipCacheIfPerformingRevalidation();
314 bool IsContentPolicyTypeOverridden() const {
315 return mContentPolicyTypeOverridden;
318 static RequestMode MapChannelToRequestMode(nsIChannel* aChannel);
320 static RequestCredentials MapChannelToRequestCredentials(
321 nsIChannel* aChannel);
323 // Takes ownership of the principal info.
324 void SetPrincipalInfo(UniquePtr<mozilla::ipc::PrincipalInfo> aPrincipalInfo);
326 const UniquePtr<mozilla::ipc::PrincipalInfo>& GetPrincipalInfo() const {
327 return mPrincipalInfo;
330 const nsCString& GetPreferredAlternativeDataType() const {
331 return mPreferredAlternativeDataType;
334 void SetPreferredAlternativeDataType(const nsACString& aDataType) {
335 mPreferredAlternativeDataType = aDataType;
338 ~InternalRequest();
340 InternalRequest(const InternalRequest& aOther) = delete;
342 void SetEmbedderPolicy(nsILoadInfo::CrossOriginEmbedderPolicy aPolicy) {
343 mEmbedderPolicy = aPolicy;
346 nsILoadInfo::CrossOriginEmbedderPolicy GetEmbedderPolicy() const {
347 return mEmbedderPolicy;
350 private:
351 struct ConstructorGuard {};
353 public:
354 // Does not copy mBodyStream. Use fallible Clone() for complete copy.
355 InternalRequest(const InternalRequest& aOther, ConstructorGuard);
357 private:
358 // Map the content policy type to the associated fetch destination, as defined
359 // by the spec at https://fetch.spec.whatwg.org/#concept-request-destination.
360 // Note that while the HTML spec for the "Link" element and its "as" attribute
361 // (https://html.spec.whatwg.org/#attr-link-as) reuse fetch's definition of
362 // destination.
363 static RequestDestination MapContentPolicyTypeToRequestDestination(
364 nsContentPolicyType aContentPolicyType);
366 static bool IsNavigationContentPolicy(nsContentPolicyType aContentPolicyType);
368 static bool IsWorkerContentPolicy(nsContentPolicyType aContentPolicyType);
370 // It should only be called while there is a service-worker-internal-redirect.
371 void SetURL(const nsACString& aURL, const nsACString& aFragment) {
372 MOZ_ASSERT(!aURL.IsEmpty());
373 MOZ_ASSERT(!aURL.Contains('#'));
374 MOZ_ASSERT(mURLList.Length() > 0);
376 mURLList.LastElement() = aURL;
377 mFragment.Assign(aFragment);
380 nsCString mMethod;
381 // mURLList: a list of one or more fetch URLs
382 nsTArray<nsCString> mURLList;
383 RefPtr<InternalHeaders> mHeaders;
384 nsCString mBodyBlobURISpec;
385 nsString mBodyLocalPath;
386 nsCOMPtr<nsIInputStream> mBodyStream;
387 int64_t mBodyLength;
389 nsCString mPreferredAlternativeDataType;
391 nsContentPolicyType mContentPolicyType;
393 // Empty string: no-referrer
394 // "about:client": client (default)
395 // URL: an URL
396 nsString mReferrer;
397 ReferrerPolicy mReferrerPolicy;
399 // This will be used for request created from Window or Worker contexts
400 // In case there's no Referrer Policy in Request, this will be passed to
401 // channel.
402 ReferrerPolicy mEnvironmentReferrerPolicy;
403 RequestMode mMode;
404 RequestCredentials mCredentialsMode;
405 LoadTainting mResponseTainting = LoadTainting::Basic;
406 RequestCache mCacheMode;
407 RequestRedirect mRedirectMode;
408 nsString mIntegrity;
409 bool mMozErrors = false;
410 nsCString mFragment;
411 bool mSkipServiceWorker = false;
412 bool mSynchronous = false;
413 bool mUnsafeRequest = false;
414 bool mUseURLCredentials = false;
415 // This is only set when Request.overrideContentPolicyType() has been set.
416 // It is illegal to pass such a Request object to a fetch() method unless
417 // if the caller has chrome privileges.
418 bool mContentPolicyTypeOverridden = false;
419 nsILoadInfo::CrossOriginEmbedderPolicy mEmbedderPolicy =
420 nsILoadInfo::EMBEDDER_POLICY_NULL;
422 UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
425 } // namespace dom
426 } // namespace mozilla
428 #endif // mozilla_dom_InternalRequest_h