Bug 1700051: part 26) Correct typo in comment of `mozInlineSpellWordUtil::BuildSoftTe...
[gecko.git] / dom / fetch / InternalRequest.cpp
blob0f55a8486a8414f5183b8430c6a195df9fe07610
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 #include "InternalRequest.h"
9 #include "InternalResponse.h"
10 #include "mozilla/ErrorResult.h"
11 #include "mozilla/dom/Document.h"
12 #include "mozilla/dom/FetchTypes.h"
13 #include "mozilla/dom/ScriptSettings.h"
14 #include "mozilla/dom/WorkerCommon.h"
15 #include "mozilla/dom/WorkerPrivate.h"
16 #include "mozilla/ipc/IPCStreamUtils.h"
17 #include "mozilla/ipc/PBackgroundChild.h"
18 #include "mozilla/RemoteLazyInputStreamChild.h"
19 #include "nsIContentPolicy.h"
20 #include "nsStreamUtils.h"
22 namespace mozilla::dom {
23 // The global is used to extract the principal.
24 SafeRefPtr<InternalRequest> InternalRequest::GetRequestConstructorCopy(
25 nsIGlobalObject* aGlobal, ErrorResult& aRv) const {
26 MOZ_RELEASE_ASSERT(!mURLList.IsEmpty(),
27 "Internal Request's urlList should not be empty when "
28 "copied from constructor.");
29 auto copy =
30 MakeSafeRefPtr<InternalRequest>(mURLList.LastElement(), mFragment);
31 copy->SetMethod(mMethod);
32 copy->mHeaders = new InternalHeaders(*mHeaders);
33 copy->SetUnsafeRequest();
34 copy->mBodyStream = mBodyStream;
35 copy->mBodyLength = mBodyLength;
36 // The "client" is not stored in our implementation. Fetch API users should
37 // use the appropriate window/document/principal and other Gecko security
38 // mechanisms as appropriate.
39 copy->mReferrer = mReferrer;
40 copy->mReferrerPolicy = mReferrerPolicy;
41 copy->mEnvironmentReferrerPolicy = mEnvironmentReferrerPolicy;
42 copy->mIntegrity = mIntegrity;
43 copy->mMozErrors = mMozErrors;
45 copy->mContentPolicyType = mContentPolicyTypeOverridden
46 ? mContentPolicyType
47 : nsIContentPolicy::TYPE_FETCH;
48 copy->mMode = mMode;
49 copy->mCredentialsMode = mCredentialsMode;
50 copy->mCacheMode = mCacheMode;
51 copy->mRedirectMode = mRedirectMode;
52 copy->mContentPolicyTypeOverridden = mContentPolicyTypeOverridden;
54 copy->mPreferredAlternativeDataType = mPreferredAlternativeDataType;
55 return copy;
58 SafeRefPtr<InternalRequest> InternalRequest::Clone() {
59 auto clone = MakeSafeRefPtr<InternalRequest>(*this, ConstructorGuard{});
61 if (!mBodyStream) {
62 return clone;
65 nsCOMPtr<nsIInputStream> clonedBody;
66 nsCOMPtr<nsIInputStream> replacementBody;
68 nsresult rv = NS_CloneInputStream(mBodyStream, getter_AddRefs(clonedBody),
69 getter_AddRefs(replacementBody));
70 if (NS_WARN_IF(NS_FAILED(rv))) {
71 return nullptr;
74 clone->mBodyStream.swap(clonedBody);
75 if (replacementBody) {
76 mBodyStream.swap(replacementBody);
78 return clone;
80 InternalRequest::InternalRequest(const nsACString& aURL,
81 const nsACString& aFragment)
82 : mMethod("GET"),
83 mHeaders(new InternalHeaders(HeadersGuardEnum::None)),
84 mBodyLength(InternalResponse::UNKNOWN_BODY_SIZE),
85 mContentPolicyType(nsIContentPolicy::TYPE_FETCH),
86 mReferrer(NS_LITERAL_STRING_FROM_CSTRING(kFETCH_CLIENT_REFERRER_STR)),
87 mReferrerPolicy(ReferrerPolicy::_empty),
88 mEnvironmentReferrerPolicy(ReferrerPolicy::_empty),
89 mMode(RequestMode::No_cors),
90 mCredentialsMode(RequestCredentials::Omit),
91 mCacheMode(RequestCache::Default),
92 mRedirectMode(RequestRedirect::Follow) {
93 MOZ_ASSERT(!aURL.IsEmpty());
94 AddURL(aURL, aFragment);
96 InternalRequest::InternalRequest(
97 const nsACString& aURL, const nsACString& aFragment,
98 const nsACString& aMethod, already_AddRefed<InternalHeaders> aHeaders,
99 RequestCache aCacheMode, RequestMode aMode,
100 RequestRedirect aRequestRedirect, RequestCredentials aRequestCredentials,
101 const nsAString& aReferrer, ReferrerPolicy aReferrerPolicy,
102 nsContentPolicyType aContentPolicyType, const nsAString& aIntegrity)
103 : mMethod(aMethod),
104 mHeaders(aHeaders),
105 mBodyLength(InternalResponse::UNKNOWN_BODY_SIZE),
106 mContentPolicyType(aContentPolicyType),
107 mReferrer(aReferrer),
108 mReferrerPolicy(aReferrerPolicy),
109 mEnvironmentReferrerPolicy(ReferrerPolicy::_empty),
110 mMode(aMode),
111 mCredentialsMode(aRequestCredentials),
112 mCacheMode(aCacheMode),
113 mRedirectMode(aRequestRedirect),
114 mIntegrity(aIntegrity) {
115 MOZ_ASSERT(!aURL.IsEmpty());
116 AddURL(aURL, aFragment);
118 InternalRequest::InternalRequest(const InternalRequest& aOther,
119 ConstructorGuard)
120 : mMethod(aOther.mMethod),
121 mURLList(aOther.mURLList.Clone()),
122 mHeaders(new InternalHeaders(*aOther.mHeaders)),
123 mBodyLength(InternalResponse::UNKNOWN_BODY_SIZE),
124 mContentPolicyType(aOther.mContentPolicyType),
125 mReferrer(aOther.mReferrer),
126 mReferrerPolicy(aOther.mReferrerPolicy),
127 mEnvironmentReferrerPolicy(aOther.mEnvironmentReferrerPolicy),
128 mMode(aOther.mMode),
129 mCredentialsMode(aOther.mCredentialsMode),
130 mResponseTainting(aOther.mResponseTainting),
131 mCacheMode(aOther.mCacheMode),
132 mRedirectMode(aOther.mRedirectMode),
133 mIntegrity(aOther.mIntegrity),
134 mMozErrors(aOther.mMozErrors),
135 mFragment(aOther.mFragment),
136 mSkipServiceWorker(aOther.mSkipServiceWorker),
137 mSynchronous(aOther.mSynchronous),
138 mUnsafeRequest(aOther.mUnsafeRequest),
139 mUseURLCredentials(aOther.mUseURLCredentials),
140 mContentPolicyTypeOverridden(aOther.mContentPolicyTypeOverridden) {
141 // NOTE: does not copy body stream... use the fallible Clone() for that
144 InternalRequest::InternalRequest(const IPCInternalRequest& aIPCRequest)
145 : mMethod(aIPCRequest.method()),
146 mURLList(aIPCRequest.urlList().Clone()),
147 mHeaders(new InternalHeaders(aIPCRequest.headers(),
148 aIPCRequest.headersGuard())),
149 mBodyLength(aIPCRequest.bodySize()),
150 mPreferredAlternativeDataType(aIPCRequest.preferredAlternativeDataType()),
151 mContentPolicyType(
152 static_cast<nsContentPolicyType>(aIPCRequest.contentPolicyType())),
153 mReferrer(aIPCRequest.referrer()),
154 mReferrerPolicy(aIPCRequest.referrerPolicy()),
155 mMode(aIPCRequest.requestMode()),
156 mCredentialsMode(aIPCRequest.requestCredentials()),
157 mCacheMode(aIPCRequest.cacheMode()),
158 mRedirectMode(aIPCRequest.requestRedirect()),
159 mIntegrity(aIPCRequest.integrity()),
160 mFragment(aIPCRequest.fragment()) {
161 if (aIPCRequest.principalInfo()) {
162 mPrincipalInfo = MakeUnique<mozilla::ipc::PrincipalInfo>(
163 aIPCRequest.principalInfo().ref());
166 const Maybe<BodyStreamVariant>& body = aIPCRequest.body();
168 // This constructor is (currently) only used for parent -> child communication
169 // (constructed on the child side).
170 if (body) {
171 MOZ_ASSERT(body->type() == BodyStreamVariant::TParentToChildStream);
172 mBodyStream = static_cast<RemoteLazyInputStreamChild*>(
173 body->get_ParentToChildStream().actorChild())
174 ->CreateStream();
178 InternalRequest::~InternalRequest() = default;
180 void InternalRequest::SetContentPolicyType(
181 nsContentPolicyType aContentPolicyType) {
182 mContentPolicyType = aContentPolicyType;
185 void InternalRequest::OverrideContentPolicyType(
186 nsContentPolicyType aContentPolicyType) {
187 SetContentPolicyType(aContentPolicyType);
188 mContentPolicyTypeOverridden = true;
191 /* static */
192 RequestDestination InternalRequest::MapContentPolicyTypeToRequestDestination(
193 nsContentPolicyType aContentPolicyType) {
194 switch (aContentPolicyType) {
195 case nsIContentPolicy::TYPE_OTHER:
196 return RequestDestination::_empty;
197 case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
198 case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
199 case nsIContentPolicy::TYPE_INTERNAL_MODULE:
200 case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
201 case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER:
202 case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS:
203 case nsIContentPolicy::TYPE_INTERNAL_CHROMEUTILS_COMPILED_SCRIPT:
204 case nsIContentPolicy::TYPE_INTERNAL_FRAME_MESSAGEMANAGER_SCRIPT:
205 case nsIContentPolicy::TYPE_SCRIPT:
206 return RequestDestination::Script;
207 case nsIContentPolicy::TYPE_INTERNAL_WORKER:
208 return RequestDestination::Worker;
209 case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
210 return RequestDestination::Sharedworker;
211 case nsIContentPolicy::TYPE_IMAGESET:
212 case nsIContentPolicy::TYPE_INTERNAL_IMAGE:
213 case nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD:
214 case nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON:
215 case nsIContentPolicy::TYPE_IMAGE:
216 return RequestDestination::Image;
217 case nsIContentPolicy::TYPE_STYLESHEET:
218 case nsIContentPolicy::TYPE_INTERNAL_STYLESHEET:
219 case nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD:
220 return RequestDestination::Style;
221 case nsIContentPolicy::TYPE_OBJECT:
222 case nsIContentPolicy::TYPE_INTERNAL_OBJECT:
223 return RequestDestination::Object;
224 case nsIContentPolicy::TYPE_INTERNAL_EMBED:
225 return RequestDestination::Embed;
226 case nsIContentPolicy::TYPE_DOCUMENT:
227 return RequestDestination::Document;
228 case nsIContentPolicy::TYPE_SUBDOCUMENT:
229 case nsIContentPolicy::TYPE_INTERNAL_IFRAME:
230 return RequestDestination::Iframe;
231 case nsIContentPolicy::TYPE_INTERNAL_FRAME:
232 return RequestDestination::Frame;
233 case nsIContentPolicy::TYPE_PING:
234 return RequestDestination::_empty;
235 case nsIContentPolicy::TYPE_XMLHTTPREQUEST:
236 case nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST:
237 return RequestDestination::_empty;
238 case nsIContentPolicy::TYPE_INTERNAL_EVENTSOURCE:
239 return RequestDestination::_empty;
240 case nsIContentPolicy::TYPE_OBJECT_SUBREQUEST:
241 return RequestDestination::_empty;
242 case nsIContentPolicy::TYPE_DTD:
243 case nsIContentPolicy::TYPE_INTERNAL_DTD:
244 case nsIContentPolicy::TYPE_INTERNAL_FORCE_ALLOWED_DTD:
245 return RequestDestination::_empty;
246 case nsIContentPolicy::TYPE_FONT:
247 case nsIContentPolicy::TYPE_INTERNAL_FONT_PRELOAD:
248 return RequestDestination::Font;
249 case nsIContentPolicy::TYPE_MEDIA:
250 return RequestDestination::_empty;
251 case nsIContentPolicy::TYPE_INTERNAL_AUDIO:
252 return RequestDestination::Audio;
253 case nsIContentPolicy::TYPE_INTERNAL_VIDEO:
254 return RequestDestination::Video;
255 case nsIContentPolicy::TYPE_INTERNAL_TRACK:
256 return RequestDestination::Track;
257 case nsIContentPolicy::TYPE_WEBSOCKET:
258 return RequestDestination::_empty;
259 case nsIContentPolicy::TYPE_CSP_REPORT:
260 return RequestDestination::Report;
261 case nsIContentPolicy::TYPE_XSLT:
262 return RequestDestination::Xslt;
263 case nsIContentPolicy::TYPE_BEACON:
264 return RequestDestination::_empty;
265 case nsIContentPolicy::TYPE_FETCH:
266 case nsIContentPolicy::TYPE_INTERNAL_FETCH_PRELOAD:
267 return RequestDestination::_empty;
268 case nsIContentPolicy::TYPE_WEB_MANIFEST:
269 return RequestDestination::Manifest;
270 case nsIContentPolicy::TYPE_SAVEAS_DOWNLOAD:
271 return RequestDestination::_empty;
272 case nsIContentPolicy::TYPE_SPECULATIVE:
273 return RequestDestination::_empty;
274 case nsIContentPolicy::TYPE_INTERNAL_AUDIOWORKLET:
275 return RequestDestination::Audioworklet;
276 case nsIContentPolicy::TYPE_INTERNAL_PAINTWORKLET:
277 return RequestDestination::Paintworklet;
278 case nsIContentPolicy::TYPE_INVALID:
279 break;
280 // Do not add default: so that compilers can catch the missing case.
283 MOZ_ASSERT(false, "Unhandled nsContentPolicyType value");
284 return RequestDestination::_empty;
287 // static
288 bool InternalRequest::IsNavigationContentPolicy(
289 nsContentPolicyType aContentPolicyType) {
290 // https://fetch.spec.whatwg.org/#navigation-request-context
292 // A navigation request context is one of "form", "frame", "hyperlink",
293 // "iframe", "internal" (as long as context frame type is not "none"),
294 // "location", "metarefresh", and "prerender".
296 // Note, all of these request types are effectively initiated by nsDocShell.
297 return aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT ||
298 aContentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT ||
299 aContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_FRAME ||
300 aContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_IFRAME;
303 // static
304 bool InternalRequest::IsWorkerContentPolicy(
305 nsContentPolicyType aContentPolicyType) {
306 // https://fetch.spec.whatwg.org/#worker-request-context
308 // A worker request context is one of "serviceworker", "sharedworker", and
309 // "worker".
311 // Note, service workers are not included here because currently there is
312 // no way to generate a Request with a "serviceworker" RequestDestination.
313 // ServiceWorker scripts cannot be intercepted.
314 return aContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
315 aContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER;
318 bool InternalRequest::IsNavigationRequest() const {
319 return IsNavigationContentPolicy(mContentPolicyType);
322 bool InternalRequest::IsWorkerRequest() const {
323 return IsWorkerContentPolicy(mContentPolicyType);
326 bool InternalRequest::IsClientRequest() const {
327 return IsNavigationRequest() || IsWorkerRequest();
330 // static
331 RequestMode InternalRequest::MapChannelToRequestMode(nsIChannel* aChannel) {
332 MOZ_ASSERT(aChannel);
334 nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
336 nsContentPolicyType contentPolicy = loadInfo->InternalContentPolicyType();
337 if (IsNavigationContentPolicy(contentPolicy)) {
338 return RequestMode::Navigate;
341 // TODO: remove the worker override once securityMode is fully implemented
342 // (bug 1189945)
343 if (IsWorkerContentPolicy(contentPolicy)) {
344 return RequestMode::Same_origin;
347 uint32_t securityMode = loadInfo->GetSecurityMode();
349 switch (securityMode) {
350 case nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_INHERITS_SEC_CONTEXT:
351 case nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED:
352 return RequestMode::Same_origin;
353 case nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT:
354 case nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL:
355 return RequestMode::No_cors;
356 case nsILoadInfo::SEC_REQUIRE_CORS_INHERITS_SEC_CONTEXT:
357 // TODO: Check additional flag force-preflight after bug 1199693 (bug
358 // 1189945)
359 return RequestMode::Cors;
360 default:
361 MOZ_ASSERT_UNREACHABLE("Unexpected security mode!");
362 return RequestMode::Same_origin;
366 // static
367 RequestCredentials InternalRequest::MapChannelToRequestCredentials(
368 nsIChannel* aChannel) {
369 MOZ_ASSERT(aChannel);
371 nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
373 uint32_t cookiePolicy = loadInfo->GetCookiePolicy();
375 if (cookiePolicy == nsILoadInfo::SEC_COOKIES_INCLUDE) {
376 return RequestCredentials::Include;
377 } else if (cookiePolicy == nsILoadInfo::SEC_COOKIES_OMIT) {
378 return RequestCredentials::Omit;
379 } else if (cookiePolicy == nsILoadInfo::SEC_COOKIES_SAME_ORIGIN) {
380 return RequestCredentials::Same_origin;
383 MOZ_ASSERT_UNREACHABLE("Unexpected cookie policy!");
384 return RequestCredentials::Same_origin;
387 void InternalRequest::MaybeSkipCacheIfPerformingRevalidation() {
388 if (mCacheMode == RequestCache::Default &&
389 mHeaders->HasRevalidationHeaders()) {
390 mCacheMode = RequestCache::No_store;
394 void InternalRequest::SetPrincipalInfo(
395 UniquePtr<mozilla::ipc::PrincipalInfo> aPrincipalInfo) {
396 mPrincipalInfo = std::move(aPrincipalInfo);
399 } // namespace mozilla::dom