summaryrefslogtreecommitdiffstats
path: root/netwerk/base/nsIOService.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--netwerk/base/nsIOService.h280
1 files changed, 280 insertions, 0 deletions
diff --git a/netwerk/base/nsIOService.h b/netwerk/base/nsIOService.h
new file mode 100644
index 0000000000..de6fe060fb
--- /dev/null
+++ b/netwerk/base/nsIOService.h
@@ -0,0 +1,280 @@
+/* -*- 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 nsIOService_h__
+#define nsIOService_h__
+
+#include "nsStringFwd.h"
+#include "nsIIOService.h"
+#include "nsTArray.h"
+#include "nsCOMPtr.h"
+#include "nsIObserver.h"
+#include "nsIWeakReferenceUtils.h"
+#include "nsINetUtil.h"
+#include "nsIChannelEventSink.h"
+#include "nsCategoryCache.h"
+#include "nsISpeculativeConnect.h"
+#include "nsWeakReference.h"
+#include "mozilla/Atomics.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/RWLock.h"
+#include "mozilla/net/ProtocolHandlerInfo.h"
+#include "prtime.h"
+#include "nsICaptivePortalService.h"
+#include "nsIObserverService.h"
+#include "nsTHashSet.h"
+#include "nsWeakReference.h"
+#include "nsNetCID.h"
+
+#define NS_N(x) (sizeof(x) / sizeof(*(x)))
+
+// We don't want to expose this observer topic.
+// Intended internal use only for remoting offline/inline events.
+// See Bug 552829
+#define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
+#define NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC "ipc:network:set-connectivity"
+
+class nsINetworkLinkService;
+class nsIPrefBranch;
+class nsIProtocolProxyService2;
+class nsIProxyInfo;
+class nsPISocketTransportService;
+
+namespace mozilla {
+class MemoryReportingProcess;
+namespace net {
+class NeckoChild;
+class nsAsyncRedirectVerifyHelper;
+class SocketProcessHost;
+class SocketProcessMemoryReporter;
+
+class nsIOService final : public nsIIOService,
+ public nsIObserver,
+ public nsINetUtil,
+ public nsISpeculativeConnect,
+ public nsSupportsWeakReference,
+ public nsIIOServiceInternal,
+ public nsIObserverService {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIIOSERVICE
+ NS_DECL_NSIOBSERVER
+ NS_DECL_NSINETUTIL
+ NS_DECL_NSISPECULATIVECONNECT
+ NS_DECL_NSIIOSERVICEINTERNAL
+ NS_DECL_NSIOBSERVERSERVICE
+
+ // Gets the singleton instance of the IO Service, creating it as needed
+ // Returns nullptr on out of memory or failure to initialize.
+ static already_AddRefed<nsIOService> GetInstance();
+
+ nsresult Init();
+ nsresult NewURI(const char* aSpec, nsIURI* aBaseURI, nsIURI** result,
+ nsIProtocolHandler** hdlrResult);
+
+ // Called by channels before a redirect happens. This notifies the global
+ // redirect observers.
+ nsresult AsyncOnChannelRedirect(nsIChannel* oldChan, nsIChannel* newChan,
+ uint32_t flags,
+ nsAsyncRedirectVerifyHelper* helper);
+
+ bool IsOffline() { return mOffline; }
+ PRIntervalTime LastOfflineStateChange() { return mLastOfflineStateChange; }
+ PRIntervalTime LastConnectivityChange() { return mLastConnectivityChange; }
+ PRIntervalTime LastNetworkLinkChange() { return mLastNetworkLinkChange; }
+ bool IsNetTearingDown() {
+ return mShutdown || mOfflineForProfileChange ||
+ mHttpHandlerAlreadyShutingDown;
+ }
+ PRIntervalTime NetTearingDownStarted() { return mNetTearingDownStarted; }
+
+ // nsHttpHandler is going to call this function to inform nsIOService that
+ // network is in process of tearing down. Moving nsHttpConnectionMgr::Shutdown
+ // to nsIOService caused problems (bug 1242755) so we doing it in this way. As
+ // soon as nsIOService gets notification that it is shutdown it is going to
+ // reset mHttpHandlerAlreadyShutingDown.
+ void SetHttpHandlerAlreadyShutingDown();
+
+ bool IsLinkUp();
+
+ // Converts an internal URI (e.g. one that has a username and password in
+ // it) into one which we can expose to the user, for example on the URL bar.
+ static already_AddRefed<nsIURI> CreateExposableURI(nsIURI*);
+
+ // Used to count the total number of HTTP requests made
+ void IncrementRequestNumber() { mTotalRequests++; }
+ uint32_t GetTotalRequestNumber() { return mTotalRequests; }
+ // Used to keep "race cache with network" stats
+ void IncrementCacheWonRequestNumber() { mCacheWon++; }
+ uint32_t GetCacheWonRequestNumber() { return mCacheWon; }
+ void IncrementNetWonRequestNumber() { mNetWon++; }
+ uint32_t GetNetWonRequestNumber() { return mNetWon; }
+
+ // Used to trigger a recheck of the captive portal status
+ nsresult RecheckCaptivePortal();
+
+ void OnProcessLaunchComplete(SocketProcessHost* aHost, bool aSucceeded);
+ void OnProcessUnexpectedShutdown(SocketProcessHost* aHost);
+ bool SocketProcessReady();
+ static void NotifySocketProcessPrefsChanged(const char* aName, void* aSelf);
+ void NotifySocketProcessPrefsChanged(const char* aName);
+ static bool UseSocketProcess(bool aCheckAgain = false);
+
+ bool IsSocketProcessLaunchComplete();
+
+ // Call func immediately if socket process is launched completely. Otherwise,
+ // |func| will be queued and then executed in the *main thread* once socket
+ // process is launced.
+ void CallOrWaitForSocketProcess(const std::function<void()>& aFunc);
+
+ int32_t SocketProcessPid();
+ SocketProcessHost* SocketProcess() { return mSocketProcess; }
+
+ friend SocketProcessMemoryReporter;
+ RefPtr<MemoryReportingProcess> GetSocketProcessMemoryReporter();
+
+ // Lookup the ProtocolHandlerInfo based on a given scheme.
+ // Safe to call from any thread.
+ ProtocolHandlerInfo LookupProtocolHandler(const nsACString& aScheme);
+
+ static void OnTLSPrefChange(const char* aPref, void* aSelf);
+
+ nsresult LaunchSocketProcess();
+
+ static bool TooManySocketProcessCrash();
+ static void IncreaseSocketProcessCrashCount();
+
+ private:
+ // These shouldn't be called directly:
+ // - construct using GetInstance
+ // - destroy using Release
+ nsIOService();
+ ~nsIOService();
+ nsresult SetConnectivityInternal(bool aConnectivity);
+
+ nsresult OnNetworkLinkEvent(const char* data);
+
+ nsresult InitializeCaptivePortalService();
+ nsresult RecheckCaptivePortalIfLocalRedirect(nsIChannel* newChan);
+
+ // Prefs wrangling
+ static void PrefsChanged(const char* pref, void* self);
+ void PrefsChanged(const char* pref = nullptr);
+ void ParsePortList(const char* pref, bool remove);
+
+ nsresult InitializeSocketTransportService();
+ nsresult InitializeNetworkLinkService();
+ nsresult InitializeProtocolProxyService();
+
+ // consolidated helper function
+ void LookupProxyInfo(nsIURI* aURI, nsIURI* aProxyURI, uint32_t aProxyFlags,
+ nsCString* aScheme, nsIProxyInfo** outPI);
+
+ nsresult NewChannelFromURIWithProxyFlagsInternal(
+ nsIURI* aURI, nsIURI* aProxyURI, uint32_t aProxyFlags,
+ nsINode* aLoadingNode, nsIPrincipal* aLoadingPrincipal,
+ nsIPrincipal* aTriggeringPrincipal,
+ const mozilla::Maybe<mozilla::dom::ClientInfo>& aLoadingClientInfo,
+ const mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor>& aController,
+ uint32_t aSecurityFlags, nsContentPolicyType aContentPolicyType,
+ uint32_t aSandboxFlags, bool aSkipCheckForBrokenURLOrZeroSized,
+ nsIChannel** result);
+
+ nsresult NewChannelFromURIWithProxyFlagsInternal(nsIURI* aURI,
+ nsIURI* aProxyURI,
+ uint32_t aProxyFlags,
+ nsILoadInfo* aLoadInfo,
+ nsIChannel** result);
+
+ nsresult SpeculativeConnectInternal(nsIURI* aURI, nsIPrincipal* aPrincipal,
+ nsIInterfaceRequestor* aCallbacks,
+ bool aAnonymous);
+
+ void DestroySocketProcess();
+
+ nsresult SetOfflineInternal(bool offline, bool notifySocketProcess = true);
+
+ bool UsesExternalProtocolHandler(const nsACString& aScheme)
+ MOZ_REQUIRES_SHARED(mLock);
+
+ private:
+ mozilla::Atomic<bool, mozilla::Relaxed> mOffline{true};
+ mozilla::Atomic<bool, mozilla::Relaxed> mOfflineForProfileChange{false};
+ bool mManageLinkStatus{false};
+ mozilla::Atomic<bool, mozilla::Relaxed> mConnectivity{true};
+
+ // Used to handle SetOffline() reentrancy. See the comment in
+ // SetOffline() for more details.
+ bool mSettingOffline{false};
+ bool mSetOfflineValue{false};
+
+ bool mSocketProcessLaunchComplete{false};
+
+ mozilla::Atomic<bool, mozilla::Relaxed> mShutdown{false};
+ mozilla::Atomic<bool, mozilla::Relaxed> mHttpHandlerAlreadyShutingDown{false};
+
+ nsCOMPtr<nsPISocketTransportService> mSocketTransportService;
+ nsCOMPtr<nsICaptivePortalService> mCaptivePortalService;
+ nsCOMPtr<nsINetworkLinkService> mNetworkLinkService;
+ bool mNetworkLinkServiceInitialized{false};
+
+ // cached categories
+ nsCategoryCache<nsIChannelEventSink> mChannelEventSinks{
+ NS_CHANNEL_EVENT_SINK_CATEGORY};
+
+ RWLock mLock{"nsIOService::mLock"};
+ nsTArray<int32_t> mRestrictedPortList MOZ_GUARDED_BY(mLock);
+ nsTArray<nsCString> mForceExternalSchemes MOZ_GUARDED_BY(mLock);
+ nsTHashMap<nsCString, RuntimeProtocolHandler> mRuntimeProtocolHandlers
+ MOZ_GUARDED_BY(mLock);
+
+ uint32_t mTotalRequests{0};
+ uint32_t mCacheWon{0};
+ uint32_t mNetWon{0};
+ static uint32_t sSocketProcessCrashedCount;
+
+ // These timestamps are needed for collecting telemetry on PR_Connect,
+ // PR_ConnectContinue and PR_Close blocking time. If we spend very long
+ // time in any of these functions we want to know if and what network
+ // change has happened shortly before.
+ mozilla::Atomic<PRIntervalTime> mLastOfflineStateChange;
+ mozilla::Atomic<PRIntervalTime> mLastConnectivityChange;
+ mozilla::Atomic<PRIntervalTime> mLastNetworkLinkChange;
+
+ // Time a network tearing down started.
+ mozilla::Atomic<PRIntervalTime> mNetTearingDownStarted{0};
+
+ SocketProcessHost* mSocketProcess{nullptr};
+
+ // Events should be executed after the socket process is launched. Will
+ // dispatch these events while socket process fires OnProcessLaunchComplete.
+ // Note: this array is accessed only on the main thread.
+ nsTArray<std::function<void()>> mPendingEvents;
+
+ // The observer notifications need to be forwarded to socket process.
+ nsTHashSet<nsCString> mObserverTopicForSocketProcess;
+ // Some noticications (e.g., NS_XPCOM_SHUTDOWN_OBSERVER_ID) are triggered in
+ // socket process, so we should not send the notifications again.
+ nsTHashSet<nsCString> mSocketProcessTopicBlockedList;
+ // Used to store the topics that are already observed by IOService.
+ nsTHashSet<nsCString> mIOServiceTopicList;
+
+ nsCOMPtr<nsIObserverService> mObserverService;
+
+ public:
+ // Used for all default buffer sizes that necko allocates.
+ static uint32_t gDefaultSegmentSize;
+ static uint32_t gDefaultSegmentCount;
+};
+
+/**
+ * Reference to the IO service singleton. May be null.
+ */
+extern nsIOService* gIOService;
+
+} // namespace net
+} // namespace mozilla
+
+#endif // nsIOService_h__