Bug 1595079 - Add an abstract layer to nsHttpTransaction r=dragana
authorKershaw Chang <kershaw@mozilla.com>
Fri, 15 Nov 2019 11:06:04 +0000
changeset 502152 2f87baa2ba544e90dacc26eb46afd5b636806b26
parent 502151 f8d156649aaaa1882bfd57b3c2dd4d2dd6ac9494
child 502153 0f20566c7b2fa7b1204e432828940fd81ab2a197
push id114172
push userdluca@mozilla.com
push dateTue, 19 Nov 2019 11:31:10 +0000
treeherdermozilla-inbound@b5c5ba07d3db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdragana
bugs1595079
milestone72.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1595079 - Add an abstract layer to nsHttpTransaction r=dragana 1. Add nsAHttpTransactionShell layer to nsHttpTransaction 2. Replace nsHttpTransaction with nsAHttpTransactionShell in nsHttpChannel and nsHttpHandler Differential Revision: https://phabricator.services.mozilla.com/D52363
netwerk/protocol/http/Http2Push.cpp
netwerk/protocol/http/Http2Session.cpp
netwerk/protocol/http/Http3Session.cpp
netwerk/protocol/http/HttpTransactionShell.h
netwerk/protocol/http/NullHttpTransaction.cpp
netwerk/protocol/http/NullHttpTransaction.h
netwerk/protocol/http/TunnelUtils.cpp
netwerk/protocol/http/nsAHttpTransaction.h
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpChannel.h
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/protocol/http/nsHttpConnectionMgr.h
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/http/nsHttpHandler.h
netwerk/protocol/http/nsHttpTransaction.cpp
netwerk/protocol/http/nsHttpTransaction.h
--- a/netwerk/protocol/http/Http2Push.cpp
+++ b/netwerk/protocol/http/Http2Push.cpp
@@ -446,18 +446,16 @@ nsHttpConnectionInfo* Http2PushTransacti
 }
 
 bool Http2PushTransactionBuffer::IsDone() { return mIsDone; }
 
 nsresult Http2PushTransactionBuffer::Status() { return mStatus; }
 
 uint32_t Http2PushTransactionBuffer::Caps() { return 0; }
 
-void Http2PushTransactionBuffer::SetDNSWasRefreshed() {}
-
 uint64_t Http2PushTransactionBuffer::Available() {
   return mBufferedHTTP1Used - mBufferedHTTP1Consumed;
 }
 
 nsresult Http2PushTransactionBuffer::ReadSegments(nsAHttpSegmentReader* reader,
                                                   uint32_t count,
                                                   uint32_t* countRead) {
   *countRead = 0;
--- a/netwerk/protocol/http/Http2Session.cpp
+++ b/netwerk/protocol/http/Http2Session.cpp
@@ -4502,20 +4502,16 @@ nsresult Http2Session::Status() {
   return NS_ERROR_UNEXPECTED;
 }
 
 uint32_t Http2Session::Caps() {
   MOZ_ASSERT(false, "Http2Session::Caps()");
   return 0;
 }
 
-void Http2Session::SetDNSWasRefreshed() {
-  MOZ_ASSERT(false, "Http2Session::SetDNSWasRefreshed()");
-}
-
 nsHttpRequestHead* Http2Session::RequestHead() {
   MOZ_ASSERT(OnSocketThread(), "not on socket thread");
   MOZ_ASSERT(false,
              "Http2Session::RequestHead() "
              "should not be called after http/2 is setup");
   return nullptr;
 }
 
--- a/netwerk/protocol/http/Http3Session.cpp
+++ b/netwerk/protocol/http/Http3Session.cpp
@@ -686,20 +686,16 @@ nsresult Http3Session::Status() {
   return NS_ERROR_UNEXPECTED;
 }
 
 uint32_t Http3Session::Caps() {
   MOZ_ASSERT(false, "Http3Session::Caps()");
   return 0;
 }
 
-void Http3Session::SetDNSWasRefreshed() {
-  MOZ_ASSERT(false, "Http3Session::SetDNSWasRefreshed()");
-}
-
 nsresult Http3Session::ReadSegments(nsAHttpSegmentReader* reader,
                                     uint32_t count, uint32_t* countRead) {
   bool again = false;
   return ReadSegmentsAgain(reader, count, countRead, &again);
 }
 
 nsresult Http3Session::ReadSegmentsAgain(nsAHttpSegmentReader* reader,
                                          uint32_t count, uint32_t* countRead,
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/http/HttpTransactionShell.h
@@ -0,0 +1,184 @@
+/* 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/. */
+
+#ifndef HttpTransactionShell_h__
+#define HttpTransactionShell_h__
+
+#include "nsISupports.h"
+#include "TimingStruct.h"
+#include "nsInputStreamPump.h"
+
+class nsIEventTraget;
+class nsIInputStream;
+class nsIInterfaceRequestor;
+class nsIRequest;
+class nsIRequestContext;
+class nsITransportEventSink;
+enum HttpTrafficCategory : uint8_t;
+
+namespace mozilla {
+namespace net {
+
+class Http2PushedStreamWrapper;
+class nsHttpConnectionInfo;
+class nsHttpHeaderArray;
+class nsHttpRequestHead;
+class nsHttpTransaction;
+class TransactionObserver;
+
+//----------------------------------------------------------------------------
+// Abstract base class for a HTTP transaction in the chrome process
+//----------------------------------------------------------------------------
+
+// 95e5a5b7-6aa2-4011-920a-0908b52f95d4
+#define HTTPTRANSACTIONSHELL_IID                     \
+  {                                                  \
+    0x95e5a5b7, 0x6aa2, 0x4011, {                    \
+      0x92, 0x0a, 0x09, 0x08, 0xb5, 0x2f, 0x95, 0xd4 \
+    }                                                \
+  }
+
+class HttpTransactionShell : public nsISupports {
+ public:
+  NS_DECLARE_STATIC_IID_ACCESSOR(HTTPTRANSACTIONSHELL_IID)
+
+  //
+  // called to initialize the transaction
+  //
+  // @param caps
+  //        the transaction capabilities (see nsHttp.h)
+  // @param connInfo
+  //        the connection type for this transaction.
+  // @param reqHeaders
+  //        the request header struct
+  // @param reqBody
+  //        the request body (POST or PUT data stream)
+  // @param reqBodyIncludesHeaders
+  //        fun stuff to support NPAPI plugins.
+  // @param target
+  //        the dispatch target were notifications should be sent.
+  // @param callbacks
+  //        the notification callbacks to be given to PSM.
+  // @param topLevelOuterContentWindowId
+  //        indicate the top level outer content window in which
+  //        this transaction is being loaded.
+  // @param responseBody
+  //        the input stream that will contain the response data.  async
+  //        wait on this input stream for data.  on first notification,
+  //        headers should be available (check transaction status).
+  //
+  MOZ_MUST_USE nsresult virtual Init(
+      uint32_t caps, nsHttpConnectionInfo* connInfo,
+      nsHttpRequestHead* reqHeaders, nsIInputStream* reqBody,
+      uint64_t reqContentLength, bool reqBodyIncludesHeaders,
+      nsIEventTarget* consumerTarget, nsIInterfaceRequestor* callbacks,
+      nsITransportEventSink* eventsink, uint64_t topLevelOuterContentWindowId,
+      HttpTrafficCategory trafficCategory,
+      nsIAsyncInputStream** responseBody) = 0;
+
+  virtual void SetClassOfService(uint32_t classOfService) = 0;
+
+  // Called to take ownership of the response headers; the transaction
+  // will drop any reference to the response headers after this call.
+  virtual nsHttpResponseHead* TakeResponseHead() = 0;
+
+  // Called to take ownership of the trailer headers.
+  // Returning null if there is no trailer.
+  virtual nsHttpHeaderArray* TakeResponseTrailers() = 0;
+
+  virtual nsISupports* SecurityInfo() = 0;
+  virtual void SetSecurityCallbacks(nsIInterfaceRequestor* aCallbacks) = 0;
+
+  virtual void GetNetworkAddresses(NetAddr& self, NetAddr& peer) = 0;
+
+  // Functions for Timing interface
+  virtual mozilla::TimeStamp GetDomainLookupStart() = 0;
+  virtual mozilla::TimeStamp GetDomainLookupEnd() = 0;
+  virtual mozilla::TimeStamp GetConnectStart() = 0;
+  virtual mozilla::TimeStamp GetTcpConnectEnd() = 0;
+  virtual mozilla::TimeStamp GetSecureConnectionStart() = 0;
+
+  virtual mozilla::TimeStamp GetConnectEnd() = 0;
+  virtual mozilla::TimeStamp GetRequestStart() = 0;
+  virtual mozilla::TimeStamp GetResponseStart() = 0;
+  virtual mozilla::TimeStamp GetResponseEnd() = 0;
+
+  virtual void SetDomainLookupStart(mozilla::TimeStamp timeStamp,
+                                    bool onlyIfNull = false) = 0;
+  virtual void SetDomainLookupEnd(mozilla::TimeStamp timeStamp,
+                                  bool onlyIfNull = false) = 0;
+
+  virtual const TimingStruct Timings() = 0;
+
+  // Called to set/find out if the transaction generated a complete response.
+  virtual bool ResponseIsComplete() = 0;
+  virtual int64_t GetTransferSize() = 0;
+  virtual int64_t GetRequestSize() = 0;
+
+  // Called to notify that a requested DNS cache entry was refreshed.
+  virtual void SetDNSWasRefreshed() = 0;
+
+  virtual void DontReuseConnection() = 0;
+  virtual bool HasStickyConnection() const = 0;
+
+  virtual void SetH2WSConnRefTaken() = 0;
+  virtual void SetTransactionObserver(TransactionObserver* arg) = 0;
+  virtual void SetRequestContext(nsIRequestContext* aRequestContext) = 0;
+  virtual void SetPushedStream(Http2PushedStreamWrapper* push) = 0;
+
+  virtual bool ProxyConnectFailed() = 0;
+  virtual bool ResolvedByTRR() = 0;
+
+  virtual nsHttpTransaction* AsHttpTransaction() = 0;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(HttpTransactionShell, HTTPTRANSACTIONSHELL_IID)
+
+#define NS_DECL_HTTPTRANSACTIONSHELL                                           \
+  virtual nsresult Init(                                                       \
+      uint32_t caps, nsHttpConnectionInfo* connInfo,                           \
+      nsHttpRequestHead* reqHeaders, nsIInputStream* reqBody,                  \
+      uint64_t reqContentLength, bool reqBodyIncludesHeaders,                  \
+      nsIEventTarget* consumerTarget, nsIInterfaceRequestor* callbacks,        \
+      nsITransportEventSink* eventsink, uint64_t topLevelOuterContentWindowId, \
+      HttpTrafficCategory trafficCategory, nsIAsyncInputStream** responseBody) \
+      override;                                                                \
+  virtual void SetClassOfService(uint32_t classOfService) override;            \
+  virtual nsHttpResponseHead* TakeResponseHead() override;                     \
+  virtual nsHttpHeaderArray* TakeResponseTrailers() override;                  \
+  virtual nsISupports* SecurityInfo() override;                                \
+  virtual void SetSecurityCallbacks(nsIInterfaceRequestor* aCallbacks)         \
+      override;                                                                \
+  virtual void GetNetworkAddresses(NetAddr& self, NetAddr& peer) override;     \
+  virtual mozilla::TimeStamp GetDomainLookupStart() override;                  \
+  virtual mozilla::TimeStamp GetDomainLookupEnd() override;                    \
+  virtual mozilla::TimeStamp GetConnectStart() override;                       \
+  virtual mozilla::TimeStamp GetTcpConnectEnd() override;                      \
+  virtual mozilla::TimeStamp GetSecureConnectionStart() override;              \
+  virtual mozilla::TimeStamp GetConnectEnd() override;                         \
+  virtual mozilla::TimeStamp GetRequestStart() override;                       \
+  virtual mozilla::TimeStamp GetResponseStart() override;                      \
+  virtual mozilla::TimeStamp GetResponseEnd() override;                        \
+  virtual void SetDomainLookupStart(mozilla::TimeStamp timeStamp,              \
+                                    bool onlyIfNull = false) override;         \
+  virtual void SetDomainLookupEnd(mozilla::TimeStamp timeStamp,                \
+                                  bool onlyIfNull = false) override;           \
+  virtual const TimingStruct Timings() override;                               \
+  virtual bool ResponseIsComplete() override;                                  \
+  virtual int64_t GetTransferSize() override;                                  \
+  virtual int64_t GetRequestSize() override;                                   \
+  virtual void SetDNSWasRefreshed() override;                                  \
+  virtual void DontReuseConnection() override;                                 \
+  virtual bool HasStickyConnection() const override;                           \
+  virtual void SetH2WSConnRefTaken() override;                                 \
+  virtual void SetTransactionObserver(TransactionObserver* arg) override;      \
+  virtual void SetRequestContext(nsIRequestContext* aRequestContext) override; \
+  virtual void SetPushedStream(Http2PushedStreamWrapper* push) override;       \
+  virtual bool ProxyConnectFailed() override;                                  \
+  virtual bool ResolvedByTRR() override;                                       \
+  virtual nsHttpTransaction* AsHttpTransaction() override;
+}  // namespace net
+}  // namespace mozilla
+
+#endif  // HttpTransactionShell_h__
--- a/netwerk/protocol/http/NullHttpTransaction.cpp
+++ b/netwerk/protocol/http/NullHttpTransaction.cpp
@@ -85,17 +85,16 @@ NS_IMPL_ISUPPORTS(NullHttpTransaction, N
                   nsISupportsWeakReference)
 
 NullHttpTransaction::NullHttpTransaction(nsHttpConnectionInfo* ci,
                                          nsIInterfaceRequestor* callbacks,
                                          uint32_t caps)
     : mStatus(NS_OK),
       mCaps(caps | NS_HTTP_ALLOW_KEEPALIVE),
       mRequestHead(nullptr),
-      mCapsToClear(0),
       mIsDone(false),
       mClaimed(false),
       mFastOpenStatus(TFO_NOT_TRIED),
       mCallbacks(callbacks),
       mConnectionInfo(ci) {
   nsresult rv;
   mActivityDistributor =
       do_GetService(NS_HTTPACTIVITYDISTRIBUTOR_CONTRACTID, &rv);
@@ -191,22 +190,17 @@ void NullHttpTransaction::OnTransportSta
         PR_Now(), progress, EmptyCString()));
   }
 }
 
 bool NullHttpTransaction::IsDone() { return mIsDone; }
 
 nsresult NullHttpTransaction::Status() { return mStatus; }
 
-uint32_t NullHttpTransaction::Caps() { return mCaps & ~mCapsToClear; }
-
-void NullHttpTransaction::SetDNSWasRefreshed() {
-  MOZ_ASSERT(NS_IsMainThread(), "SetDNSWasRefreshed on main thread only!");
-  mCapsToClear |= NS_HTTP_REFRESH_DNS;
-}
+uint32_t NullHttpTransaction::Caps() { return mCaps; }
 
 nsresult NullHttpTransaction::ReadSegments(nsAHttpSegmentReader* reader,
                                            uint32_t count,
                                            uint32_t* countRead) {
   *countRead = 0;
   mIsDone = true;
   return NS_BASE_STREAM_CLOSED;
 }
--- a/netwerk/protocol/http/NullHttpTransaction.h
+++ b/netwerk/protocol/http/NullHttpTransaction.h
@@ -74,24 +74,16 @@ class NullHttpTransaction : public nsAHt
  private:
   nsresult mStatus;
 
  protected:
   uint32_t mCaps;
   nsHttpRequestHead* mRequestHead;
 
  private:
-  // mCapsToClear holds flags that should be cleared in mCaps, e.g. unset
-  // NS_HTTP_REFRESH_DNS when DNS refresh request has completed to avoid
-  // redundant requests on the network. The member itself is atomic, but
-  // access to it from the networking thread may happen either before or
-  // after the main thread modifies it. To deal with raciness, only unsetting
-  // bitfields should be allowed: 'lost races' will thus err on the
-  // conservative side, e.g. by going ahead with a 2nd DNS refresh.
-  Atomic<uint32_t> mCapsToClear;
   bool mIsDone;
   bool mClaimed;
   TimingStruct mTimings;
   uint8_t mFastOpenStatus;
 
  protected:
   RefPtr<nsAHttpConnection> mConnection;
   nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
--- a/netwerk/protocol/http/TunnelUtils.cpp
+++ b/netwerk/protocol/http/TunnelUtils.cpp
@@ -708,24 +708,16 @@ nsresult TLSFilterTransaction::Status() 
 uint32_t TLSFilterTransaction::Caps() {
   if (!mTransaction) {
     return 0;
   }
 
   return mTransaction->Caps();
 }
 
-void TLSFilterTransaction::SetDNSWasRefreshed() {
-  if (!mTransaction) {
-    return;
-  }
-
-  mTransaction->SetDNSWasRefreshed();
-}
-
 void TLSFilterTransaction::SetProxyConnectFailed() {
   if (!mTransaction) {
     return;
   }
 
   mTransaction->SetProxyConnectFailed();
 }
 
--- a/netwerk/protocol/http/nsAHttpTransaction.h
+++ b/netwerk/protocol/http/nsAHttpTransaction.h
@@ -73,19 +73,16 @@ class nsAHttpTransaction : public nsSupp
   virtual void OnTransportStatus(nsITransport* transport, nsresult status,
                                  int64_t progress) = 0;
 
   // called to check the transaction status.
   virtual bool IsDone() = 0;
   virtual nsresult Status() = 0;
   virtual uint32_t Caps() = 0;
 
-  // called to notify that a requested DNS cache entry was refreshed.
-  virtual void SetDNSWasRefreshed() = 0;
-
   // called to read request data from the transaction.
   virtual MOZ_MUST_USE nsresult ReadSegments(nsAHttpSegmentReader* reader,
                                              uint32_t count,
                                              uint32_t* countRead) = 0;
 
   // called to write response data to the transaction.
   virtual MOZ_MUST_USE nsresult WriteSegments(nsAHttpSegmentWriter* writer,
                                               uint32_t count,
@@ -230,17 +227,16 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpTra
   void SetConnection(nsAHttpConnection*) override;                             \
   nsAHttpConnection* Connection() override;                                    \
   void GetSecurityCallbacks(nsIInterfaceRequestor**) override;                 \
   void OnTransportStatus(nsITransport* transport, nsresult status,             \
                          int64_t progress) override;                           \
   bool IsDone() override;                                                      \
   nsresult Status() override;                                                  \
   uint32_t Caps() override;                                                    \
-  void SetDNSWasRefreshed() override;                                          \
   virtual MOZ_MUST_USE nsresult ReadSegments(nsAHttpSegmentReader*, uint32_t,  \
                                              uint32_t*) override;              \
   virtual MOZ_MUST_USE nsresult WriteSegments(nsAHttpSegmentWriter*, uint32_t, \
                                               uint32_t*) override;             \
   virtual void Close(nsresult reason) override;                                \
   nsHttpConnectionInfo* ConnectionInfo() override;                             \
   void SetProxyConnectFailed() override;                                       \
   virtual nsHttpRequestHead* RequestHead() override;                           \
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -835,17 +835,17 @@ nsresult nsHttpChannel::ContinueConnect(
     LOG(("  mLoadFlags & LOAD_NO_NETWORK_IO"));
     return NS_ERROR_DOCUMENT_NOT_CACHED;
   }
 
   // hit the net...
   return DoConnect();
 }
 
-nsresult nsHttpChannel::DoConnect(nsHttpTransaction* aTransWithStickyConn) {
+nsresult nsHttpChannel::DoConnect(HttpTransactionShell* aTransWithStickyConn) {
   LOG(("nsHttpChannel::DoConnect [this=%p, aTransWithStickyConn=%p]\n", this,
        aTransWithStickyConn));
 
   nsresult rv = SetupTransaction();
   if (NS_FAILED(rv)) {
     return rv;
   }
 
@@ -6115,17 +6115,17 @@ NS_IMETHODIMP nsHttpChannel::CloseSticky
   }
 
   MOZ_ASSERT(mTransaction);
   if (!mTransaction) {
     return NS_ERROR_UNEXPECTED;
   }
 
   if (!(mCaps & NS_HTTP_STICKY_CONNECTION ||
-        mTransaction->Caps() & NS_HTTP_STICKY_CONNECTION)) {
+        mTransaction->HasStickyConnection())) {
     LOG(("  not sticky"));
     return NS_OK;
   }
 
   mTransaction->DontReuseConnection();
   return NS_OK;
 }
 
@@ -7934,19 +7934,19 @@ nsHttpChannel::OnStopRequest(nsIRequest*
     mStronglyFramed = mTransaction->ResponseIsComplete();
     LOG(("nsHttpChannel %p has a strongly framed transaction: %d", this,
          mStronglyFramed));
 
     // Save the reference of |mTransaction| to |transactionWithStickyConn|
     // when it has a sticky connection.
     // In the case we need to retry an authentication request, we need to
     // reuse the connection of |transactionWithStickyConn|.
-    RefPtr<nsHttpTransaction> transactionWithStickyConn;
+    RefPtr<HttpTransactionShell> transactionWithStickyConn;
     if (mCaps & NS_HTTP_STICKY_CONNECTION ||
-        mTransaction->Caps() & NS_HTTP_STICKY_CONNECTION) {
+        mTransaction->HasStickyConnection()) {
       transactionWithStickyConn = mTransaction;
       LOG(("  transaction %p has sticky connection",
            transactionWithStickyConn.get()));
     }
 
     // this code relies on the code in nsHttpTransaction::Close, which
     // tests for NS_HTTP_STICKY_CONNECTION to determine whether or not to
     // keep the connection around after the transaction is finished.
@@ -8033,17 +8033,17 @@ nsHttpChannel::OnStopRequest(nsIRequest*
                                                transactionWithStickyConn);
   }
 
   return ContinueOnStopRequest(status, isFromNet, contentComplete);
 }
 
 nsresult nsHttpChannel::ContinueOnStopRequestAfterAuthRetry(
     nsresult aStatus, bool aAuthRetry, bool aIsFromNet, bool aContentComplete,
-    nsHttpTransaction* aTransWithStickyConn) {
+    HttpTransactionShell* aTransWithStickyConn) {
   LOG(
       ("nsHttpChannel::ContinueOnStopRequestAfterAuthRetry "
        "[this=%p, aStatus=%" PRIx32
        " aAuthRetry=%d, aIsFromNet=%d, aTransWithStickyConn=%p]\n",
        this, static_cast<uint32_t>(aStatus), aAuthRetry, aIsFromNet,
        aTransWithStickyConn));
 
   if (aAuthRetry && NS_SUCCEEDED(aStatus)) {
@@ -9005,17 +9005,17 @@ nsHttpChannel::ResumeAt(uint64_t aStartP
        aStartPos, PromiseFlatCString(aEntityID).get()));
   mEntityID = aEntityID;
   mStartPos = aStartPos;
   mResuming = true;
   return NS_OK;
 }
 
 nsresult nsHttpChannel::DoAuthRetry(
-    nsHttpTransaction* aTransWithStickyConn,
+    HttpTransactionShell* aTransWithStickyConn,
     const std::function<nsresult(nsHttpChannel*, nsresult)>&
         aContinueOnStopRequestFunc) {
   LOG(("nsHttpChannel::DoAuthRetry [this=%p, aTransWithStickyConn=%p]\n", this,
        aTransWithStickyConn));
 
   MOZ_ASSERT(!mTransaction, "should not have a transaction");
 
   // Note that we don't have to toggle |mIsPending| anymore. See the reasons
@@ -9032,25 +9032,25 @@ nsresult nsHttpChannel::DoAuthRetry(
   // the server response could have included cookies that must be sent with
   // this authentication attempt (bug 84794).
   // TODO: save cookies from auth response and send them here (bug 572151).
   AddCookiesToRequest();
 
   // notify "http-on-modify-request" observers
   CallOnModifyRequestObservers();
 
-  RefPtr<nsHttpTransaction> trans(aTransWithStickyConn);
+  RefPtr<HttpTransactionShell> trans(aTransWithStickyConn);
   return CallOrWaitForResume(
       [trans{std::move(trans)}, aContinueOnStopRequestFunc](auto* self) {
         return self->ContinueDoAuthRetry(trans, aContinueOnStopRequestFunc);
       });
 }
 
 nsresult nsHttpChannel::ContinueDoAuthRetry(
-    nsHttpTransaction* aTransWithStickyConn,
+    HttpTransactionShell* aTransWithStickyConn,
     const std::function<nsresult(nsHttpChannel*, nsresult)>&
         aContinueOnStopRequestFunc) {
   LOG(("nsHttpChannel::ContinueDoAuthRetry [this=%p]\n", this));
 
   mIsPending = true;
 
   // get rid of the old response headers
   mResponseHead = nullptr;
@@ -9073,17 +9073,17 @@ nsresult nsHttpChannel::ContinueDoAuthRe
   } else {
     LOG(("  connection made non-restartable"));
     mCaps &= ~NS_HTTP_CONNECTION_RESTARTABLE;
   }
 
   // notify "http-on-before-connect" observers
   gHttpHandler->OnBeforeConnect(this);
 
-  RefPtr<nsHttpTransaction> trans(aTransWithStickyConn);
+  RefPtr<HttpTransactionShell> trans(aTransWithStickyConn);
   return CallOrWaitForResume(
       [trans{std::move(trans)}, aContinueOnStopRequestFunc](auto* self) {
         nsresult rv = self->DoConnect(trans);
         return aContinueOnStopRequestFunc(self, rv);
       });
 }
 
 //-----------------------------------------------------------------------------
--- a/netwerk/protocol/http/nsHttpChannel.h
+++ b/netwerk/protocol/http/nsHttpChannel.h
@@ -423,28 +423,28 @@ class nsHttpChannel final : public HttpB
   MOZ_MUST_USE nsresult ProcessPartialContent(
       const std::function<nsresult(nsHttpChannel*, nsresult)>&
           aContinueProcessResponseFunc);
   MOZ_MUST_USE nsresult
   ContinueProcessResponseAfterPartialContent(nsresult aRv);
   MOZ_MUST_USE nsresult OnDoneReadingPartialCacheEntry(bool* streamDone);
 
   MOZ_MUST_USE nsresult
-  DoAuthRetry(nsHttpTransaction* aTransWithStickyConn,
+  DoAuthRetry(HttpTransactionShell* aTransWithStickyConn,
               const std::function<nsresult(nsHttpChannel*, nsresult)>&
                   aContinueOnStopRequestFunc);
   MOZ_MUST_USE nsresult
-  ContinueDoAuthRetry(nsHttpTransaction* aTransWithStickyConn,
+  ContinueDoAuthRetry(HttpTransactionShell* aTransWithStickyConn,
                       const std::function<nsresult(nsHttpChannel*, nsresult)>&
                           aContinueOnStopRequestFunc);
   MOZ_MUST_USE nsresult
-  DoConnect(nsHttpTransaction* aTransWithStickyConn = nullptr);
+  DoConnect(HttpTransactionShell* aTransWithStickyConn = nullptr);
   MOZ_MUST_USE nsresult ContinueOnStopRequestAfterAuthRetry(
       nsresult aStatus, bool aAuthRetry, bool aIsFromNet, bool aContentComplete,
-      nsHttpTransaction* aTransWithStickyConn);
+      HttpTransactionShell* aTransWithStickyConn);
   MOZ_MUST_USE nsresult ContinueOnStopRequest(nsresult status, bool aIsFromNet,
                                               bool aContentComplete);
 
   void HandleAsyncRedirectChannelToHttps();
   MOZ_MUST_USE nsresult StartRedirectChannelToHttps();
   MOZ_MUST_USE nsresult ContinueAsyncRedirectChannelToURI(nsresult rv);
   MOZ_MUST_USE nsresult OpenRedirectChannel(nsresult rv);
 
@@ -599,17 +599,17 @@ class nsHttpChannel final : public HttpB
   void PerformBackgroundCacheRevalidation();
   // This method can only be called on the main thread.
   void PerformBackgroundCacheRevalidationNow();
 
  private:
   nsCOMPtr<nsICancelable> mProxyRequest;
 
   RefPtr<nsInputStreamPump> mTransactionPump;
-  RefPtr<nsHttpTransaction> mTransaction;
+  RefPtr<HttpTransactionShell> mTransaction;
 
   uint64_t mLogicalOffset;
 
   // cache specific data
   nsCOMPtr<nsICacheEntry> mCacheEntry;
   // This will be set during OnStopRequest() before calling CloseCacheEntry(),
   // but only if the listener wants to use alt-data (signaled by
   // HttpBaseChannel::mPreferredCachedAltDataType being not empty)
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -573,24 +573,24 @@ class nsCompleteUpgradeData : public ARe
  private:
   virtual ~nsCompleteUpgradeData() {
     NS_ReleaseOnMainThreadSystemGroup("nsCompleteUpgradeData.mUpgradeListener",
                                       mUpgradeListener.forget());
   }
 };
 
 nsresult nsHttpConnectionMgr::CompleteUpgrade(
-    nsHttpTransaction* aTrans, nsIHttpUpgradeListener* aUpgradeListener) {
+    HttpTransactionShell* aTrans, nsIHttpUpgradeListener* aUpgradeListener) {
   // test if aUpgradeListener is a wrapped JsObject
   nsCOMPtr<nsIXPConnectWrappedJS> wrapper = do_QueryInterface(aUpgradeListener);
 
   bool wrapped = !!wrapper;
 
-  RefPtr<nsCompleteUpgradeData> data =
-      new nsCompleteUpgradeData(aTrans, aUpgradeListener, wrapped);
+  RefPtr<nsCompleteUpgradeData> data = new nsCompleteUpgradeData(
+      aTrans->AsHttpTransaction(), aUpgradeListener, wrapped);
   return PostEvent(&nsHttpConnectionMgr::OnMsgCompleteUpgrade, 0, data);
 }
 
 nsresult nsHttpConnectionMgr::UpdateParam(nsParamName name, uint16_t value) {
   uint32_t param = (uint32_t(name) << 16) | uint32_t(value);
   return PostEvent(&nsHttpConnectionMgr::OnMsgUpdateParam,
                    static_cast<int32_t>(param), nullptr);
 }
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
@@ -165,17 +165,17 @@ class nsHttpConnectionMgr final : public
 
   // called by the main thread to execute the taketransport() logic on the
   // socket thread after a 101 response has been received and the socket
   // needs to be transferred to an expectant upgrade listener such as
   // websockets.
   // @param aTrans: a transaction that contains a sticky connection. We'll
   //                take the transport of this connection.
   MOZ_MUST_USE nsresult CompleteUpgrade(
-      nsHttpTransaction* aTrans, nsIHttpUpgradeListener* aUpgradeListener);
+      HttpTransactionShell* aTrans, nsIHttpUpgradeListener* aUpgradeListener);
 
   // called to update a parameter after the connection manager has already
   // been initialized.
   MOZ_MUST_USE nsresult UpdateParam(nsParamName name, uint16_t value);
 
   // called from main thread to post a new request token bucket
   // to the socket thread
   MOZ_MUST_USE nsresult UpdateRequestTokenBucket(EventTokenBucket* aBucket);
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -2694,10 +2694,38 @@ HttpTrafficAnalyzer* nsHttpHandler::GetH
 
   return &mHttpTrafficAnalyzer;
 }
 
 bool nsHttpHandler::IsHttp3VersionSupportedHex(const nsACString& version) {
   return version.LowerCaseEqualsLiteral(kHttp3VersionHEX);
 }
 
+nsresult nsHttpHandler::InitiateTransaction(HttpTransactionShell* aTrans,
+                                            int32_t aPriority) {
+  return mConnMgr->AddTransaction(aTrans->AsHttpTransaction(), aPriority);
+}
+nsresult nsHttpHandler::InitiateTransactionWithStickyConn(
+    HttpTransactionShell* aTrans, int32_t aPriority,
+    HttpTransactionShell* aTransWithStickyConn) {
+  return mConnMgr->AddTransactionWithStickyConn(
+      aTrans->AsHttpTransaction(), aPriority,
+      aTransWithStickyConn->AsHttpTransaction());
+}
+
+nsresult nsHttpHandler::RescheduleTransaction(HttpTransactionShell* trans,
+                                              int32_t priority) {
+  return mConnMgr->RescheduleTransaction(trans->AsHttpTransaction(), priority);
+}
+
+void nsHttpHandler::UpdateClassOfServiceOnTransaction(
+    HttpTransactionShell* trans, uint32_t classOfService) {
+  mConnMgr->UpdateClassOfServiceOnTransaction(trans->AsHttpTransaction(),
+                                              classOfService);
+}
+
+nsresult nsHttpHandler::CancelTransaction(HttpTransactionShell* trans,
+                                          nsresult reason) {
+  return mConnMgr->CancelTransaction(trans->AsHttpTransaction(), reason);
+}
+
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -40,17 +40,17 @@ namespace net {
 
 bool OnSocketThread();
 
 class ATokenBucketEvent;
 class EventTokenBucket;
 class Tickler;
 class nsHttpConnection;
 class nsHttpConnectionInfo;
-class nsHttpTransaction;
+class HttpTransactionShell;
 class AltSvcMapping;
 
 /*
  * FRAMECHECK_LAX - no check
  * FRAMECHECK_BARELY - allows:
  *                     1) that chunk-encoding does not have the last 0-size
  *                     chunk. So, if a chunked-encoded transfer ends on exactly
  *                     a chunk boundary we consider that fine. This will allows
@@ -259,49 +259,38 @@ class nsHttpHandler final : public nsIHt
   //
   // - the handler keeps a count of active connections to enforce the
   //   steady-state max-connections pref.
   //
 
   // Called to kick-off a new transaction, by default the transaction
   // will be put on the pending transaction queue if it cannot be
   // initiated at this time.  Callable from any thread.
-  MOZ_MUST_USE nsresult InitiateTransaction(nsHttpTransaction* trans,
-                                            int32_t priority) {
-    return mConnMgr->AddTransaction(trans, priority);
-  }
+  MOZ_MUST_USE nsresult InitiateTransaction(HttpTransactionShell* trans,
+                                            int32_t priority);
 
   // This function is also called to kick-off a new transaction. But the new
   // transaction will take a sticky connection from |transWithStickyConn|
   // and reuse it.
-  MOZ_MUST_USE nsresult
-  InitiateTransactionWithStickyConn(nsHttpTransaction* trans, int32_t priority,
-                                    nsHttpTransaction* transWithStickyConn) {
-    return mConnMgr->AddTransactionWithStickyConn(trans, priority,
-                                                  transWithStickyConn);
-  }
+  MOZ_MUST_USE nsresult InitiateTransactionWithStickyConn(
+      HttpTransactionShell* trans, int32_t priority,
+      HttpTransactionShell* transWithStickyConn);
 
   // Called to change the priority of an existing transaction that has
   // already been initiated.
-  MOZ_MUST_USE nsresult RescheduleTransaction(nsHttpTransaction* trans,
-                                              int32_t priority) {
-    return mConnMgr->RescheduleTransaction(trans, priority);
-  }
+  MOZ_MUST_USE nsresult RescheduleTransaction(HttpTransactionShell* trans,
+                                              int32_t priority);
 
-  void UpdateClassOfServiceOnTransaction(nsHttpTransaction* trans,
-                                         uint32_t classOfService) {
-    mConnMgr->UpdateClassOfServiceOnTransaction(trans, classOfService);
-  }
+  void UpdateClassOfServiceOnTransaction(HttpTransactionShell* trans,
+                                         uint32_t classOfService);
 
   // Called to cancel a transaction, which may or may not be assigned to
   // a connection.  Callable from any thread.
-  MOZ_MUST_USE nsresult CancelTransaction(nsHttpTransaction* trans,
-                                          nsresult reason) {
-    return mConnMgr->CancelTransaction(trans, reason);
-  }
+  MOZ_MUST_USE nsresult CancelTransaction(HttpTransactionShell* trans,
+                                          nsresult reason);
 
   // Called when a connection is done processing a transaction.  Callable
   // from any thread.
   MOZ_MUST_USE nsresult ReclaimConnection(nsHttpConnection* conn) {
     return mConnMgr->ReclaimConnection(conn);
   }
 
   MOZ_MUST_USE nsresult ProcessPendingQ(nsHttpConnectionInfo* cinfo) {
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -977,16 +977,42 @@ nsresult nsHttpTransaction::WriteSegment
   } else if (mThrottlingReadAllowance > 0 && NS_SUCCEEDED(rv)) {
     MOZ_ASSERT(count >= *countWritten);
     mThrottlingReadAllowance -= *countWritten;
   }
 
   return rv;
 }
 
+bool nsHttpTransaction::ProxyConnectFailed() { return mProxyConnectFailed; }
+
+nsISupports* nsHttpTransaction::SecurityInfo() { return mSecurityInfo; }
+
+bool nsHttpTransaction::HasStickyConnection() const {
+  return mCaps & NS_HTTP_STICKY_CONNECTION;
+}
+
+bool nsHttpTransaction::ResponseIsComplete() { return mResponseIsComplete; }
+
+int64_t nsHttpTransaction::GetTransferSize() { return mTransferSize; }
+
+int64_t nsHttpTransaction::GetRequestSize() { return mRequestSize; }
+
+void nsHttpTransaction::SetTransactionObserver(TransactionObserver* arg) {
+  mTransactionObserver = arg;
+}
+
+void nsHttpTransaction::SetPushedStream(Http2PushedStreamWrapper* push) {
+  mPushedStream = push;
+}
+
+bool nsHttpTransaction::ResolvedByTRR() { return mResolvedByTRR; }
+
+nsHttpTransaction* nsHttpTransaction::AsHttpTransaction() { return this; }
+
 void nsHttpTransaction::Close(nsresult reason) {
   LOG(("nsHttpTransaction::Close [this=%p reason=%" PRIx32 "]\n", this,
        static_cast<uint32_t>(reason)));
 
   if (!mClosed) {
     gHttpHandler->ConnMgr()->RemoveActiveTransaction(this);
     mActivated = false;
   }
--- a/netwerk/protocol/http/nsHttpTransaction.h
+++ b/netwerk/protocol/http/nsHttpTransaction.h
@@ -3,16 +3,17 @@
  * 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/. */
 
 #ifndef nsHttpTransaction_h__
 #define nsHttpTransaction_h__
 
 #include "nsHttp.h"
 #include "nsAHttpTransaction.h"
+#include "HttpTransactionShell.h"
 #include "nsAHttpConnection.h"
 #include "EventTokenBucket.h"
 #include "nsCOMPtr.h"
 #include "nsThreadUtils.h"
 #include "nsIInterfaceRequestor.h"
 #include "TimingStruct.h"
 #include "Http2Push.h"
 #include "mozilla/net/DNS.h"
@@ -38,90 +39,43 @@ class NullHttpTransaction;
 class SpdyConnectTransaction;
 
 //-----------------------------------------------------------------------------
 // nsHttpTransaction represents a single HTTP transaction.  It is thread-safe,
 // intended to run on the socket thread.
 //-----------------------------------------------------------------------------
 
 class nsHttpTransaction final : public nsAHttpTransaction,
+                                public HttpTransactionShell,
                                 public ATokenBucketEvent,
                                 public nsIInputStreamCallback,
                                 public nsIOutputStreamCallback,
                                 public ARefBase {
  public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSAHTTPTRANSACTION
+  NS_DECL_HTTPTRANSACTIONSHELL
   NS_DECL_NSIINPUTSTREAMCALLBACK
   NS_DECL_NSIOUTPUTSTREAMCALLBACK
 
   nsHttpTransaction();
 
-  //
-  // called to initialize the transaction
-  //
-  // @param caps
-  //        the transaction capabilities (see nsHttp.h)
-  // @param connInfo
-  //        the connection type for this transaction.
-  // @param reqHeaders
-  //        the request header struct
-  // @param reqBody
-  //        the request body (POST or PUT data stream)
-  // @param reqBodyIncludesHeaders
-  //        fun stuff to support NPAPI plugins.
-  // @param target
-  //        the dispatch target were notifications should be sent.
-  // @param callbacks
-  //        the notification callbacks to be given to PSM.
-  // @param topLevelOuterContentWindowId
-  //        indicate the top level outer content window in which
-  //        this transaction is being loaded.
-  // @param responseBody
-  //        the input stream that will contain the response data.  async
-  //        wait on this input stream for data.  on first notification,
-  //        headers should be available (check transaction status).
-  //
-  MOZ_MUST_USE nsresult
-  Init(uint32_t caps, nsHttpConnectionInfo* connInfo,
-       nsHttpRequestHead* reqHeaders, nsIInputStream* reqBody,
-       uint64_t reqContentLength, bool reqBodyIncludesHeaders,
-       nsIEventTarget* consumerTarget, nsIInterfaceRequestor* callbacks,
-       nsITransportEventSink* eventsink, uint64_t topLevelOuterContentWindowId,
-       HttpTrafficCategory trafficCategory, nsIAsyncInputStream** responseBody);
-
   void OnActivated() override;
 
   // attributes
   nsHttpResponseHead* ResponseHead() {
     return mHaveAllHeaders ? mResponseHead : nullptr;
   }
-  nsISupports* SecurityInfo() { return mSecurityInfo; }
 
   nsIEventTarget* ConsumerTarget() { return mConsumerTarget; }
   nsISupports* HttpChannel() { return mChannel; }
 
-  void SetSecurityCallbacks(nsIInterfaceRequestor* aCallbacks);
-
-  // Called to take ownership of the response headers; the transaction
-  // will drop any reference to the response headers after this call.
-  nsHttpResponseHead* TakeResponseHead();
-
-  // Called to take ownership of the trailer headers.
-  // Returning null if there is no trailer.
-  nsHttpHeaderArray* TakeResponseTrailers();
-
-  void SetH2WSConnRefTaken();
-
   // Called to set/find out if the transaction generated a complete response.
-  bool ResponseIsComplete() { return mResponseIsComplete; }
   void SetResponseIsComplete() { mResponseIsComplete = true; }
 
-  bool ProxyConnectFailed() { return mProxyConnectFailed; }
-
   void EnableKeepAlive() { mCaps |= NS_HTTP_ALLOW_KEEPALIVE; }
   void MakeSticky() { mCaps |= NS_HTTP_STICKY_CONNECTION; }
   void MakeNonSticky() override { mCaps &= ~NS_HTTP_STICKY_CONNECTION; }
 
   // SetPriority() may only be used by the connection manager.
   void SetPriority(int32_t priority) { mPriority = priority; }
   int32_t Priority() { return mPriority; }
 
@@ -131,64 +85,41 @@ class nsHttpTransaction final : public n
   // is false)
   void SetPendingTime(bool now = true) {
     mPendingTime = now ? TimeStamp::Now() : TimeStamp();
   }
   const TimeStamp GetPendingTime() { return mPendingTime; }
 
   // overload of nsAHttpTransaction::RequestContext()
   nsIRequestContext* RequestContext() override { return mRequestContext.get(); }
-  void SetRequestContext(nsIRequestContext* aRequestContext);
   void DispatchedAsBlocking();
   void RemoveDispatchedAsBlocking();
 
   void DisableSpdy() override;
 
-  void DoNotRemoveAltSvc() override { mDoNotRemoveAltSvc = true; }
-
   nsHttpTransaction* QueryHttpTransaction() override { return this; }
 
   already_AddRefed<Http2PushedStreamWrapper> GetPushedStream() {
     return do_AddRef(mPushedStream);
   }
   already_AddRefed<Http2PushedStreamWrapper> TakePushedStream() {
     return mPushedStream.forget();
   }
 
-  void SetPushedStream(Http2PushedStreamWrapper* push) { mPushedStream = push; }
   uint32_t InitialRwin() const { return mInitialRwin; };
   bool ChannelPipeFull() { return mWaitingOnPipeOut; }
 
   // Locked methods to get and set timing info
-  const TimingStruct Timings();
   void BootstrapTimings(TimingStruct times);
-  void SetDomainLookupStart(mozilla::TimeStamp timeStamp,
-                            bool onlyIfNull = false);
-  void SetDomainLookupEnd(mozilla::TimeStamp timeStamp,
-                          bool onlyIfNull = false);
   void SetConnectStart(mozilla::TimeStamp timeStamp, bool onlyIfNull = false);
   void SetConnectEnd(mozilla::TimeStamp timeStamp, bool onlyIfNull = false);
   void SetRequestStart(mozilla::TimeStamp timeStamp, bool onlyIfNull = false);
   void SetResponseStart(mozilla::TimeStamp timeStamp, bool onlyIfNull = false);
   void SetResponseEnd(mozilla::TimeStamp timeStamp, bool onlyIfNull = false);
 
-  mozilla::TimeStamp GetDomainLookupStart();
-  mozilla::TimeStamp GetDomainLookupEnd();
-  mozilla::TimeStamp GetConnectStart();
-  mozilla::TimeStamp GetTcpConnectEnd();
-  mozilla::TimeStamp GetSecureConnectionStart();
-
-  mozilla::TimeStamp GetConnectEnd();
-  mozilla::TimeStamp GetRequestStart();
-  mozilla::TimeStamp GetResponseStart();
-  mozilla::TimeStamp GetResponseEnd();
-
-  int64_t GetTransferSize() { return mTransferSize; }
-  int64_t GetRequestSize() { return mRequestSize; }
-
   MOZ_MUST_USE bool Do0RTT() override;
   MOZ_MUST_USE nsresult Finish0RTT(bool aRestart,
                                    bool aAlpnChanged /* ignored */) override;
 
   // After Finish0RTT early data may have failed but the caller did not request
   // restart - this indicates that state for dev tools
   void Refused0RTT();
 
@@ -425,26 +356,23 @@ class nsHttpTransaction final : public n
   // Called by the connetion manager on the socket thread when reading for this
   // previously throttled transaction has to be resumed.
   void ResumeReading();
 
   // This examins classification of this transaction whether the Throttleable
   // class has been set while Leader, Unblocked, DontThrottle has not.
   bool EligibleForThrottling() const;
 
-  void DontReuseConnection();
-
  private:
   bool mSubmittedRatePacing;
   bool mPassedRatePacing;
   bool mSynchronousRatePaceRequest;
   nsCOMPtr<nsICancelable> mTokenBucketCancel;
 
  public:
-  void SetClassOfService(uint32_t cos);
   uint32_t ClassOfService() { return mClassOfService; }
 
  private:
   uint32_t mClassOfService;
 
  public:
   // setting TunnelProvider to non-null means the transaction should only
   // be dispatched on a specific ConnectionInfo Hash Key (as opposed to a
@@ -454,30 +382,17 @@ class nsHttpTransaction final : public n
   // The tunnel provider is used for ASpdySession::MaybeReTunnel() checks.
 
   void SetTunnelProvider(ASpdySession* provider) { mTunnelProvider = provider; }
   ASpdySession* TunnelProvider() { return mTunnelProvider; }
   nsIInterfaceRequestor* SecurityCallbacks() { return mCallbacks; }
 
  private:
   RefPtr<ASpdySession> mTunnelProvider;
-
- public:
-  void SetTransactionObserver(TransactionObserver* arg) {
-    mTransactionObserver = arg;
-  }
-
- private:
   RefPtr<TransactionObserver> mTransactionObserver;
-
- public:
-  void GetNetworkAddresses(NetAddr& self, NetAddr& peer);
-  bool ResolvedByTRR() { return mResolvedByTRR; }
-
- private:
   NetAddr mSelfAddr;
   NetAddr mPeerAddr;
   bool mResolvedByTRR;
 
   bool m0RTTInProgress;
   bool mDoNotTryEarlyData;
   enum {
     EARLY_NONE,