1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsIOService_h__
7 #define nsIOService_h__
9 #include "nsStringFwd.h"
10 #include "nsIIOService.h"
13 #include "nsIObserver.h"
14 #include "nsIWeakReferenceUtils.h"
15 #include "nsINetUtil.h"
16 #include "nsIChannelEventSink.h"
17 #include "nsCategoryCache.h"
18 #include "nsISpeculativeConnect.h"
19 #include "nsWeakReference.h"
20 #include "mozilla/Atomics.h"
21 #include "mozilla/Attributes.h"
22 #include "mozilla/RWLock.h"
23 #include "mozilla/net/ProtocolHandlerInfo.h"
25 #include "nsICaptivePortalService.h"
26 #include "nsIObserverService.h"
27 #include "nsTHashSet.h"
28 #include "nsWeakReference.h"
31 // We don't want to expose this observer topic.
32 // Intended internal use only for remoting offline/inline events.
34 #define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
35 #define NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC "ipc:network:set-connectivity"
37 class nsINetworkLinkService
;
39 class nsIProtocolProxyService2
;
41 class nsPISocketTransportService
;
44 class MemoryReportingProcess
;
47 class nsAsyncRedirectVerifyHelper
;
48 class SocketProcessHost
;
49 class SocketProcessMemoryReporter
;
51 class nsIOService final
: public nsIIOService
,
54 public nsISpeculativeConnect
,
55 public nsSupportsWeakReference
,
56 public nsIIOServiceInternal
,
57 public nsIObserverService
{
59 NS_DECL_THREADSAFE_ISUPPORTS
63 NS_DECL_NSISPECULATIVECONNECT
64 NS_DECL_NSIIOSERVICEINTERNAL
65 NS_DECL_NSIOBSERVERSERVICE
67 // Gets the singleton instance of the IO Service, creating it as needed
68 // Returns nullptr on out of memory or failure to initialize.
69 static already_AddRefed
<nsIOService
> GetInstance();
72 nsresult
NewURI(const char* aSpec
, nsIURI
* aBaseURI
, nsIURI
** result
,
73 nsIProtocolHandler
** hdlrResult
);
75 // Called by channels before a redirect happens. This notifies the global
76 // redirect observers.
77 nsresult
AsyncOnChannelRedirect(nsIChannel
* oldChan
, nsIChannel
* newChan
,
79 nsAsyncRedirectVerifyHelper
* helper
);
81 bool IsOffline() { return mOffline
; }
82 bool InSleepMode() { return mInSleepMode
; }
83 PRIntervalTime
LastOfflineStateChange() { return mLastOfflineStateChange
; }
84 PRIntervalTime
LastConnectivityChange() { return mLastConnectivityChange
; }
85 PRIntervalTime
LastNetworkLinkChange() { return mLastNetworkLinkChange
; }
86 bool IsNetTearingDown() {
87 return mShutdown
|| mOfflineForProfileChange
||
88 mHttpHandlerAlreadyShutingDown
;
90 PRIntervalTime
NetTearingDownStarted() { return mNetTearingDownStarted
; }
92 // nsHttpHandler is going to call this function to inform nsIOService that
93 // network is in process of tearing down. Moving nsHttpConnectionMgr::Shutdown
94 // to nsIOService caused problems (bug 1242755) so we doing it in this way. As
95 // soon as nsIOService gets notification that it is shutdown it is going to
96 // reset mHttpHandlerAlreadyShutingDown.
97 void SetHttpHandlerAlreadyShutingDown();
101 // Converts an internal URI (e.g. one that has a username and password in
102 // it) into one which we can expose to the user, for example on the URL bar.
103 static already_AddRefed
<nsIURI
> CreateExposableURI(nsIURI
*);
105 // Used to count the total number of HTTP requests made
106 void IncrementRequestNumber() { mTotalRequests
++; }
107 uint32_t GetTotalRequestNumber() { return mTotalRequests
; }
108 // Used to keep "race cache with network" stats
109 void IncrementCacheWonRequestNumber() { mCacheWon
++; }
110 uint32_t GetCacheWonRequestNumber() { return mCacheWon
; }
111 void IncrementNetWonRequestNumber() { mNetWon
++; }
112 uint32_t GetNetWonRequestNumber() { return mNetWon
; }
114 // Used to trigger a recheck of the captive portal status
115 nsresult
RecheckCaptivePortal();
117 void OnProcessLaunchComplete(SocketProcessHost
* aHost
, bool aSucceeded
);
118 void OnProcessUnexpectedShutdown(SocketProcessHost
* aHost
);
119 bool SocketProcessReady();
120 static void NotifySocketProcessPrefsChanged(const char* aName
, void* aSelf
);
121 void NotifySocketProcessPrefsChanged(const char* aName
);
122 static bool UseSocketProcess(bool aCheckAgain
= false);
124 bool IsSocketProcessLaunchComplete();
126 // Call func immediately if socket process is launched completely. Otherwise,
127 // |func| will be queued and then executed in the *main thread* once socket
128 // process is launced.
129 void CallOrWaitForSocketProcess(const std::function
<void()>& aFunc
);
131 int32_t SocketProcessPid();
132 SocketProcessHost
* SocketProcess() { return mSocketProcess
; }
134 friend SocketProcessMemoryReporter
;
135 RefPtr
<MemoryReportingProcess
> GetSocketProcessMemoryReporter();
137 // Lookup the ProtocolHandlerInfo based on a given scheme.
138 // Safe to call from any thread.
139 ProtocolHandlerInfo
LookupProtocolHandler(const nsACString
& aScheme
);
141 static void OnTLSPrefChange(const char* aPref
, void* aSelf
);
143 nsresult
LaunchSocketProcess();
145 static bool TooManySocketProcessCrash();
146 static void IncreaseSocketProcessCrashCount();
147 #ifdef MOZ_WIDGET_ANDROID
148 static bool ShouldAddAdditionalSearchHeaders(nsIURI
* aURI
, bool* val
);
152 // These shouldn't be called directly:
153 // - construct using GetInstance
154 // - destroy using Release
157 nsresult
SetConnectivityInternal(bool aConnectivity
);
159 nsresult
OnNetworkLinkEvent(const char* data
);
161 nsresult
InitializeCaptivePortalService();
162 nsresult
RecheckCaptivePortalIfLocalRedirect(nsIChannel
* newChan
);
165 static void PrefsChanged(const char* pref
, void* self
);
166 void PrefsChanged(const char* pref
= nullptr);
167 void ParsePortList(const char* pref
, bool remove
);
169 nsresult
InitializeSocketTransportService();
170 nsresult
InitializeNetworkLinkService();
171 nsresult
InitializeProtocolProxyService();
173 // consolidated helper function
174 void LookupProxyInfo(nsIURI
* aURI
, nsIURI
* aProxyURI
, uint32_t aProxyFlags
,
175 nsCString
* aScheme
, nsIProxyInfo
** outPI
);
177 nsresult
NewChannelFromURIWithProxyFlagsInternal(
178 nsIURI
* aURI
, nsIURI
* aProxyURI
, uint32_t aProxyFlags
,
179 nsINode
* aLoadingNode
, nsIPrincipal
* aLoadingPrincipal
,
180 nsIPrincipal
* aTriggeringPrincipal
,
181 const mozilla::Maybe
<mozilla::dom::ClientInfo
>& aLoadingClientInfo
,
182 const mozilla::Maybe
<mozilla::dom::ServiceWorkerDescriptor
>& aController
,
183 uint32_t aSecurityFlags
, nsContentPolicyType aContentPolicyType
,
184 uint32_t aSandboxFlags
, bool aSkipCheckForBrokenURLOrZeroSized
,
185 nsIChannel
** result
);
187 nsresult
NewChannelFromURIWithProxyFlagsInternal(nsIURI
* aURI
,
189 uint32_t aProxyFlags
,
190 nsILoadInfo
* aLoadInfo
,
191 nsIChannel
** result
);
193 nsresult
SpeculativeConnectInternal(
194 nsIURI
* aURI
, nsIPrincipal
* aPrincipal
,
195 Maybe
<OriginAttributes
>&& aOriginAttributes
,
196 nsIInterfaceRequestor
* aCallbacks
, bool aAnonymous
);
198 void DestroySocketProcess();
200 nsresult
SetOfflineInternal(bool offline
, bool notifySocketProcess
= true);
202 bool UsesExternalProtocolHandler(const nsACString
& aScheme
)
203 MOZ_REQUIRES_SHARED(mLock
);
206 mozilla::Atomic
<bool, mozilla::Relaxed
> mOffline
{true};
207 mozilla::Atomic
<bool, mozilla::Relaxed
> mOfflineForProfileChange
{false};
208 bool mManageLinkStatus
{false};
209 mozilla::Atomic
<bool, mozilla::Relaxed
> mConnectivity
{true};
211 // Used to handle SetOffline() reentrancy. See the comment in
212 // SetOffline() for more details.
213 bool mSettingOffline
{false};
214 bool mSetOfflineValue
{false};
216 bool mSocketProcessLaunchComplete
{false};
218 mozilla::Atomic
<bool, mozilla::Relaxed
> mShutdown
{false};
219 mozilla::Atomic
<bool, mozilla::Relaxed
> mHttpHandlerAlreadyShutingDown
{false};
220 mozilla::Atomic
<bool, mozilla::Relaxed
> mInSleepMode
{false};
222 nsCOMPtr
<nsPISocketTransportService
> mSocketTransportService
;
223 nsCOMPtr
<nsICaptivePortalService
> mCaptivePortalService
;
224 nsCOMPtr
<nsINetworkLinkService
> mNetworkLinkService
;
225 bool mNetworkLinkServiceInitialized
{false};
228 nsCategoryCache
<nsIChannelEventSink
> mChannelEventSinks
{
229 NS_CHANNEL_EVENT_SINK_CATEGORY
};
231 RWLock mLock
{"nsIOService::mLock"};
232 nsTArray
<int32_t> mRestrictedPortList
MOZ_GUARDED_BY(mLock
);
233 nsTArray
<nsCString
> mForceExternalSchemes
MOZ_GUARDED_BY(mLock
);
234 nsTHashMap
<nsCString
, RuntimeProtocolHandler
> mRuntimeProtocolHandlers
235 MOZ_GUARDED_BY(mLock
);
237 uint32_t mTotalRequests
{0};
238 uint32_t mCacheWon
{0};
240 static uint32_t sSocketProcessCrashedCount
;
242 // These timestamps are needed for collecting telemetry on PR_Connect,
243 // PR_ConnectContinue and PR_Close blocking time. If we spend very long
244 // time in any of these functions we want to know if and what network
245 // change has happened shortly before.
246 mozilla::Atomic
<PRIntervalTime
> mLastOfflineStateChange
;
247 mozilla::Atomic
<PRIntervalTime
> mLastConnectivityChange
;
248 mozilla::Atomic
<PRIntervalTime
> mLastNetworkLinkChange
;
250 // Time a network tearing down started.
251 mozilla::Atomic
<PRIntervalTime
> mNetTearingDownStarted
{0};
253 SocketProcessHost
* mSocketProcess
{nullptr};
255 // Events should be executed after the socket process is launched. Will
256 // dispatch these events while socket process fires OnProcessLaunchComplete.
257 // Note: this array is accessed only on the main thread.
258 nsTArray
<std::function
<void()>> mPendingEvents
;
260 // The observer notifications need to be forwarded to socket process.
261 nsTHashSet
<nsCString
> mObserverTopicForSocketProcess
;
262 // Some noticications (e.g., NS_XPCOM_SHUTDOWN_OBSERVER_ID) are triggered in
263 // socket process, so we should not send the notifications again.
264 nsTHashSet
<nsCString
> mSocketProcessTopicBlockedList
;
265 // Used to store the topics that are already observed by IOService.
266 nsTHashSet
<nsCString
> mIOServiceTopicList
;
268 nsCOMPtr
<nsIObserverService
> mObserverService
;
271 // Used for all default buffer sizes that necko allocates.
272 static uint32_t gDefaultSegmentSize
;
273 static uint32_t gDefaultSegmentCount
;
277 * Reference to the IO service singleton. May be null.
279 extern nsIOService
* gIOService
;
282 } // namespace mozilla
284 #endif // nsIOService_h__