/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_InternalResponse_h #define mozilla_dom_InternalResponse_h #include "nsIInputStream.h" #include "nsISupportsImpl.h" #include "mozilla/dom/ResponseBinding.h" namespace mozilla { namespace dom { class InternalHeaders; class InternalResponse final { friend class FetchDriver; public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalResponse) InternalResponse(uint16_t aStatus, const nsACString& aStatusText); already_AddRefed Clone(); static already_AddRefed NetworkError() { nsRefPtr response = new InternalResponse(0, EmptyCString()); ErrorResult result; response->Headers()->SetGuard(HeadersGuardEnum::Immutable, result); MOZ_ASSERT(!result.Failed()); response->mType = ResponseType::Error; return response.forget(); } already_AddRefed OpaqueResponse() { MOZ_ASSERT(!mWrappedResponse, "Can't OpaqueResponse a already wrapped response"); nsRefPtr response = new InternalResponse(0, EmptyCString()); response->mType = ResponseType::Opaque; response->mTerminationReason = mTerminationReason; response->mURL = mURL; response->mFinalURL = mFinalURL; response->mSecurityInfo = mSecurityInfo; response->mWrappedResponse = this; return response.forget(); } already_AddRefed BasicResponse(); already_AddRefed CORSResponse(); ResponseType Type() const { MOZ_ASSERT_IF(mType == ResponseType::Error, !mWrappedResponse); MOZ_ASSERT_IF(mType == ResponseType::Default, !mWrappedResponse); MOZ_ASSERT_IF(mType == ResponseType::Basic, mWrappedResponse); MOZ_ASSERT_IF(mType == ResponseType::Cors, mWrappedResponse); MOZ_ASSERT_IF(mType == ResponseType::Opaque, mWrappedResponse); return mType; } bool IsError() const { return Type() == ResponseType::Error; } // FIXME(nsm): Return with exclude fragment. void GetUrl(nsCString& aURL) const { aURL.Assign(mURL); } void SetUrl(const nsACString& aURL) { mURL.Assign(aURL); } bool FinalURL() const { return mFinalURL; } void SetFinalURL(bool aFinalURL) { mFinalURL = aFinalURL; } uint16_t GetStatus() const { return mStatus; } const nsCString& GetStatusText() const { return mStatusText; } InternalHeaders* Headers() { return mHeaders; } InternalHeaders* UnfilteredHeaders() { if (mWrappedResponse) { return mWrappedResponse->Headers(); }; return Headers(); } void GetBody(nsIInputStream** aStream) { if (Type() == ResponseType::Opaque) { *aStream = nullptr; return; } if (mWrappedResponse) { MOZ_ASSERT(!mBody); return mWrappedResponse->GetBody(aStream); } nsCOMPtr stream = mBody; stream.forget(aStream); } void SetBody(nsIInputStream* aBody) { if (mWrappedResponse) { return mWrappedResponse->SetBody(aBody); } // A request's body may not be reset once set. MOZ_ASSERT(!mBody); mBody = aBody; } const nsCString& GetSecurityInfo() const { return mSecurityInfo; } void SetSecurityInfo(nsISupports* aSecurityInfo); void SetSecurityInfo(const nsCString& aSecurityInfo); private: ~InternalResponse() { } explicit InternalResponse(const InternalResponse& aOther) = delete; InternalResponse& operator=(const InternalResponse&) = delete; // Returns an instance of InternalResponse which is a copy of this // InternalResponse, except headers, body and wrapped response (if any) which // are left uninitialized. Used for cloning and filtering. already_AddRefed CreateIncompleteCopy() { nsRefPtr copy = new InternalResponse(mStatus, mStatusText); copy->mType = mType; copy->mTerminationReason = mTerminationReason; copy->mURL = mURL; copy->mFinalURL = mFinalURL; copy->mSecurityInfo = mSecurityInfo; return copy.forget(); } ResponseType mType; nsCString mTerminationReason; nsCString mURL; bool mFinalURL; const uint16_t mStatus; const nsCString mStatusText; nsRefPtr mHeaders; nsCOMPtr mBody; nsCString mSecurityInfo; // For filtered responses. // Cache, and SW interception should always serialize/access the underlying // unfiltered headers and when deserializing, create an InternalResponse // with the unfiltered headers followed by wrapping it. nsRefPtr mWrappedResponse; }; } // namespace dom } // namespace mozilla #endif // mozilla_dom_InternalResponse_h