HttpConnectionMgrParent.cpp (10391B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* vim:set ts=4 sw=4 sts=4 et cin: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 // HttpLog.h should generally be included first 8 #include "HttpLog.h" 9 10 #include "HttpConnectionMgrParent.h" 11 #include "AltSvcTransactionParent.h" 12 #include "mozilla/net/HttpTransactionParent.h" 13 #include "mozilla/net/WebSocketConnectionParent.h" 14 #include "nsHttpConnectionInfo.h" 15 #include "nsIHttpChannelInternal.h" 16 #include "nsIInterfaceRequestor.h" 17 #include "nsIInterfaceRequestorUtils.h" 18 #include "nsISpeculativeConnect.h" 19 #include "nsIOService.h" 20 #include "nsQueryObject.h" 21 22 namespace mozilla::net { 23 24 MOZ_RUNINIT nsTHashMap<uint32_t, nsCOMPtr<nsIHttpUpgradeListener>> 25 HttpConnectionMgrParent::sHttpUpgradeListenerMap; 26 uint32_t HttpConnectionMgrParent::sListenerId = 0; 27 StaticMutex HttpConnectionMgrParent::sLock; 28 29 // static 30 uint32_t HttpConnectionMgrParent::AddHttpUpgradeListenerToMap( 31 nsIHttpUpgradeListener* aListener) { 32 StaticMutexAutoLock lock(sLock); 33 uint32_t id = sListenerId++; 34 sHttpUpgradeListenerMap.InsertOrUpdate(id, nsCOMPtr{aListener}); 35 return id; 36 } 37 38 // static 39 void HttpConnectionMgrParent::RemoveHttpUpgradeListenerFromMap(uint32_t aId) { 40 StaticMutexAutoLock lock(sLock); 41 sHttpUpgradeListenerMap.Remove(aId); 42 } 43 44 // static 45 Maybe<nsCOMPtr<nsIHttpUpgradeListener>> 46 HttpConnectionMgrParent::GetAndRemoveHttpUpgradeListener(uint32_t aId) { 47 StaticMutexAutoLock lock(sLock); 48 return sHttpUpgradeListenerMap.Extract(aId); 49 } 50 51 NS_IMPL_ISUPPORTS0(HttpConnectionMgrParent) 52 53 nsresult HttpConnectionMgrParent::Init( 54 uint16_t maxUrgentExcessiveConns, uint16_t maxConnections, 55 uint16_t maxPersistentConnectionsPerHost, 56 uint16_t maxPersistentConnectionsPerProxy, uint16_t maxRequestDelay, 57 bool throttleEnabled, uint32_t throttleSuspendFor, 58 uint32_t throttleResumeFor, uint32_t throttleHoldTime, 59 uint32_t throttleMaxTime, bool beConservativeForProxy) { 60 // We don't have to do anything here. nsHttpConnectionMgr in socket process is 61 // initialized by nsHttpHandler. 62 return NS_OK; 63 } 64 65 nsresult HttpConnectionMgrParent::Shutdown() { 66 if (mShutDown) { 67 return NS_OK; 68 } 69 70 if (!CanSend()) { 71 return NS_ERROR_NOT_AVAILABLE; 72 } 73 74 mShutDown = true; 75 (void)Send__delete__(this); 76 return NS_OK; 77 } 78 79 nsresult HttpConnectionMgrParent::UpdateRequestTokenBucket( 80 EventTokenBucket* aBucket) { 81 // We don't have to do anything here. UpdateRequestTokenBucket() will be 82 // triggered by pref change in socket process. 83 return NS_OK; 84 } 85 86 nsresult HttpConnectionMgrParent::DoShiftReloadConnectionCleanup() { 87 // Do nothing here. DoShiftReloadConnectionCleanup() will be triggered by 88 // observer notification or pref change in socket process. 89 return NS_OK; 90 } 91 92 nsresult HttpConnectionMgrParent::DoShiftReloadConnectionCleanupWithConnInfo( 93 nsHttpConnectionInfo* aCi) { 94 if (!aCi) { 95 return NS_ERROR_INVALID_ARG; 96 } 97 98 HttpConnectionInfoCloneArgs connInfoArgs; 99 nsHttpConnectionInfo::SerializeHttpConnectionInfo(aCi, connInfoArgs); 100 101 RefPtr<HttpConnectionMgrParent> self = this; 102 auto task = [self, connInfoArgs{std::move(connInfoArgs)}]() { 103 (void)self->SendDoShiftReloadConnectionCleanupWithConnInfo(connInfoArgs); 104 }; 105 gIOService->CallOrWaitForSocketProcess(std::move(task)); 106 return NS_OK; 107 } 108 109 nsresult HttpConnectionMgrParent::PruneDeadConnections() { 110 // Do nothing here. PruneDeadConnections() will be triggered by 111 // observer notification or pref change in socket process. 112 return NS_OK; 113 } 114 115 void HttpConnectionMgrParent::AbortAndCloseAllConnections(int32_t, ARefBase*) { 116 // Do nothing here. AbortAndCloseAllConnections() will be triggered by 117 // observer notification in socket process. 118 } 119 120 nsresult HttpConnectionMgrParent::UpdateParam(nsParamName name, 121 uint16_t value) { 122 // Do nothing here. UpdateParam() will be triggered by pref change in 123 // socket process. 124 return NS_OK; 125 } 126 127 void HttpConnectionMgrParent::PrintDiagnostics() { 128 // Do nothing here. PrintDiagnostics() will be triggered by pref change in 129 // socket process. 130 } 131 132 nsresult HttpConnectionMgrParent::UpdateCurrentBrowserId(uint64_t aId) { 133 RefPtr<HttpConnectionMgrParent> self = this; 134 auto task = [self, aId]() { (void)self->SendUpdateCurrentBrowserId(aId); }; 135 gIOService->CallOrWaitForSocketProcess(std::move(task)); 136 return NS_OK; 137 } 138 139 nsresult HttpConnectionMgrParent::AddTransaction(HttpTransactionShell* aTrans, 140 int32_t aPriority) { 141 MOZ_ASSERT(gIOService->SocketProcessReady()); 142 143 if (!CanSend()) { 144 return NS_ERROR_NOT_AVAILABLE; 145 } 146 147 (void)SendAddTransaction(WrapNotNull(aTrans->AsHttpTransactionParent()), 148 aPriority); 149 return NS_OK; 150 } 151 152 nsresult HttpConnectionMgrParent::AddTransactionWithStickyConn( 153 HttpTransactionShell* aTrans, int32_t aPriority, 154 HttpTransactionShell* aTransWithStickyConn) { 155 MOZ_ASSERT(gIOService->SocketProcessReady()); 156 157 if (!CanSend()) { 158 return NS_ERROR_NOT_AVAILABLE; 159 } 160 161 (void)SendAddTransactionWithStickyConn( 162 WrapNotNull(aTrans->AsHttpTransactionParent()), aPriority, 163 WrapNotNull(aTransWithStickyConn->AsHttpTransactionParent())); 164 return NS_OK; 165 } 166 167 nsresult HttpConnectionMgrParent::RescheduleTransaction( 168 HttpTransactionShell* aTrans, int32_t aPriority) { 169 MOZ_ASSERT(gIOService->SocketProcessReady()); 170 171 if (!CanSend()) { 172 return NS_ERROR_NOT_AVAILABLE; 173 } 174 175 (void)SendRescheduleTransaction( 176 WrapNotNull(aTrans->AsHttpTransactionParent()), aPriority); 177 return NS_OK; 178 } 179 180 void HttpConnectionMgrParent::UpdateClassOfServiceOnTransaction( 181 HttpTransactionShell* aTrans, const ClassOfService& aClassOfService) { 182 MOZ_ASSERT(gIOService->SocketProcessReady()); 183 184 if (!CanSend()) { 185 return; 186 } 187 188 (void)SendUpdateClassOfServiceOnTransaction( 189 WrapNotNull(aTrans->AsHttpTransactionParent()), aClassOfService); 190 } 191 192 nsresult HttpConnectionMgrParent::CancelTransaction( 193 HttpTransactionShell* aTrans, nsresult aReason) { 194 MOZ_ASSERT(gIOService->SocketProcessReady()); 195 196 if (!CanSend()) { 197 return NS_ERROR_NOT_AVAILABLE; 198 } 199 200 (void)SendCancelTransaction(WrapNotNull(aTrans->AsHttpTransactionParent()), 201 aReason); 202 return NS_OK; 203 } 204 205 nsresult HttpConnectionMgrParent::ReclaimConnection(HttpConnectionBase*) { 206 MOZ_ASSERT_UNREACHABLE("ReclaimConnection should not be called"); 207 return NS_ERROR_NOT_IMPLEMENTED; 208 } 209 210 nsresult HttpConnectionMgrParent::ProcessPendingQ(nsHttpConnectionInfo*) { 211 MOZ_ASSERT_UNREACHABLE("ProcessPendingQ should not be called"); 212 return NS_ERROR_NOT_IMPLEMENTED; 213 } 214 215 nsresult HttpConnectionMgrParent::ProcessPendingQ() { 216 MOZ_ASSERT_UNREACHABLE("ProcessPendingQ should not be called"); 217 return NS_ERROR_NOT_IMPLEMENTED; 218 } 219 220 nsresult HttpConnectionMgrParent::GetSocketThreadTarget(nsIEventTarget**) { 221 MOZ_ASSERT_UNREACHABLE("GetSocketThreadTarget should not be called"); 222 return NS_ERROR_NOT_IMPLEMENTED; 223 } 224 225 nsresult HttpConnectionMgrParent::SpeculativeConnect( 226 nsHttpConnectionInfo* aConnInfo, nsIInterfaceRequestor* aCallbacks, 227 uint32_t aCaps, SpeculativeTransaction* aTransaction, bool aFetchHTTPSRR) { 228 NS_ENSURE_ARG_POINTER(aConnInfo); 229 230 nsCOMPtr<nsISpeculativeConnectionOverrider> overrider = 231 do_GetInterface(aCallbacks); 232 Maybe<SpeculativeConnectionOverriderArgs> overriderArgs; 233 if (overrider) { 234 overriderArgs.emplace(); 235 overriderArgs->parallelSpeculativeConnectLimit() = 236 overrider->GetParallelSpeculativeConnectLimit(); 237 overriderArgs->ignoreIdle() = overrider->GetIgnoreIdle(); 238 overriderArgs->allow1918() = overrider->GetAllow1918(); 239 } 240 241 HttpConnectionInfoCloneArgs connInfo; 242 nsHttpConnectionInfo::SerializeHttpConnectionInfo(aConnInfo, connInfo); 243 RefPtr<AltSvcTransactionParent> trans = do_QueryObject(aTransaction); 244 RefPtr<HttpConnectionMgrParent> self = this; 245 auto task = [self, connInfo{std::move(connInfo)}, 246 overriderArgs{std::move(overriderArgs)}, aCaps, 247 trans{std::move(trans)}, aFetchHTTPSRR]() { 248 Maybe<NotNull<AltSvcTransactionParent*>> maybeTrans; 249 if (trans) { 250 maybeTrans.emplace(WrapNotNull(trans.get())); 251 } 252 (void)self->SendSpeculativeConnect(connInfo, overriderArgs, aCaps, 253 maybeTrans, aFetchHTTPSRR); 254 }; 255 256 gIOService->CallOrWaitForSocketProcess(std::move(task)); 257 return NS_OK; 258 } 259 260 nsresult HttpConnectionMgrParent::VerifyTraffic() { 261 // Do nothing here. VerifyTraffic() will be triggered by observer notification 262 // in socket process. 263 return NS_OK; 264 } 265 266 void HttpConnectionMgrParent::ExcludeHttp2(const nsHttpConnectionInfo* ci) { 267 // Do nothing. 268 } 269 270 void HttpConnectionMgrParent::ExcludeHttp3(const nsHttpConnectionInfo* ci) { 271 // Do nothing. 272 } 273 274 nsresult HttpConnectionMgrParent::ClearConnectionHistory() { 275 // Do nothing here. ClearConnectionHistory() will be triggered by 276 // observer notification in socket process. 277 return NS_OK; 278 } 279 280 nsresult HttpConnectionMgrParent::CompleteUpgrade( 281 HttpTransactionShell* aTrans, nsIHttpUpgradeListener* aUpgradeListener) { 282 MOZ_ASSERT(aTrans->AsHttpTransactionParent()); 283 284 if (!CanSend()) { 285 // OnUpgradeFailed is expected to be called on socket thread. 286 nsCOMPtr<nsIEventTarget> target = 287 do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID); 288 if (target) { 289 nsCOMPtr<nsIHttpUpgradeListener> listener = aUpgradeListener; 290 target->Dispatch(NS_NewRunnableFunction( 291 "HttpConnectionMgrParent::CompleteUpgrade", [listener]() { 292 (void)listener->OnUpgradeFailed(NS_ERROR_NOT_AVAILABLE); 293 })); 294 } 295 return NS_OK; 296 } 297 298 // We need to link the id and the upgrade listener here, so 299 // WebSocketConnectionParent can connect to the listener correctly later. 300 uint32_t id = AddHttpUpgradeListenerToMap(aUpgradeListener); 301 (void)SendStartWebSocketConnection( 302 WrapNotNull(aTrans->AsHttpTransactionParent()), id); 303 return NS_OK; 304 } 305 306 nsHttpConnectionMgr* HttpConnectionMgrParent::AsHttpConnectionMgr() { 307 return nullptr; 308 } 309 310 HttpConnectionMgrParent* HttpConnectionMgrParent::AsHttpConnectionMgrParent() { 311 return this; 312 } 313 314 } // namespace mozilla::net