no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / dom / fetch / InternalRequest.h
blobb74ec1db1e407c966ec8d8db81f9cedcd1ecc785
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 #include "mozilla/net/NeckoChannelParams.h"
21 #ifdef DEBUG
22 # include "nsIURLParser.h"
23 # include "nsNetCID.h"
24 # include "nsServiceManagerUtils.h"
25 #endif
27 using mozilla::net::RedirectHistoryEntryInfo;
29 namespace mozilla {
31 namespace ipc {
32 class PBackgroundChild;
33 class PrincipalInfo;
34 } // namespace ipc
36 namespace dom {
39 * The mapping of RequestDestination and nsContentPolicyType is currently as the
40 * following.
42 * RequestDestination| nsContentPolicyType
43 * ------------------+--------------------
44 * "audio" | TYPE_INTERNAL_AUDIO
45 * "audioworklet" | TYPE_INTERNAL_AUDIOWORKLET
46 * "document" | TYPE_DOCUMENT
47 * "embed" | TYPE_INTERNAL_EMBED
48 * "font" | TYPE_FONT, TYPE_INTERNAL_FONT_PRELOAD
49 * "frame" | TYPE_INTERNAL_FRAME
50 * "iframe" | TYPE_SUBDOCUMENT, TYPE_INTERNAL_IFRAME
51 * "image" | TYPE_INTERNAL_IMAGE, TYPE_INTERNAL_IMAGE_PRELOAD,
52 * | TYPE_IMAGE, TYPE_INTERNAL_IMAGE_FAVICON, TYPE_IMAGESET
53 * "manifest" | TYPE_WEB_MANIFEST
54 * "object" | TYPE_INTERNAL_OBJECT, TYPE_OBJECT
55 * "paintworklet" | TYPE_INTERNAL_PAINTWORKLET
56 * "report" | TYPE_CSP_REPORT
57 * "script" | TYPE_INTERNAL_SCRIPT, TYPE_INTERNAL_SCRIPT_PRELOAD,
58 * | TYPE_INTERNAL_MODULE, TYPE_INTERNAL_MODULE_PRELOAD,
59 * | TYPE_SCRIPT,
60 * | TYPE_INTERNAL_SERVICE_WORKER,
61 * | TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS,
62 * | TYPE_INTERNAL_CHROMEUTILS_COMPILED_SCRIPT
63 * | TYPE_INTERNAL_FRAME_MESSAGEMANAGER_SCRIPT
64 * "sharedworker" | TYPE_INTERNAL_SHARED_WORKER
65 * "serviceworker" | The spec lists this as a valid value for the enum,
66 * | however it is impossible to observe a request with this
67 * | destination value.
68 * "style" | TYPE_INTERNAL_STYLESHEET,
69 * | TYPE_INTERNAL_STYLESHEET_PRELOAD,
70 * | TYPE_STYLESHEET
71 * "track" | TYPE_INTERNAL_TRACK
72 * "video" | TYPE_INTERNAL_VIDEO
73 * "worker" | TYPE_INTERNAL_WORKER, TYPE_INTERNAL_WORKER_STATIC_MODULE
74 * "xslt" | TYPE_XSLT
75 * "" | Default for everything else.
79 class IPCInternalRequest;
80 class Request;
82 #define kFETCH_CLIENT_REFERRER_STR "about:client"
83 class InternalRequest final : public AtomicSafeRefCounted<InternalRequest> {
84 friend class Request;
86 public:
87 MOZ_DECLARE_REFCOUNTED_TYPENAME(InternalRequest)
88 InternalRequest(const nsACString& aURL, const nsACString& aFragment);
89 InternalRequest(const nsACString& aURL, const nsACString& aFragment,
90 const nsACString& aMethod,
91 already_AddRefed<InternalHeaders> aHeaders,
92 RequestCache aCacheMode, RequestMode aMode,
93 RequestRedirect aRequestRedirect,
94 RequestCredentials aRequestCredentials,
95 const nsAString& aReferrer, ReferrerPolicy aReferrerPolicy,
96 RequestPriority aPriority,
97 nsContentPolicyType aContentPolicyType,
98 const nsAString& aIntegrity);
100 explicit InternalRequest(const IPCInternalRequest& aIPCRequest);
102 void ToIPCInternalRequest(IPCInternalRequest* aIPCRequest,
103 mozilla::ipc::PBackgroundChild* aManager);
105 SafeRefPtr<InternalRequest> Clone();
107 void GetMethod(nsCString& aMethod) const { aMethod.Assign(mMethod); }
109 void SetMethod(const nsACString& aMethod) { mMethod.Assign(aMethod); }
111 bool HasSimpleMethod() const {
112 return mMethod.LowerCaseEqualsASCII("get") ||
113 mMethod.LowerCaseEqualsASCII("post") ||
114 mMethod.LowerCaseEqualsASCII("head");
116 // GetURL should get the request's current url with fragment. A request has
117 // an associated current url. It is a pointer to the last fetch URL in
118 // request's url list.
119 void GetURL(nsACString& aURL) const {
120 aURL.Assign(GetURLWithoutFragment());
121 if (GetFragment().IsEmpty()) {
122 return;
124 aURL.AppendLiteral("#");
125 aURL.Append(GetFragment());
128 const nsCString& GetURLWithoutFragment() const {
129 MOZ_RELEASE_ASSERT(!mURLList.IsEmpty(),
130 "Internal Request's urlList should not be empty.");
132 return mURLList.LastElement();
135 // A safe guard for ensuring that request's URL is only allowed to be set in a
136 // sw internal redirect.
137 void SetURLForInternalRedirect(const uint32_t aFlag, const nsACString& aURL,
138 const nsACString& aFragment) {
139 // Only check in debug build to prevent it from being used unexpectedly.
140 MOZ_ASSERT(aFlag & nsIChannelEventSink::REDIRECT_INTERNAL);
142 return SetURL(aURL, aFragment);
145 // AddURL should append the url into url list.
146 // Normally we strip the fragment from the URL in Request::Constructor and
147 // pass the fragment as the second argument into it.
148 // If a fragment is present in the URL it must be stripped and passed in
149 // separately.
150 void AddURL(const nsACString& aURL, const nsACString& aFragment) {
151 MOZ_ASSERT(!aURL.IsEmpty());
152 MOZ_ASSERT(!aURL.Contains('#'));
154 mURLList.AppendElement(aURL);
156 mFragment.Assign(aFragment);
158 // Get the URL list without their fragments.
159 void GetURLListWithoutFragment(nsTArray<nsCString>& aURLList) {
160 aURLList.Assign(mURLList);
162 void GetReferrer(nsAString& aReferrer) const { aReferrer.Assign(mReferrer); }
164 void SetReferrer(const nsAString& aReferrer) {
165 #ifdef DEBUG
166 bool validReferrer = false;
167 if (aReferrer.IsEmpty() ||
168 aReferrer.EqualsLiteral(kFETCH_CLIENT_REFERRER_STR)) {
169 validReferrer = true;
170 } else {
171 nsCOMPtr<nsIURLParser> parser = do_GetService(NS_STDURLPARSER_CONTRACTID);
172 if (!parser) {
173 NS_WARNING("Could not get parser to validate URL!");
174 } else {
175 uint32_t schemePos;
176 int32_t schemeLen;
177 uint32_t authorityPos;
178 int32_t authorityLen;
179 uint32_t pathPos;
180 int32_t pathLen;
182 NS_ConvertUTF16toUTF8 ref(aReferrer);
183 nsresult rv =
184 parser->ParseURL(ref.get(), ref.Length(), &schemePos, &schemeLen,
185 &authorityPos, &authorityLen, &pathPos, &pathLen);
186 if (NS_FAILED(rv)) {
187 NS_WARNING("Invalid referrer URL!");
188 } else if (schemeLen < 0 || authorityLen < 0) {
189 NS_WARNING("Invalid referrer URL!");
190 } else {
191 validReferrer = true;
196 MOZ_ASSERT(validReferrer);
197 #endif
199 mReferrer.Assign(aReferrer);
202 ReferrerPolicy ReferrerPolicy_() const { return mReferrerPolicy; }
204 void SetReferrerPolicy(ReferrerPolicy aReferrerPolicy) {
205 mReferrerPolicy = aReferrerPolicy;
208 ReferrerPolicy GetEnvironmentReferrerPolicy() const {
209 return mEnvironmentReferrerPolicy;
212 void SetEnvironmentReferrerPolicy(ReferrerPolicy aReferrerPolicy) {
213 mEnvironmentReferrerPolicy = aReferrerPolicy;
216 bool SkipServiceWorker() const { return mSkipServiceWorker; }
218 void SetSkipServiceWorker() { mSkipServiceWorker = true; }
220 bool SkipWasmCaching() const { return mSkipWasmCaching; }
222 void SetSkipWasmCaching() { mSkipWasmCaching = true; }
224 bool IsSynchronous() const { return mSynchronous; }
226 RequestMode Mode() const { return mMode; }
228 void SetMode(RequestMode aMode) { mMode = aMode; }
230 RequestCredentials GetCredentialsMode() const { return mCredentialsMode; }
232 void SetCredentialsMode(RequestCredentials aCredentialsMode) {
233 mCredentialsMode = aCredentialsMode;
236 LoadTainting GetResponseTainting() const { return mResponseTainting; }
238 void MaybeIncreaseResponseTainting(LoadTainting aTainting) {
239 if (aTainting > mResponseTainting) {
240 mResponseTainting = aTainting;
244 RequestCache GetCacheMode() const { return mCacheMode; }
246 void SetCacheMode(RequestCache aCacheMode) { mCacheMode = aCacheMode; }
248 RequestRedirect GetRedirectMode() const { return mRedirectMode; }
250 void SetRedirectMode(RequestRedirect aRedirectMode) {
251 mRedirectMode = aRedirectMode;
254 RequestPriority GetPriorityMode() const { return mPriorityMode; }
256 void SetPriorityMode(RequestPriority aPriorityMode) {
257 mPriorityMode = aPriorityMode;
260 const nsString& GetIntegrity() const { return mIntegrity; }
262 void SetIntegrity(const nsAString& aIntegrity) {
263 mIntegrity.Assign(aIntegrity);
266 bool GetKeepalive() const { return mKeepalive; }
268 void SetKeepalive(const bool aKeepalive) { mKeepalive = aKeepalive; }
270 bool MozErrors() const { return mMozErrors; }
272 void SetMozErrors() { mMozErrors = true; }
274 const nsCString& GetFragment() const { return mFragment; }
276 nsContentPolicyType ContentPolicyType() const { return mContentPolicyType; }
277 void SetContentPolicyType(nsContentPolicyType aContentPolicyType);
279 void OverrideContentPolicyType(nsContentPolicyType aContentPolicyType);
281 RequestDestination Destination() const {
282 return MapContentPolicyTypeToRequestDestination(mContentPolicyType);
285 bool UnsafeRequest() const { return mUnsafeRequest; }
287 void SetUnsafeRequest() { mUnsafeRequest = true; }
289 InternalHeaders* Headers() const { return mHeaders; }
291 void SetHeaders(InternalHeaders* aHeaders) {
292 MOZ_ASSERT(aHeaders);
293 mHeaders = aHeaders;
296 void SetBody(nsIInputStream* aStream, int64_t aBodyLength) {
297 // A request's body may not be reset once set.
298 MOZ_ASSERT_IF(aStream, !mBodyStream);
299 mBodyStream = aStream;
300 mBodyLength = aBodyLength;
303 // Will return the original stream!
304 // Use a tee or copy if you don't want to erase the original.
305 void GetBody(nsIInputStream** aStream, int64_t* aBodyLength = nullptr) const {
306 nsCOMPtr<nsIInputStream> s = mBodyStream;
307 s.forget(aStream);
309 if (aBodyLength) {
310 *aBodyLength = mBodyLength;
314 void SetBodyBlobURISpec(nsACString& aBlobURISpec) {
315 mBodyBlobURISpec = aBlobURISpec;
318 const nsACString& BodyBlobURISpec() const { return mBodyBlobURISpec; }
320 void SetBodyLocalPath(nsAString& aLocalPath) { mBodyLocalPath = aLocalPath; }
322 const nsAString& BodyLocalPath() const { return mBodyLocalPath; }
324 // The global is used as the client for the new object.
325 SafeRefPtr<InternalRequest> GetRequestConstructorCopy(
326 nsIGlobalObject* aGlobal, ErrorResult& aRv) const;
328 bool IsNavigationRequest() const;
330 bool IsWorkerRequest() const;
332 bool IsClientRequest() const;
334 void MaybeSkipCacheIfPerformingRevalidation();
336 bool IsContentPolicyTypeOverridden() const {
337 return mContentPolicyTypeOverridden;
340 static RequestMode MapChannelToRequestMode(nsIChannel* aChannel);
342 static RequestCredentials MapChannelToRequestCredentials(
343 nsIChannel* aChannel);
345 // Takes ownership of the principal info.
346 void SetPrincipalInfo(UniquePtr<mozilla::ipc::PrincipalInfo> aPrincipalInfo);
347 const UniquePtr<mozilla::ipc::PrincipalInfo>& GetPrincipalInfo() const {
348 return mPrincipalInfo;
351 const nsCString& GetPreferredAlternativeDataType() const {
352 return mPreferredAlternativeDataType;
355 void SetPreferredAlternativeDataType(const nsACString& aDataType) {
356 mPreferredAlternativeDataType = aDataType;
359 ~InternalRequest();
361 InternalRequest(const InternalRequest& aOther) = delete;
363 void SetEmbedderPolicy(nsILoadInfo::CrossOriginEmbedderPolicy aPolicy) {
364 mEmbedderPolicy = aPolicy;
367 nsILoadInfo::CrossOriginEmbedderPolicy GetEmbedderPolicy() const {
368 return mEmbedderPolicy;
371 void SetInterceptionTriggeringPrincipalInfo(
372 UniquePtr<mozilla::ipc::PrincipalInfo> aPrincipalInfo);
374 const UniquePtr<mozilla::ipc::PrincipalInfo>&
375 GetInterceptionTriggeringPrincipalInfo() const {
376 return mInterceptionTriggeringPrincipalInfo;
379 nsContentPolicyType InterceptionContentPolicyType() const {
380 return mInterceptionContentPolicyType;
382 void SetInterceptionContentPolicyType(nsContentPolicyType aContentPolicyType);
384 const nsTArray<RedirectHistoryEntryInfo>& InterceptionRedirectChain() const {
385 return mInterceptionRedirectChain;
388 void SetInterceptionRedirectChain(
389 const nsTArray<RedirectHistoryEntryInfo>& aRedirectChain) {
390 mInterceptionRedirectChain = aRedirectChain;
393 const bool& InterceptionFromThirdParty() const {
394 return mInterceptionFromThirdParty;
397 void SetInterceptionFromThirdParty(bool aFromThirdParty) {
398 mInterceptionFromThirdParty = aFromThirdParty;
401 private:
402 struct ConstructorGuard {};
404 public:
405 // Does not copy mBodyStream. Use fallible Clone() for complete copy.
406 InternalRequest(const InternalRequest& aOther, ConstructorGuard);
408 private:
409 // Map the content policy type to the associated fetch destination, as defined
410 // by the spec at https://fetch.spec.whatwg.org/#concept-request-destination.
411 // Note that while the HTML spec for the "Link" element and its "as" attribute
412 // (https://html.spec.whatwg.org/#attr-link-as) reuse fetch's definition of
413 // destination.
414 static RequestDestination MapContentPolicyTypeToRequestDestination(
415 nsContentPolicyType aContentPolicyType);
417 static bool IsNavigationContentPolicy(nsContentPolicyType aContentPolicyType);
419 static bool IsWorkerContentPolicy(nsContentPolicyType aContentPolicyType);
421 // It should only be called while there is a service-worker-internal-redirect.
422 void SetURL(const nsACString& aURL, const nsACString& aFragment) {
423 MOZ_ASSERT(!aURL.IsEmpty());
424 MOZ_ASSERT(!aURL.Contains('#'));
425 MOZ_ASSERT(mURLList.Length() > 0);
427 mURLList.LastElement() = aURL;
428 mFragment.Assign(aFragment);
431 nsCString mMethod;
432 // mURLList: a list of one or more fetch URLs
433 nsTArray<nsCString> mURLList;
434 RefPtr<InternalHeaders> mHeaders;
435 nsCString mBodyBlobURISpec;
436 nsString mBodyLocalPath;
437 nsCOMPtr<nsIInputStream> mBodyStream;
438 int64_t mBodyLength;
440 nsCString mPreferredAlternativeDataType;
442 nsContentPolicyType mContentPolicyType;
444 // Empty string: no-referrer
445 // "about:client": client (default)
446 // URL: an URL
447 nsString mReferrer;
448 ReferrerPolicy mReferrerPolicy;
450 // This will be used for request created from Window or Worker contexts
451 // In case there's no Referrer Policy in Request, this will be passed to
452 // channel.
453 ReferrerPolicy mEnvironmentReferrerPolicy;
454 RequestMode mMode;
455 RequestCredentials mCredentialsMode;
456 LoadTainting mResponseTainting = LoadTainting::Basic;
457 RequestCache mCacheMode;
458 RequestRedirect mRedirectMode;
459 RequestPriority mPriorityMode = RequestPriority::Auto;
460 nsString mIntegrity;
461 bool mKeepalive = false;
462 bool mMozErrors = false;
463 nsCString mFragment;
464 bool mSkipServiceWorker = false;
465 bool mSkipWasmCaching = false;
466 bool mSynchronous = false;
467 bool mUnsafeRequest = false;
468 bool mUseURLCredentials = false;
469 // This is only set when Request.overrideContentPolicyType() has been set.
470 // It is illegal to pass such a Request object to a fetch() method unless
471 // if the caller has chrome privileges.
472 bool mContentPolicyTypeOverridden = false;
473 nsILoadInfo::CrossOriginEmbedderPolicy mEmbedderPolicy =
474 nsILoadInfo::EMBEDDER_POLICY_NULL;
476 UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
478 // Following members are specific for the FetchEvent.request or
479 // NavigationPreload request which is extracted from the
480 // InterceptedHttpChannel.
481 // Notice that these members would not be copied when calling
482 // InternalRequest::GetRequestConstructorCopy() since these information should
483 // not be propagated when copying the Request in ServiceWorker script.
485 // This is the trigging principalInfo of the InterceptedHttpChannel.
486 UniquePtr<mozilla::ipc::PrincipalInfo> mInterceptionTriggeringPrincipalInfo;
488 // This is the contentPolicyType of the InterceptedHttpChannel.
489 nsContentPolicyType mInterceptionContentPolicyType{
490 nsIContentPolicy::TYPE_INVALID};
492 // This is the redirect history of the InterceptedHttpChannel.
493 CopyableTArray<RedirectHistoryEntryInfo> mInterceptionRedirectChain;
495 // This indicates that the InterceptedHttpChannel is a third party channel.
496 bool mInterceptionFromThirdParty{false};
499 } // namespace dom
500 } // namespace mozilla
502 #endif // mozilla_dom_InternalRequest_h