/* 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_FetchService_h #define _mozilla_dom_FetchService_h #include "nsIChannel.h" #include "nsIObserver.h" #include "nsTHashMap.h" #include "mozilla/ErrorResult.h" #include "mozilla/MozPromise.h" #include "mozilla/RefPtr.h" #include "mozilla/dom/FetchDriver.h" #include "mozilla/dom/FetchTypes.h" #include "mozilla/dom/PerformanceTimingTypes.h" #include "mozilla/dom/SafeRefPtr.h" class nsILoadGroup; class nsIPrincipal; class nsICookieJarSettings; class PerformanceStorage; namespace mozilla::dom { class InternalRequest; class InternalResponse; using FetchServiceResponse = SafeRefPtr; using FetchServiceResponseAvailablePromise = MozPromise; using FetchServiceResponseEndPromise = MozPromise; class FetchServicePromises final { NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FetchServicePromises); public: FetchServicePromises(); RefPtr GetResponseAvailablePromise(); RefPtr GetResponseEndPromise(); void ResolveResponseAvailablePromise(FetchServiceResponse&& aResponse, const char* aMethodName); void RejectResponseAvailablePromise(const CopyableErrorResult&& aError, const char* aMethodName); void ResolveResponseEndPromise(ResponseEndArgs&& aArgs, const char* aMethodName); void RejectResponseEndPromise(const CopyableErrorResult&& aError, const char* aMethodName); private: ~FetchServicePromises() = default; RefPtr mAvailablePromise; RefPtr mEndPromise; }; /** * FetchService is a singleton object which designed to be used in parent * process main thread only. It is used to handle the special fetch requests * from ServiceWorkers(by Navigation Preload) and PFetch. * * FetchService creates FetchInstance internally to represent each Fetch * request. It supports an asynchronous fetching, FetchServicePromises is * created when a Fetch starts, once the response is ready or any error happens, * the FetchServicePromises would be resolved or rejected. The promises * consumers can set callbacks to handle the Fetch result. */ class FetchService final : public nsIObserver { public: NS_DECL_ISUPPORTS; NS_DECL_NSIOBSERVER; static already_AddRefed GetInstance(); static RefPtr NetworkErrorResponse(nsresult aRv); FetchService(); // This method creates a FetchInstance to trigger fetch. // The created FetchInstance is saved in mFetchInstanceTable RefPtr Fetch(SafeRefPtr aRequest, nsIChannel* aChannel = nullptr); void CancelFetch(RefPtr&& aPromises); private: /** * FetchInstance is an internal representation for each Fetch created by * FetchService. * FetchInstance is also a FetchDriverObserver which has responsibility to * resolve/reject the FetchServicePromises. * FetchInstance triggers fetch by instancing a FetchDriver with proper * initialization. The general usage flow of FetchInstance is as follows * * RefPtr fetch = MakeRefPtr(aResquest); * fetch->Initialize(); * RefPtr fetch->Fetch(); */ class FetchInstance final : public FetchDriverObserver { public: explicit FetchInstance(SafeRefPtr aRequest); // This method is used for initialize the fetch. // It accepts a nsIChannel for initialization, this is for the navigation // preload case since there has already been an intercepted channel for // dispatching fetch event, and needed information can be gotten from the // intercepted channel. // For other case, the fetch needed information be created according to the // mRequest nsresult Initialize(nsIChannel* aChannel = nullptr); RefPtr Fetch(); void Cancel(); /* FetchDriverObserver interface */ void OnResponseEnd(FetchDriverObserver::EndReason aReason, JS::Handle aReasonDetails) override; void OnResponseAvailableInternal( SafeRefPtr aResponse) override; bool NeedOnDataAvailable() override; void OnDataAvailable() override; void FlushConsoleReport() override; private: ~FetchInstance(); SafeRefPtr mRequest; nsCOMPtr mPrincipal; nsCOMPtr mLoadGroup; nsCOMPtr mCookieJarSettings; RefPtr mPerformanceStorage; RefPtr mFetchDriver; SafeRefPtr mResponse; RefPtr mPromises; }; ~FetchService(); nsresult RegisterNetworkObserver(); nsresult UnregisterNetworkObserver(); // This is a container to manage the generated fetches. nsTHashMap, RefPtr > mFetchInstanceTable; bool mObservingNetwork{false}; bool mOffline{false}; }; } // namespace mozilla::dom #endif // _mozilla_dom_FetchService_h