summaryrefslogtreecommitdiffstats
path: root/netwerk/protocol/http/HttpConnectionMgrParent.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--netwerk/protocol/http/HttpConnectionMgrParent.cpp317
1 files changed, 317 insertions, 0 deletions
diff --git a/netwerk/protocol/http/HttpConnectionMgrParent.cpp b/netwerk/protocol/http/HttpConnectionMgrParent.cpp
new file mode 100644
index 0000000000..ff57546f5a
--- /dev/null
+++ b/netwerk/protocol/http/HttpConnectionMgrParent.cpp
@@ -0,0 +1,317 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:set ts=4 sw=4 sts=4 et cin: */
+/* 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/. */
+
+// HttpLog.h should generally be included first
+#include "HttpLog.h"
+
+#include "HttpConnectionMgrParent.h"
+#include "AltSvcTransactionParent.h"
+#include "mozilla/net/HttpTransactionParent.h"
+#include "mozilla/net/WebSocketConnectionParent.h"
+#include "nsHttpConnectionInfo.h"
+#include "nsIHttpChannelInternal.h"
+#include "nsIInterfaceRequestor.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsISpeculativeConnect.h"
+#include "nsIOService.h"
+#include "nsQueryObject.h"
+
+namespace mozilla::net {
+
+nsTHashMap<uint32_t, nsCOMPtr<nsIHttpUpgradeListener>>
+ HttpConnectionMgrParent::sHttpUpgradeListenerMap;
+uint32_t HttpConnectionMgrParent::sListenerId = 0;
+StaticMutex HttpConnectionMgrParent::sLock;
+
+// static
+uint32_t HttpConnectionMgrParent::AddHttpUpgradeListenerToMap(
+ nsIHttpUpgradeListener* aListener) {
+ StaticMutexAutoLock lock(sLock);
+ uint32_t id = sListenerId++;
+ sHttpUpgradeListenerMap.InsertOrUpdate(id, nsCOMPtr{aListener});
+ return id;
+}
+
+// static
+void HttpConnectionMgrParent::RemoveHttpUpgradeListenerFromMap(uint32_t aId) {
+ StaticMutexAutoLock lock(sLock);
+ sHttpUpgradeListenerMap.Remove(aId);
+}
+
+// static
+Maybe<nsCOMPtr<nsIHttpUpgradeListener>>
+HttpConnectionMgrParent::GetAndRemoveHttpUpgradeListener(uint32_t aId) {
+ StaticMutexAutoLock lock(sLock);
+ return sHttpUpgradeListenerMap.Extract(aId);
+}
+
+NS_IMPL_ISUPPORTS0(HttpConnectionMgrParent)
+
+nsresult HttpConnectionMgrParent::Init(
+ uint16_t maxUrgentExcessiveConns, uint16_t maxConnections,
+ uint16_t maxPersistentConnectionsPerHost,
+ uint16_t maxPersistentConnectionsPerProxy, uint16_t maxRequestDelay,
+ bool throttleEnabled, uint32_t throttleVersion, uint32_t throttleSuspendFor,
+ uint32_t throttleResumeFor, uint32_t throttleReadLimit,
+ uint32_t throttleReadInterval, uint32_t throttleHoldTime,
+ uint32_t throttleMaxTime, bool beConservativeForProxy) {
+ // We don't have to do anything here. nsHttpConnectionMgr in socket process is
+ // initialized by nsHttpHandler.
+ return NS_OK;
+}
+
+nsresult HttpConnectionMgrParent::Shutdown() {
+ if (mShutDown) {
+ return NS_OK;
+ }
+
+ if (!CanSend()) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ mShutDown = true;
+ Unused << Send__delete__(this);
+ return NS_OK;
+}
+
+nsresult HttpConnectionMgrParent::UpdateRequestTokenBucket(
+ EventTokenBucket* aBucket) {
+ // We don't have to do anything here. UpdateRequestTokenBucket() will be
+ // triggered by pref change in socket process.
+ return NS_OK;
+}
+
+nsresult HttpConnectionMgrParent::DoShiftReloadConnectionCleanup() {
+ // Do nothing here. DoShiftReloadConnectionCleanup() will be triggered by
+ // observer notification or pref change in socket process.
+ return NS_OK;
+}
+
+nsresult HttpConnectionMgrParent::DoShiftReloadConnectionCleanupWithConnInfo(
+ nsHttpConnectionInfo* aCi) {
+ if (!aCi) {
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ HttpConnectionInfoCloneArgs connInfoArgs;
+ nsHttpConnectionInfo::SerializeHttpConnectionInfo(aCi, connInfoArgs);
+
+ RefPtr<HttpConnectionMgrParent> self = this;
+ auto task = [self, connInfoArgs{std::move(connInfoArgs)}]() {
+ Unused << self->SendDoShiftReloadConnectionCleanupWithConnInfo(
+ connInfoArgs);
+ };
+ gIOService->CallOrWaitForSocketProcess(std::move(task));
+ return NS_OK;
+}
+
+nsresult HttpConnectionMgrParent::PruneDeadConnections() {
+ // Do nothing here. PruneDeadConnections() will be triggered by
+ // observer notification or pref change in socket process.
+ return NS_OK;
+}
+
+void HttpConnectionMgrParent::AbortAndCloseAllConnections(int32_t, ARefBase*) {
+ // Do nothing here. AbortAndCloseAllConnections() will be triggered by
+ // observer notification in socket process.
+}
+
+nsresult HttpConnectionMgrParent::UpdateParam(nsParamName name,
+ uint16_t value) {
+ // Do nothing here. UpdateParam() will be triggered by pref change in
+ // socket process.
+ return NS_OK;
+}
+
+void HttpConnectionMgrParent::PrintDiagnostics() {
+ // Do nothing here. PrintDiagnostics() will be triggered by pref change in
+ // socket process.
+}
+
+nsresult HttpConnectionMgrParent::UpdateCurrentTopBrowsingContextId(
+ uint64_t aId) {
+ RefPtr<HttpConnectionMgrParent> self = this;
+ auto task = [self, aId]() {
+ Unused << self->SendUpdateCurrentTopBrowsingContextId(aId);
+ };
+ gIOService->CallOrWaitForSocketProcess(std::move(task));
+ return NS_OK;
+}
+
+nsresult HttpConnectionMgrParent::AddTransaction(HttpTransactionShell* aTrans,
+ int32_t aPriority) {
+ MOZ_ASSERT(gIOService->SocketProcessReady());
+
+ if (!CanSend()) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ Unused << SendAddTransaction(aTrans->AsHttpTransactionParent(), aPriority);
+ return NS_OK;
+}
+
+nsresult HttpConnectionMgrParent::AddTransactionWithStickyConn(
+ HttpTransactionShell* aTrans, int32_t aPriority,
+ HttpTransactionShell* aTransWithStickyConn) {
+ MOZ_ASSERT(gIOService->SocketProcessReady());
+
+ if (!CanSend()) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ Unused << SendAddTransactionWithStickyConn(
+ aTrans->AsHttpTransactionParent(), aPriority,
+ aTransWithStickyConn->AsHttpTransactionParent());
+ return NS_OK;
+}
+
+nsresult HttpConnectionMgrParent::RescheduleTransaction(
+ HttpTransactionShell* aTrans, int32_t aPriority) {
+ MOZ_ASSERT(gIOService->SocketProcessReady());
+
+ if (!CanSend()) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ Unused << SendRescheduleTransaction(aTrans->AsHttpTransactionParent(),
+ aPriority);
+ return NS_OK;
+}
+
+void HttpConnectionMgrParent::UpdateClassOfServiceOnTransaction(
+ HttpTransactionShell* aTrans, const ClassOfService& aClassOfService) {
+ MOZ_ASSERT(gIOService->SocketProcessReady());
+
+ if (!CanSend()) {
+ return;
+ }
+
+ Unused << SendUpdateClassOfServiceOnTransaction(
+ aTrans->AsHttpTransactionParent(), aClassOfService);
+}
+
+nsresult HttpConnectionMgrParent::CancelTransaction(
+ HttpTransactionShell* aTrans, nsresult aReason) {
+ MOZ_ASSERT(gIOService->SocketProcessReady());
+
+ if (!CanSend()) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ Unused << SendCancelTransaction(aTrans->AsHttpTransactionParent(), aReason);
+ return NS_OK;
+}
+
+nsresult HttpConnectionMgrParent::ReclaimConnection(HttpConnectionBase*) {
+ MOZ_ASSERT_UNREACHABLE("ReclaimConnection should not be called");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+nsresult HttpConnectionMgrParent::ProcessPendingQ(nsHttpConnectionInfo*) {
+ MOZ_ASSERT_UNREACHABLE("ProcessPendingQ should not be called");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+nsresult HttpConnectionMgrParent::ProcessPendingQ() {
+ MOZ_ASSERT_UNREACHABLE("ProcessPendingQ should not be called");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+nsresult HttpConnectionMgrParent::GetSocketThreadTarget(nsIEventTarget**) {
+ MOZ_ASSERT_UNREACHABLE("GetSocketThreadTarget should not be called");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+nsresult HttpConnectionMgrParent::SpeculativeConnect(
+ nsHttpConnectionInfo* aConnInfo, nsIInterfaceRequestor* aCallbacks,
+ uint32_t aCaps, SpeculativeTransaction* aTransaction, bool aFetchHTTPSRR) {
+ NS_ENSURE_ARG_POINTER(aConnInfo);
+
+ nsCOMPtr<nsISpeculativeConnectionOverrider> overrider =
+ do_GetInterface(aCallbacks);
+ Maybe<SpeculativeConnectionOverriderArgs> overriderArgs;
+ if (overrider) {
+ overriderArgs.emplace();
+ overriderArgs->parallelSpeculativeConnectLimit() =
+ overrider->GetParallelSpeculativeConnectLimit();
+ overriderArgs->ignoreIdle() = overrider->GetIgnoreIdle();
+ overriderArgs->isFromPredictor() = overrider->GetIsFromPredictor();
+ overriderArgs->allow1918() = overrider->GetAllow1918();
+ }
+
+ HttpConnectionInfoCloneArgs connInfo;
+ nsHttpConnectionInfo::SerializeHttpConnectionInfo(aConnInfo, connInfo);
+ RefPtr<AltSvcTransactionParent> trans = do_QueryObject(aTransaction);
+ RefPtr<HttpConnectionMgrParent> self = this;
+ auto task = [self, connInfo{std::move(connInfo)},
+ overriderArgs{std::move(overriderArgs)}, aCaps,
+ trans{std::move(trans)}, aFetchHTTPSRR]() {
+ Maybe<AltSvcTransactionParent*> maybeTrans;
+ if (trans) {
+ maybeTrans.emplace(trans.get());
+ }
+ Unused << self->SendSpeculativeConnect(connInfo, overriderArgs, aCaps,
+ maybeTrans, aFetchHTTPSRR);
+ };
+
+ gIOService->CallOrWaitForSocketProcess(std::move(task));
+ return NS_OK;
+}
+
+nsresult HttpConnectionMgrParent::VerifyTraffic() {
+ // Do nothing here. VerifyTraffic() will be triggered by observer notification
+ // in socket process.
+ return NS_OK;
+}
+
+void HttpConnectionMgrParent::ExcludeHttp2(const nsHttpConnectionInfo* ci) {
+ // Do nothing.
+}
+
+void HttpConnectionMgrParent::ExcludeHttp3(const nsHttpConnectionInfo* ci) {
+ // Do nothing.
+}
+
+nsresult HttpConnectionMgrParent::ClearConnectionHistory() {
+ // Do nothing here. ClearConnectionHistory() will be triggered by
+ // observer notification in socket process.
+ return NS_OK;
+}
+
+nsresult HttpConnectionMgrParent::CompleteUpgrade(
+ HttpTransactionShell* aTrans, nsIHttpUpgradeListener* aUpgradeListener) {
+ MOZ_ASSERT(aTrans->AsHttpTransactionParent());
+
+ if (!CanSend()) {
+ // OnUpgradeFailed is expected to be called on socket thread.
+ nsCOMPtr<nsIEventTarget> target =
+ do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID);
+ if (target) {
+ nsCOMPtr<nsIHttpUpgradeListener> listener = aUpgradeListener;
+ target->Dispatch(NS_NewRunnableFunction(
+ "HttpConnectionMgrParent::CompleteUpgrade", [listener]() {
+ Unused << listener->OnUpgradeFailed(NS_ERROR_NOT_AVAILABLE);
+ }));
+ }
+ return NS_OK;
+ }
+
+ // We need to link the id and the upgrade listener here, so
+ // WebSocketConnectionParent can connect to the listener correctly later.
+ uint32_t id = AddHttpUpgradeListenerToMap(aUpgradeListener);
+ Unused << SendStartWebSocketConnection(aTrans->AsHttpTransactionParent(), id);
+ return NS_OK;
+}
+
+nsHttpConnectionMgr* HttpConnectionMgrParent::AsHttpConnectionMgr() {
+ return nullptr;
+}
+
+HttpConnectionMgrParent* HttpConnectionMgrParent::AsHttpConnectionMgrParent() {
+ return this;
+}
+
+} // namespace mozilla::net