summaryrefslogtreecommitdiffstats
path: root/dom/fetch/FetchService.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/fetch/FetchService.h')
-rw-r--r--dom/fetch/FetchService.h186
1 files changed, 186 insertions, 0 deletions
diff --git a/dom/fetch/FetchService.h b/dom/fetch/FetchService.h
new file mode 100644
index 0000000000..3032c4d2a9
--- /dev/null
+++ b/dom/fetch/FetchService.h
@@ -0,0 +1,186 @@
+/* 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"
+#include "mozilla/ipc/PBackgroundSharedTypes.h"
+#include "mozilla/net/NeckoChannelParams.h"
+
+class nsILoadGroup;
+class nsIPrincipal;
+class nsICookieJarSettings;
+class PerformanceStorage;
+
+namespace mozilla::dom {
+
+class InternalRequest;
+class InternalResponse;
+class ClientInfo;
+class ServiceWorkerDescriptor;
+
+using FetchServiceResponse = SafeRefPtr<InternalResponse>;
+using FetchServiceResponseAvailablePromise =
+ MozPromise<FetchServiceResponse, CopyableErrorResult, true>;
+using FetchServiceResponseTimingPromise =
+ MozPromise<ResponseTiming, CopyableErrorResult, true>;
+using FetchServiceResponseEndPromise =
+ MozPromise<ResponseEndArgs, CopyableErrorResult, true>;
+
+class FetchServicePromises final {
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FetchServicePromises);
+
+ public:
+ FetchServicePromises();
+
+ RefPtr<FetchServiceResponseAvailablePromise> GetResponseAvailablePromise();
+ RefPtr<FetchServiceResponseTimingPromise> GetResponseTimingPromise();
+ RefPtr<FetchServiceResponseEndPromise> GetResponseEndPromise();
+
+ void ResolveResponseAvailablePromise(FetchServiceResponse&& aResponse,
+ const char* aMethodName);
+ void RejectResponseAvailablePromise(const CopyableErrorResult&& aError,
+ const char* aMethodName);
+ void ResolveResponseTimingPromise(ResponseTiming&& aTiming,
+ const char* aMethodName);
+ void RejectResponseTimingPromise(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<FetchServiceResponseAvailablePromise::Private> mAvailablePromise;
+ RefPtr<FetchServiceResponseTimingPromise::Private> mTimingPromise;
+ RefPtr<FetchServiceResponseEndPromise::Private> 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
+
+ struct NavigationPreloadArgs {
+ SafeRefPtr<InternalRequest> mRequest;
+ nsCOMPtr<nsIChannel> mChannel;
+ };
+
+ struct WorkerFetchArgs {
+ SafeRefPtr<InternalRequest> mRequest;
+ mozilla::ipc::PrincipalInfo mPrincipalInfo;
+ nsCString mWorkerScript;
+ Maybe<ClientInfo> mClientInfo;
+ Maybe<ServiceWorkerDescriptor> mController;
+ Maybe<net::CookieJarSettingsArgs> mCookieJarSettings;
+ bool mNeedOnDataAvailable;
+ nsCOMPtr<nsICSPEventListener> mCSPEventListener;
+ uint64_t mAssociatedBrowsingContextID;
+ nsCOMPtr<nsISerialEventTarget> mEventTarget;
+ nsID mActorID;
+ };
+
+ struct UnknownArgs {};
+
+ using FetchArgs =
+ Variant<NavigationPreloadArgs, WorkerFetchArgs, UnknownArgs>;
+
+ static already_AddRefed<FetchService> GetInstance();
+
+ static RefPtr<FetchServicePromises> NetworkErrorResponse(nsresult aRv);
+
+ FetchService();
+
+ // This method creates a FetchInstance to trigger fetch.
+ // The created FetchInstance is saved in mFetchInstanceTable
+ RefPtr<FetchServicePromises> Fetch(FetchArgs&& aArgs);
+
+ void CancelFetch(const RefPtr<FetchServicePromises>&& 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<FetchInstance> fetch = MakeRefPtr<FetchInstance>();
+ * fetch->Initialize(FetchArgs args);
+ * RefPtr<FetchServicePromises> fetch->Fetch();
+ */
+ class FetchInstance final : public FetchDriverObserver {
+ public:
+ FetchInstance() = default;
+
+ nsresult Initialize(FetchArgs&& aArgs);
+
+ RefPtr<FetchServicePromises> Fetch();
+
+ void Cancel();
+
+ /* FetchDriverObserver interface */
+ void OnResponseEnd(FetchDriverObserver::EndReason aReason,
+ JS::Handle<JS::Value> aReasonDetails) override;
+ void OnResponseAvailableInternal(
+ SafeRefPtr<InternalResponse> aResponse) override;
+ bool NeedOnDataAvailable() override;
+ void OnDataAvailable() override;
+ void FlushConsoleReport() override;
+ void OnReportPerformanceTiming() override;
+ void OnNotifyNetworkMonitorAlternateStack(uint64_t aChannelID) override;
+
+ private:
+ ~FetchInstance() = default;
+
+ SafeRefPtr<InternalRequest> mRequest;
+ nsCOMPtr<nsIPrincipal> mPrincipal;
+ nsCOMPtr<nsILoadGroup> mLoadGroup;
+ nsCOMPtr<nsICookieJarSettings> mCookieJarSettings;
+ RefPtr<PerformanceStorage> mPerformanceStorage;
+ FetchArgs mArgs{AsVariant(FetchService::UnknownArgs())};
+ RefPtr<FetchDriver> mFetchDriver;
+ SafeRefPtr<InternalResponse> mResponse;
+ RefPtr<FetchServicePromises> mPromises;
+ bool mIsWorkerFetch{false};
+ };
+
+ ~FetchService();
+
+ nsresult RegisterNetworkObserver();
+ nsresult UnregisterNetworkObserver();
+
+ // This is a container to manage the generated fetches.
+ nsTHashMap<nsRefPtrHashKey<FetchServicePromises>, RefPtr<FetchInstance> >
+ mFetchInstanceTable;
+ bool mObservingNetwork{false};
+ bool mOffline{false};
+};
+
+} // namespace mozilla::dom
+
+#endif // _mozilla_dom_FetchService_h