Bug 1881621 - Add colors/color_canvas.html tests to dom/canvas/test/reftest. r=bradwerth
[gecko.git] / dom / fetch / InternalResponse.h
blobe8a492a3141013b9301382e25ef209a06df94ffb
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_InternalResponse_h
8 #define mozilla_dom_InternalResponse_h
10 #include "mozilla/dom/FetchTypes.h"
11 #include "nsIInputStream.h"
12 #include "nsICacheInfoChannel.h"
13 #include "nsISupportsImpl.h"
14 #include "nsProxyRelease.h"
16 #include "mozilla/dom/InternalHeaders.h"
17 #include "mozilla/dom/RequestBinding.h"
18 #include "mozilla/dom/ResponseBinding.h"
19 #include "mozilla/dom/ChannelInfo.h"
20 #include "mozilla/dom/SafeRefPtr.h"
21 #include "mozilla/NotNull.h"
22 #include "mozilla/UniquePtr.h"
24 namespace mozilla {
25 namespace ipc {
26 class PBackgroundChild;
27 class PBackgroundParent;
28 class PrincipalInfo;
29 } // namespace ipc
31 namespace dom {
33 class ChildToParentInternalResponse;
34 class InternalHeaders;
35 class ParentToChildInternalResponse;
36 class ParentToParentInternalResponse;
38 class InternalResponse final : public AtomicSafeRefCounted<InternalResponse> {
39 friend class FetchDriver;
41 public:
42 MOZ_DECLARE_REFCOUNTED_TYPENAME(InternalResponse)
44 InternalResponse(
45 uint16_t aStatus, const nsACString& aStatusText,
46 RequestCredentials aCredentialsMode = RequestCredentials::Omit);
48 static SafeRefPtr<InternalResponse> FromIPC(
49 const ParentToChildInternalResponse& aIPCResponse);
51 static SafeRefPtr<InternalResponse> FromIPC(
52 const ParentToParentInternalResponse& aIPCResponse);
54 void ToChildToParentInternalResponse(
55 ChildToParentInternalResponse* aIPCResponse,
56 mozilla::ipc::PBackgroundChild* aManager);
58 ParentToParentInternalResponse ToParentToParentInternalResponse();
60 ParentToChildInternalResponse ToParentToChildInternalResponse(
61 NotNull<mozilla::ipc::PBackgroundParent*> aBackgroundParent);
63 enum CloneType {
64 eCloneInputStream,
65 eDontCloneInputStream,
68 SafeRefPtr<InternalResponse> Clone(CloneType aCloneType);
70 static SafeRefPtr<InternalResponse> NetworkError(nsresult aRv) {
71 MOZ_DIAGNOSTIC_ASSERT(NS_FAILED(aRv));
72 SafeRefPtr<InternalResponse> response =
73 MakeSafeRefPtr<InternalResponse>(0, ""_ns);
74 ErrorResult result;
75 response->Headers()->SetGuard(HeadersGuardEnum::Immutable, result);
76 MOZ_ASSERT(!result.Failed());
77 response->mType = ResponseType::Error;
78 response->mErrorCode = aRv;
79 return response;
82 SafeRefPtr<InternalResponse> OpaqueResponse();
84 SafeRefPtr<InternalResponse> OpaqueRedirectResponse();
86 SafeRefPtr<InternalResponse> BasicResponse();
88 SafeRefPtr<InternalResponse> CORSResponse();
90 ResponseType Type() const {
91 MOZ_ASSERT_IF(mType == ResponseType::Error, !mWrappedResponse);
92 MOZ_ASSERT_IF(mType == ResponseType::Default, !mWrappedResponse);
93 MOZ_ASSERT_IF(mType == ResponseType::Basic, mWrappedResponse);
94 MOZ_ASSERT_IF(mType == ResponseType::Cors, mWrappedResponse);
95 MOZ_ASSERT_IF(mType == ResponseType::Opaque, mWrappedResponse);
96 MOZ_ASSERT_IF(mType == ResponseType::Opaqueredirect, mWrappedResponse);
97 return mType;
100 bool IsError() const { return Type() == ResponseType::Error; }
101 // GetUrl should return last fetch URL in response's url list and null if
102 // response's url list is the empty list.
103 const nsCString& GetURL() const {
104 // Empty urlList when response is a synthetic response.
105 if (mURLList.IsEmpty()) {
106 return EmptyCString();
108 return mURLList.LastElement();
110 void GetURLList(nsTArray<nsCString>& aURLList) const {
111 aURLList.Assign(mURLList);
113 const nsCString& GetUnfilteredURL() const {
114 if (mWrappedResponse) {
115 return mWrappedResponse->GetURL();
117 return GetURL();
119 void GetUnfilteredURLList(nsTArray<nsCString>& aURLList) const {
120 if (mWrappedResponse) {
121 return mWrappedResponse->GetURLList(aURLList);
124 return GetURLList(aURLList);
127 nsTArray<nsCString> GetUnfilteredURLList() const {
128 nsTArray<nsCString> list;
129 GetUnfilteredURLList(list);
130 return list;
133 void SetURLList(const nsTArray<nsCString>& aURLList) {
134 mURLList.Assign(aURLList);
136 #ifdef DEBUG
137 for (uint32_t i = 0; i < mURLList.Length(); ++i) {
138 MOZ_ASSERT(mURLList[i].Find("#"_ns) == kNotFound);
140 #endif
143 uint16_t GetStatus() const { return mStatus; }
145 uint16_t GetUnfilteredStatus() const {
146 if (mWrappedResponse) {
147 return mWrappedResponse->GetStatus();
150 return GetStatus();
153 const nsCString& GetStatusText() const { return mStatusText; }
155 const nsCString& GetUnfilteredStatusText() const {
156 if (mWrappedResponse) {
157 return mWrappedResponse->GetStatusText();
160 return GetStatusText();
163 InternalHeaders* Headers() { return mHeaders; }
165 InternalHeaders* UnfilteredHeaders() {
166 if (mWrappedResponse) {
167 return mWrappedResponse->Headers();
170 return Headers();
173 void GetUnfilteredBody(nsIInputStream** aStream,
174 int64_t* aBodySize = nullptr) {
175 if (mWrappedResponse) {
176 MOZ_ASSERT(!mBody);
177 return mWrappedResponse->GetBody(aStream, aBodySize);
179 nsCOMPtr<nsIInputStream> stream = mBody;
180 stream.forget(aStream);
181 if (aBodySize) {
182 *aBodySize = mBodySize;
186 void GetBody(nsIInputStream** aStream, int64_t* aBodySize = nullptr) {
187 if (Type() == ResponseType::Opaque ||
188 Type() == ResponseType::Opaqueredirect) {
189 *aStream = nullptr;
190 if (aBodySize) {
191 *aBodySize = UNKNOWN_BODY_SIZE;
193 return;
196 GetUnfilteredBody(aStream, aBodySize);
199 void SetBodyBlobURISpec(nsACString& aBlobURISpec) {
200 mBodyBlobURISpec = aBlobURISpec;
203 const nsACString& BodyBlobURISpec() const {
204 if (mWrappedResponse) {
205 return mWrappedResponse->BodyBlobURISpec();
207 return mBodyBlobURISpec;
210 void SetBodyLocalPath(nsAString& aLocalPath) { mBodyLocalPath = aLocalPath; }
212 const nsAString& BodyLocalPath() const {
213 if (mWrappedResponse) {
214 return mWrappedResponse->BodyLocalPath();
216 return mBodyLocalPath;
219 void SetBody(nsIInputStream* aBody, int64_t aBodySize) {
220 if (mWrappedResponse) {
221 return mWrappedResponse->SetBody(aBody, aBodySize);
223 // A request's body may not be reset once set.
224 MOZ_ASSERT(!mBody);
225 MOZ_ASSERT(mBodySize == UNKNOWN_BODY_SIZE);
226 // Check arguments.
227 MOZ_ASSERT(aBodySize == UNKNOWN_BODY_SIZE || aBodySize >= 0);
228 // If body is not given, then size must be unknown.
229 MOZ_ASSERT_IF(!aBody, aBodySize == UNKNOWN_BODY_SIZE);
231 mBody = aBody;
232 mBodySize = aBodySize;
235 uint32_t GetPaddingInfo();
237 nsresult GeneratePaddingInfo();
239 int64_t GetPaddingSize();
241 void SetPaddingSize(int64_t aPaddingSize);
243 void SetAlternativeDataType(const nsACString& aAltDataType) {
244 if (mWrappedResponse) {
245 return mWrappedResponse->SetAlternativeDataType(aAltDataType);
248 MOZ_DIAGNOSTIC_ASSERT(mAlternativeDataType.IsEmpty());
250 mAlternativeDataType.Assign(aAltDataType);
253 const nsCString& GetAlternativeDataType() {
254 if (mWrappedResponse) {
255 return mWrappedResponse->GetAlternativeDataType();
258 return mAlternativeDataType;
261 void SetAlternativeBody(nsIInputStream* aAlternativeBody) {
262 if (mWrappedResponse) {
263 return mWrappedResponse->SetAlternativeBody(aAlternativeBody);
265 // A request's body may not be reset once set.
266 MOZ_DIAGNOSTIC_ASSERT(!mAlternativeBody);
268 mAlternativeBody = aAlternativeBody;
271 already_AddRefed<nsIInputStream> TakeAlternativeBody() {
272 if (mWrappedResponse) {
273 return mWrappedResponse->TakeAlternativeBody();
276 if (!mAlternativeBody) {
277 return nullptr;
280 // cleanup the non-alternative body here.
281 // Once alternative data is used, the real body is no need anymore.
282 mBody = nullptr;
283 mBodySize = UNKNOWN_BODY_SIZE;
284 return mAlternativeBody.forget();
287 void SetCacheInfoChannel(
288 const nsMainThreadPtrHandle<nsICacheInfoChannel>& aCacheInfoChannel) {
289 if (mWrappedResponse) {
290 return mWrappedResponse->SetCacheInfoChannel(aCacheInfoChannel);
292 MOZ_ASSERT(!mCacheInfoChannel);
293 mCacheInfoChannel = aCacheInfoChannel;
296 nsMainThreadPtrHandle<nsICacheInfoChannel> TakeCacheInfoChannel() {
297 if (mWrappedResponse) {
298 return mWrappedResponse->TakeCacheInfoChannel();
300 nsMainThreadPtrHandle<nsICacheInfoChannel> rtn = mCacheInfoChannel;
301 mCacheInfoChannel = nullptr;
302 return rtn;
305 bool HasCacheInfoChannel() const {
306 if (mWrappedResponse) {
307 return !!mWrappedResponse->HasCacheInfoChannel();
309 return !!mCacheInfoChannel;
312 bool HasBeenCloned() const { return mCloned; }
314 void SetSerializeAsLazy(bool aAllow) { mSerializeAsLazy = aAllow; }
315 bool CanSerializeAsLazy() const { return mSerializeAsLazy; }
317 void InitChannelInfo(nsIChannel* aChannel) {
318 mChannelInfo.InitFromChannel(aChannel);
321 void InitChannelInfo(nsITransportSecurityInfo* aSecurityInfo) {
322 mChannelInfo.InitFromTransportSecurityInfo(aSecurityInfo);
325 void InitChannelInfo(const ChannelInfo& aChannelInfo) {
326 mChannelInfo = aChannelInfo;
329 const ChannelInfo& GetChannelInfo() const { return mChannelInfo; }
331 const UniquePtr<mozilla::ipc::PrincipalInfo>& GetPrincipalInfo() const {
332 return mPrincipalInfo;
335 bool IsRedirected() const { return mURLList.Length() > 1; }
337 nsresult GetErrorCode() const { return mErrorCode; }
339 // Takes ownership of the principal info.
340 void SetPrincipalInfo(UniquePtr<mozilla::ipc::PrincipalInfo> aPrincipalInfo);
342 LoadTainting GetTainting() const;
344 SafeRefPtr<InternalResponse> Unfiltered();
346 InternalResponseMetadata GetMetadata();
348 RequestCredentials GetCredentialsMode() const {
349 if (mWrappedResponse) {
350 return mWrappedResponse->GetCredentialsMode();
352 return mCredentialsMode;
355 ~InternalResponse();
357 private:
358 explicit InternalResponse(const InternalResponse& aOther) = delete;
359 InternalResponse& operator=(const InternalResponse&) = delete;
361 // Returns an instance of InternalResponse which is a copy of this
362 // InternalResponse, except headers, body and wrapped response (if any) which
363 // are left uninitialized. Used for cloning and filtering.
364 SafeRefPtr<InternalResponse> CreateIncompleteCopy();
366 template <typename T>
367 static SafeRefPtr<InternalResponse> FromIPCTemplate(const T& aIPCResponse);
369 ResponseType mType;
370 // A response has an associated url list (a list of zero or more fetch URLs).
371 // Unless stated otherwise, it is the empty list. The current url is the last
372 // element in mURLlist
373 nsTArray<nsCString> mURLList;
374 const uint16_t mStatus;
375 const nsCString mStatusText;
376 RefPtr<InternalHeaders> mHeaders;
377 nsCOMPtr<nsIInputStream> mBody;
378 nsCString mBodyBlobURISpec;
379 nsString mBodyLocalPath;
380 int64_t mBodySize;
381 // It's used to passed to the CacheResponse to generate padding size. Once, we
382 // generate the padding size for resposne, we don't need it anymore.
383 Maybe<uint32_t> mPaddingInfo;
384 int64_t mPaddingSize;
385 nsresult mErrorCode;
386 RequestCredentials mCredentialsMode;
388 // For alternative data such as JS Bytecode cached in the HTTP cache.
389 nsCString mAlternativeDataType;
390 nsCOMPtr<nsIInputStream> mAlternativeBody;
391 nsMainThreadPtrHandle<nsICacheInfoChannel> mCacheInfoChannel;
392 bool mCloned;
393 // boolean to indicate the body/alternativeBody will be serialized as a
394 // RemoteLazyInputStream.
395 bool mSerializeAsLazy{true};
397 public:
398 static constexpr int64_t UNKNOWN_BODY_SIZE = -1;
399 static constexpr int64_t UNKNOWN_PADDING_SIZE = -1;
401 private:
402 ChannelInfo mChannelInfo;
403 UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
405 // For filtered responses.
406 // Cache, and SW interception should always serialize/access the underlying
407 // unfiltered headers and when deserializing, create an InternalResponse
408 // with the unfiltered headers followed by wrapping it.
409 SafeRefPtr<InternalResponse> mWrappedResponse;
412 ParentToChildInternalResponse ToParentToChild(
413 const ParentToParentInternalResponse& aResponse,
414 NotNull<mozilla::ipc::PBackgroundParent*> aBackgroundParent);
416 } // namespace dom
417 } // namespace mozilla
419 #endif // mozilla_dom_InternalResponse_h