tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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