tor-browser

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

NullHttpTransaction.cpp (7076B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set sw=2 ts=8 et tw=80 : */
      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 "mozilla/net/NeckoChannelParams.h"  // For HttpActivityArgs.
     11 #include "mozilla/Components.h"
     12 #include "nsHttp.h"
     13 #include "NullHttpTransaction.h"
     14 #include "nsHttpHandler.h"
     15 #include "nsHttpRequestHead.h"
     16 #include "nsIHttpActivityObserver.h"
     17 #include "nsQueryObject.h"
     18 #include "nsNetUtil.h"
     19 
     20 namespace mozilla {
     21 namespace net {
     22 
     23 NS_IMPL_ISUPPORTS(NullHttpTransaction, NullHttpTransaction,
     24                  nsISupportsWeakReference)
     25 
     26 NullHttpTransaction::NullHttpTransaction(nsHttpConnectionInfo* ci,
     27                                         nsIInterfaceRequestor* callbacks,
     28                                         uint32_t caps)
     29    : mStatus(NS_OK),
     30      mCaps(caps | NS_HTTP_ALLOW_KEEPALIVE),
     31      mRequestHead(nullptr),
     32      mIsDone(false),
     33      mClaimed(false),
     34      mCallbacks(callbacks),
     35      mConnectionInfo(ci) {
     36  nsresult rv;
     37  mActivityDistributor =
     38      mozilla::components::HttpActivityDistributor::Service(&rv);
     39  if (NS_FAILED(rv)) {
     40    return;
     41  }
     42 
     43  bool activityDistributorActive;
     44  rv = mActivityDistributor->GetIsActive(&activityDistributorActive);
     45  if (NS_SUCCEEDED(rv) && activityDistributorActive) {
     46    // There are some observers registered at activity distributor.
     47    LOG(
     48        ("NulHttpTransaction::NullHttpTransaction() "
     49         "mActivityDistributor is active "
     50         "[this=%p, %s]",
     51         this, ci->GetOrigin().get()));
     52  } else {
     53    // There is no observer, so don't use it.
     54    mActivityDistributor = nullptr;
     55  }
     56 }
     57 
     58 NullHttpTransaction::~NullHttpTransaction() {
     59  mCallbacks = nullptr;
     60  delete mRequestHead;
     61 }
     62 
     63 bool NullHttpTransaction::Claim() {
     64  if (mClaimed) {
     65    return false;
     66  }
     67  mClaimed = true;
     68  return true;
     69 }
     70 
     71 void NullHttpTransaction::Unclaim() { mClaimed = false; }
     72 
     73 void NullHttpTransaction::SetConnection(nsAHttpConnection* conn) {
     74  mConnection = conn;
     75 }
     76 
     77 nsAHttpConnection* NullHttpTransaction::Connection() {
     78  return mConnection.get();
     79 }
     80 
     81 void NullHttpTransaction::GetSecurityCallbacks(nsIInterfaceRequestor** outCB) {
     82  nsCOMPtr<nsIInterfaceRequestor> copyCB(mCallbacks);
     83  *outCB = copyCB.forget().take();
     84 }
     85 
     86 void NullHttpTransaction::OnTransportStatus(nsITransport* transport,
     87                                            nsresult status, int64_t progress) {
     88  if (status == NS_NET_STATUS_RESOLVING_HOST) {
     89    if (mTimings.domainLookupStart.IsNull()) {
     90      mTimings.domainLookupStart = TimeStamp::Now();
     91    }
     92  } else if (status == NS_NET_STATUS_RESOLVED_HOST) {
     93    if (mTimings.domainLookupEnd.IsNull()) {
     94      mTimings.domainLookupEnd = TimeStamp::Now();
     95    }
     96  } else if (status == NS_NET_STATUS_CONNECTING_TO) {
     97    if (mTimings.connectStart.IsNull()) {
     98      mTimings.connectStart = TimeStamp::Now();
     99    }
    100  } else if (status == NS_NET_STATUS_CONNECTED_TO) {
    101    TimeStamp tnow = TimeStamp::Now();
    102    if (mTimings.connectEnd.IsNull()) {
    103      mTimings.connectEnd = tnow;
    104    }
    105    if (mTimings.tcpConnectEnd.IsNull()) {
    106      mTimings.tcpConnectEnd = tnow;
    107    }
    108  } else if (status == NS_NET_STATUS_TLS_HANDSHAKE_STARTING) {
    109    if (mTimings.secureConnectionStart.IsNull()) {
    110      mTimings.secureConnectionStart = TimeStamp::Now();
    111    }
    112  } else if (status == NS_NET_STATUS_TLS_HANDSHAKE_ENDED) {
    113    mTimings.connectEnd = TimeStamp::Now();
    114    ;
    115  }
    116 
    117  if (mActivityDistributor) {
    118    (void)mActivityDistributor->ObserveActivityWithArgs(
    119        HttpActivity(mConnectionInfo->GetOrigin(),
    120                     mConnectionInfo->OriginPort(),
    121                     mConnectionInfo->EndToEndSSL()),
    122        NS_HTTP_ACTIVITY_TYPE_SOCKET_TRANSPORT, static_cast<uint32_t>(status),
    123        PR_Now(), progress, ""_ns);
    124  }
    125 }
    126 
    127 bool NullHttpTransaction::IsDone() { return mIsDone; }
    128 
    129 nsresult NullHttpTransaction::Status() { return mStatus; }
    130 
    131 uint32_t NullHttpTransaction::Caps() { return mCaps; }
    132 
    133 nsresult NullHttpTransaction::ReadSegments(nsAHttpSegmentReader* reader,
    134                                           uint32_t count,
    135                                           uint32_t* countRead) {
    136  *countRead = 0;
    137  mIsDone = true;
    138  return NS_BASE_STREAM_CLOSED;
    139 }
    140 
    141 nsresult NullHttpTransaction::WriteSegments(nsAHttpSegmentWriter* writer,
    142                                            uint32_t count,
    143                                            uint32_t* countWritten) {
    144  *countWritten = 0;
    145  return NS_BASE_STREAM_CLOSED;
    146 }
    147 
    148 uint32_t NullHttpTransaction::Http1xTransactionCount() { return 0; }
    149 
    150 nsHttpRequestHead* NullHttpTransaction::RequestHead() {
    151  // We suport a requesthead at all so that a CONNECT tunnel transaction
    152  // can obtain a Host header from it, but we lazy-popualate that header.
    153 
    154  if (!mRequestHead) {
    155    mRequestHead = new nsHttpRequestHead();
    156 
    157    nsAutoCString hostHeader;
    158    nsCString host(mConnectionInfo->GetOrigin());
    159    nsresult rv = nsHttpHandler::GenerateHostPort(
    160        host, mConnectionInfo->OriginPort(), hostHeader);
    161    if (NS_SUCCEEDED(rv)) {
    162      rv = mRequestHead->SetHeader(nsHttp::Host, hostHeader);
    163      MOZ_ASSERT(NS_SUCCEEDED(rv));
    164      if (mActivityDistributor) {
    165        // Report request headers.
    166        nsCString reqHeaderBuf;
    167        mRequestHead->Flatten(reqHeaderBuf, false);
    168        (void)mActivityDistributor->ObserveActivityWithArgs(
    169            HttpActivity(mConnectionInfo->GetOrigin(),
    170                         mConnectionInfo->OriginPort(),
    171                         mConnectionInfo->EndToEndSSL()),
    172            NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
    173            NS_HTTP_ACTIVITY_SUBTYPE_REQUEST_HEADER, PR_Now(), 0, reqHeaderBuf);
    174      }
    175    }
    176 
    177    // CONNECT tunnels may also want Proxy-Authorization but that is a lot
    178    // harder to determine, so for now we will let those connections fail in
    179    // the NullHttpTransaction and let them be retried from the pending queue
    180    // with a bound transaction
    181  }
    182 
    183  return mRequestHead;
    184 }
    185 
    186 nsresult NullHttpTransaction::TakeSubTransactions(
    187    nsTArray<RefPtr<nsAHttpTransaction> >& outTransactions) {
    188  return NS_ERROR_NOT_IMPLEMENTED;
    189 }
    190 
    191 void NullHttpTransaction::SetProxyConnectFailed() {}
    192 
    193 void NullHttpTransaction::Close(nsresult reason) {
    194  mStatus = reason;
    195  mConnection = nullptr;
    196  mIsDone = true;
    197  if (mActivityDistributor) {
    198    // Report that this transaction is closing.
    199    (void)mActivityDistributor->ObserveActivityWithArgs(
    200        HttpActivity(mConnectionInfo->GetOrigin(),
    201                     mConnectionInfo->OriginPort(),
    202                     mConnectionInfo->EndToEndSSL()),
    203        NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
    204        NS_HTTP_ACTIVITY_SUBTYPE_TRANSACTION_CLOSE, PR_Now(), 0, ""_ns);
    205  }
    206 }
    207 
    208 nsHttpConnectionInfo* NullHttpTransaction::ConnectionInfo() {
    209  return mConnectionInfo;
    210 }
    211 
    212 }  // namespace net
    213 }  // namespace mozilla