Bug 1754737 - Add some structure to nsHttpConnection: r=necko-reviewers,kershaw

- nsHttpConnection now has states. Currently only proxy setup phase is added to the states.
- The states are used in nsHttpConnection::OnSocketWritable tto make the code more understandable.
- Some pieces of selfcontained code are extracted from nsHttpConnection::OnHeadersAvailable, i.e. HandleTunnelResponse and HandleWebSocketResponse

Differential Revision: https://phabricator.services.mozilla.com/D138714
This commit is contained in:
Dragana Damjanovic 2022-02-22 11:21:38 +00:00
Родитель 8673dcf418
Коммит 0248b17c59
2 изменённых файлов: 241 добавлений и 164 удалений

Просмотреть файл

@ -161,6 +161,12 @@ nsresult nsHttpConnection::Init(
return NS_OK;
}
void nsHttpConnection::ChangeState(HttpConnectionState newState) {
LOG(("nsHttpConnection::ChanfeState %d -> %d [this=%p]", mState, newState,
this));
mState = newState;
}
nsresult nsHttpConnection::TryTakeSubTransactions(
nsTArray<RefPtr<nsAHttpTransaction> >& list) {
nsresult rv = mTransaction->TakeSubTransactions(list);
@ -315,11 +321,7 @@ void nsHttpConnection::StartSpdy(nsISSLSocketControl* sslControl,
("nsHttpConnection::StartSpdy %p Connecting To a HTTP/2 "
"Proxy and Need Connect",
this));
MOZ_ASSERT(mProxyConnectStream);
mProxyConnectStream = nullptr;
mCompletedProxyConnect = true;
mProxyConnectInProgress = false;
SetTunnelSetupDone();
}
nsresult rv = NS_OK;
@ -658,13 +660,8 @@ nsresult nsHttpConnection::Activate(nsAHttpTransaction* trans, uint32_t caps,
// need to handle HTTP CONNECT tunnels if this is the first time if
// we are tunneling through a proxy
nsresult rv = NS_OK;
if (mTransaction->ConnectionInfo()->UsingConnect() &&
!mCompletedProxyConnect) {
rv = SetupProxyConnect();
if (NS_FAILED(rv)) goto failed_activation;
mProxyConnectInProgress = true;
}
nsresult rv = CheckTunnelIsNeeded();
if (NS_FAILED(rv)) goto failed_activation;
// Clear the per activation counter
mCurrentBytesRead = 0;
@ -1200,77 +1197,101 @@ nsresult nsHttpConnection::OnHeadersAvailable(nsAHttpTransaction* trans,
--mRemainingConnectionUses;
}
switch (mState) {
case HttpConnectionState::SETTING_UP_TUNNEL:
HandleTunnelResponse(responseStatus, reset);
break;
default:
if (requestHead->HasHeader(nsHttp::Upgrade)) {
HandleWebSocketResponse(requestHead, responseHead, responseStatus);
} else if (responseStatus == 101) {
// We got an 101 but we are not asking of a WebSsocket?
Close(NS_ERROR_ABORT);
}
}
mLastHttpResponseVersion = responseHead->Version();
return NS_OK;
}
void nsHttpConnection::HandleTunnelResponse(uint16_t responseStatus,
bool* reset) {
MOZ_ASSERT(TunnelSetupInProgress());
MOZ_ASSERT(mProxyConnectStream);
MOZ_ASSERT(mUsingSpdyVersion == SpdyVersion::NONE,
"SPDY NPN Complete while using proxy connect stream");
// If we're doing a proxy connect, we need to check whether or not
// it was successful. If so, we have to reset the transaction and step-up
// the socket connection if using SSL. Finally, we have to wake up the
// socket write request.
bool itWasProxyConnect = !!mProxyConnectStream;
if (mProxyConnectStream) {
MOZ_ASSERT(mUsingSpdyVersion == SpdyVersion::NONE,
"SPDY NPN Complete while using proxy connect stream");
mProxyConnectStream = nullptr;
bool isHttps = mTransaction ? mTransaction->ConnectionInfo()->EndToEndSSL()
: mConnInfo->EndToEndSSL();
bool onlyConnect = mTransactionCaps & NS_HTTP_CONNECT_ONLY;
mTransaction->OnProxyConnectComplete(responseStatus);
if (responseStatus == 200) {
LOG(("proxy CONNECT succeeded! endtoendssl=%d onlyconnect=%d\n", isHttps,
onlyConnect));
// If we're only connecting, we don't need to reset the transaction
// state. We need to upgrade the socket now without doing the actual
// http request.
if (!onlyConnect) {
*reset = true;
}
nsresult rv;
// CONNECT only flag doesn't do the tls setup. https here only
// ensures a proxy tunnel was used not that tls is setup.
if (isHttps) {
if (!onlyConnect) {
if (mConnInfo->UsingHttpsProxy()) {
LOG(("%p new TLSFilterTransaction %s %d\n", this,
mConnInfo->Origin(), mConnInfo->OriginPort()));
SetupSecondaryTLS();
}
rv = InitSSLParams(false, true);
LOG(("InitSSLParams [rv=%" PRIx32 "]\n", static_cast<uint32_t>(rv)));
} else {
// We have an https protocol but the CONNECT only flag was
// specified. The consumer only wants a raw socket to the
// proxy. We have to mark this as complete to finish the
// transaction and be upgraded. OnSocketReadable() uses this
// to detect an inactive tunnel and blocks completion.
mNPNComplete = true;
}
}
mCompletedProxyConnect = true;
mProxyConnectInProgress = false;
rv = mSocketOut->AsyncWait(this, 0, 0, nullptr);
// XXX what if this fails -- need to handle this error
MOZ_ASSERT(NS_SUCCEEDED(rv), "mSocketOut->AsyncWait failed");
} else {
LOG(("proxy CONNECT failed! endtoendssl=%d onlyconnect=%d\n", isHttps,
onlyConnect));
mTransaction->SetProxyConnectFailed();
}
if (responseStatus == 200) {
ChangeState(HttpConnectionState::TUNNEL_DONE);
}
mProxyConnectStream = nullptr;
bool isHttps = mTransaction ? mTransaction->ConnectionInfo()->EndToEndSSL()
: mConnInfo->EndToEndSSL();
bool onlyConnect = mTransactionCaps & NS_HTTP_CONNECT_ONLY;
nsAutoCString upgradeReq;
bool hasUpgradeReq =
NS_SUCCEEDED(requestHead->GetHeader(nsHttp::Upgrade, upgradeReq));
mTransaction->OnProxyConnectComplete(responseStatus);
if (responseStatus == 200) {
LOG(("proxy CONNECT succeeded! endtoendssl=%d onlyconnect=%d\n", isHttps,
onlyConnect));
// If we're only connecting, we don't need to reset the transaction
// state. We need to upgrade the socket now without doing the actual
// http request.
if (!onlyConnect) {
*reset = true;
}
nsresult rv;
// CONNECT only flag doesn't do the tls setup. https here only
// ensures a proxy tunnel was used not that tls is setup.
if (isHttps) {
if (!onlyConnect) {
if (mConnInfo->UsingHttpsProxy()) {
LOG(("%p new TLSFilterTransaction %s %d\n", this, mConnInfo->Origin(),
mConnInfo->OriginPort()));
SetupSecondaryTLS();
}
rv = InitSSLParams(false, true);
LOG(("InitSSLParams [rv=%" PRIx32 "]\n", static_cast<uint32_t>(rv)));
} else {
// We have an https protocol but the CONNECT only flag was
// specified. The consumer only wants a raw socket to the
// proxy. We have to mark this as complete to finish the
// transaction and be upgraded. OnSocketReadable() uses this
// to detect an inactive tunnel and blocks completion.
mNPNComplete = true;
}
}
rv = mSocketOut->AsyncWait(this, 0, 0, nullptr);
// XXX what if this fails -- need to handle this error
MOZ_ASSERT(NS_SUCCEEDED(rv), "mSocketOut->AsyncWait failed");
} else {
LOG(("proxy CONNECT failed! endtoendssl=%d onlyconnect=%d\n", isHttps,
onlyConnect));
mTransaction->SetProxyConnectFailed();
}
}
void nsHttpConnection::HandleWebSocketResponse(nsHttpRequestHead* requestHead,
nsHttpResponseHead* responseHead,
uint16_t responseStatus) {
// Don't use persistent connection for Upgrade unless there's an auth failure:
// some proxies expect to see auth response on persistent connection.
// Also allow persistent conn for h2, as we don't want to waste connections
// for multiplexed upgrades.
if (!itWasProxyConnect && hasUpgradeReq && responseStatus != 401 &&
responseStatus != 407 && !mSpdySession) {
if (responseStatus != 401 && responseStatus != 407 && !mSpdySession) {
LOG(("HTTP Upgrade in play - disable keepalive for http/1.x\n"));
DontReuse();
}
if (responseStatus == 101) {
nsAutoCString upgradeReq;
bool hasUpgradeReq =
NS_SUCCEEDED(requestHead->GetHeader(nsHttp::Upgrade, upgradeReq));
nsAutoCString upgradeResp;
bool hasUpgradeResp =
NS_SUCCEEDED(responseHead->GetHeader(nsHttp::Upgrade, upgradeResp));
@ -1286,10 +1307,6 @@ nsresult nsHttpConnection::OnHeadersAvailable(nsAHttpTransaction* trans,
LOG(("HTTP Upgrade Response to %s\n", upgradeResp.get()));
}
}
mLastHttpResponseVersion = responseHead->Version();
return NS_OK;
}
bool nsHttpConnection::IsReused() {
@ -1692,14 +1709,6 @@ void nsHttpConnection::CloseTransaction(nsAHttpTransaction* trans,
mIsReused = true;
}
nsresult nsHttpConnection::ReadFromStream(nsIInputStream* input, void* closure,
const char* buf, uint32_t offset,
uint32_t count, uint32_t* countRead) {
// thunk for nsIInputStream instance
nsHttpConnection* conn = (nsHttpConnection*)closure;
return conn->OnReadSegment(buf, count, countRead);
}
bool nsHttpConnection::CheckCanWrite0RTTData() {
MOZ_ASSERT(EarlyDataAvailable());
nsCOMPtr<nsISupports> securityInfo;
@ -1764,7 +1773,7 @@ nsresult nsHttpConnection::OnReadSegment(const char* buf, uint32_t count,
} else {
mLastWriteTime = PR_IntervalNow();
mSocketOutCondition = NS_OK; // reset condition
if (!mProxyConnectInProgress) mTotalBytesWritten += *countRead;
if (!TunnelSetupInProgress()) mTotalBytesWritten += *countRead;
}
return mSocketOutCondition;
@ -1784,7 +1793,7 @@ nsresult nsHttpConnection::OnSocketWritable() {
uint32_t writeAttempts = 0;
if (mTransactionCaps & NS_HTTP_CONNECT_ONLY) {
if (!mCompletedProxyConnect && !mProxyConnectStream) {
if (!TunnelUsed()) {
// A CONNECT has been requested for this connection but will never
// be performed. This should never happen.
MOZ_ASSERT(false, "proxy connect will never happen");
@ -1792,7 +1801,7 @@ nsresult nsHttpConnection::OnSocketWritable() {
return NS_ERROR_FAILURE;
}
if (mCompletedProxyConnect) {
if (TunnelCompleted()) {
// Don't need to check this each write attempt since it is only
// updated after OnSocketWritable completes.
// We've already done primary tls (if needed) and sent our CONNECT.
@ -1808,50 +1817,51 @@ nsresult nsHttpConnection::OnSocketWritable() {
rv = mSocketOutCondition = NS_OK;
transactionBytes = 0;
// The SSL handshake must be completed before the
// transaction->readsegments() processing can proceed because we need to
// know how to format the request differently for http/1, http/2, spdy,
// etc.. and that is negotiated with NPN/ALPN in the SSL handshake.
if (mConnInfo->UsingHttpsProxy() && !EnsureNPNComplete()) {
MOZ_DIAGNOSTIC_ASSERT(!EarlyDataAvailable());
mSocketOutCondition = NS_BASE_STREAM_WOULD_BLOCK;
} else if (mProxyConnectStream) {
// If we're need an HTTP/1 CONNECT tunnel through a proxy
// send it before doing the SSL handshake
LOG((" writing CONNECT request stream\n"));
rv = mProxyConnectStream->ReadSegments(ReadFromStream, this,
nsIOService::gDefaultSegmentSize,
&transactionBytes);
} else if (!EnsureNPNComplete() &&
(!EarlyDataUsed() || mTlsHandshakeComplitionPending)) {
// The handshake is not done and we cannot write 0RTT data or nss has
// already finished 0RTT data.
mSocketOutCondition = NS_BASE_STREAM_WOULD_BLOCK;
} else if (!mTransaction) {
rv = NS_ERROR_FAILURE;
LOG((" No Transaction In OnSocketWritable\n"));
} else if (NS_SUCCEEDED(rv)) {
// for non spdy sessions let the connection manager know
if (!mReportedSpdy && mNPNComplete) {
mReportedSpdy = true;
MOZ_ASSERT(!mEverUsedSpdy);
gHttpHandler->ConnMgr()->ReportSpdyConnection(this, false);
}
LOG((" writing transaction request stream\n"));
MOZ_DIAGNOSTIC_ASSERT(!mProxyConnectInProgress || !EarlyDataAvailable());
mProxyConnectInProgress = false;
rv = mTransaction->ReadSegmentsAgain(
this, nsIOService::gDefaultSegmentSize, &transactionBytes, &again);
if (EarlyDataUsed()) {
mContentBytesWritten0RTT += transactionBytes;
if (NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) {
// If an error happens while writting 0RTT data, restart
// the transactiions without 0RTT.
FinishNPNSetup(false, true);
switch (mState) {
case HttpConnectionState::SETTING_UP_TUNNEL:
if (mConnInfo->UsingHttpsProxy() && !EnsureNPNComplete()) {
MOZ_DIAGNOSTIC_ASSERT(!EarlyDataAvailable());
mSocketOutCondition = NS_BASE_STREAM_WOULD_BLOCK;
} else {
rv = SendConnectRequest(this, &transactionBytes);
}
break;
default: {
// The SSL handshake must be completed before the
// transaction->readsegments() processing can proceed because we need to
// know how to format the request differently for http/1, http/2, spdy,
// etc.. and that is negotiated with NPN/ALPN in the SSL handshake.
if (!EnsureNPNComplete() &&
(!EarlyDataUsed() || mTlsHandshakeComplitionPending)) {
// The handshake is not done and we cannot write 0RTT data or nss has
// already finished 0RTT data.
mSocketOutCondition = NS_BASE_STREAM_WOULD_BLOCK;
} else if (!mTransaction) {
rv = NS_ERROR_FAILURE;
LOG((" No Transaction In OnSocketWritable\n"));
} else if (NS_SUCCEEDED(rv)) {
// for non spdy sessions let the connection manager know
if (!mReportedSpdy && mNPNComplete) {
mReportedSpdy = true;
MOZ_ASSERT(!mEverUsedSpdy);
gHttpHandler->ConnMgr()->ReportSpdyConnection(this, false);
}
LOG((" writing transaction request stream\n"));
rv = mTransaction->ReadSegmentsAgain(this,
nsIOService::gDefaultSegmentSize,
&transactionBytes, &again);
if (EarlyDataUsed()) {
mContentBytesWritten0RTT += transactionBytes;
if (NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) {
// If an error happens while writting 0RTT data, restart
// the transactiions without 0RTT.
FinishNPNSetup(false, true);
}
} else {
mContentBytesWritten += transactionBytes;
}
}
} else {
mContentBytesWritten += transactionBytes;
}
}
@ -1955,8 +1965,7 @@ nsresult nsHttpConnection::OnSocketReadable() {
// Reset mResponseTimeoutEnabled to stop response timeout checks.
mResponseTimeoutEnabled = false;
if ((mTransactionCaps & NS_HTTP_CONNECT_ONLY) && !mCompletedProxyConnect &&
!mProxyConnectStream) {
if ((mTransactionCaps & NS_HTTP_CONNECT_ONLY) && !TunnelUsed()) {
// A CONNECT has been requested for this connection but will never
// be performed. This should never happen.
MOZ_ASSERT(false, "proxy connect will never happen");
@ -1981,7 +1990,7 @@ nsresult nsHttpConnection::OnSocketReadable() {
bool again = true;
do {
if (!mProxyConnectInProgress && !EnsureNPNComplete()) {
if (!TunnelSetupInProgress() && !EnsureNPNComplete()) {
// Unless we are setting up a tunnel via CONNECT, prevent reading
// from the socket until the results of NPN
// negotiation are known (which is determined from the write path).
@ -2070,9 +2079,7 @@ void nsHttpConnection::SetInSpdyTunnel(bool arg) {
mInSpdyTunnel = arg;
// don't setup another tunnel :)
mProxyConnectStream = nullptr;
mCompletedProxyConnect = true;
mProxyConnectInProgress = false;
SetTunnelSetupDone();
}
// static
@ -2126,7 +2133,6 @@ nsresult nsHttpConnection::MakeConnectString(nsAHttpTransaction* trans,
rv = request->SetHeader(nsHttp::Proxy_Authorization, val);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
if ((trans->Caps() & NS_HTTP_CONNECT_ONLY) &&
NS_SUCCEEDED(trans->RequestHead()->GetHeader(nsHttp::Upgrade, val))) {
// rfc7639 proposes using the ALPN header to indicate the protocol used
@ -2151,22 +2157,6 @@ nsresult nsHttpConnection::MakeConnectString(nsAHttpTransaction* trans,
return NS_OK;
}
nsresult nsHttpConnection::SetupProxyConnect() {
LOG(("nsHttpConnection::SetupProxyConnect [this=%p]\n", this));
NS_ENSURE_TRUE(!mProxyConnectStream, NS_ERROR_ALREADY_INITIALIZED);
MOZ_ASSERT(mUsingSpdyVersion == SpdyVersion::NONE,
"SPDY NPN Complete while using proxy connect stream");
nsAutoCString buf;
nsHttpRequestHead request;
nsresult rv = MakeConnectString(mTransaction, &request, buf, false);
if (NS_FAILED(rv)) {
return rv;
}
return NS_NewCStringInputStream(getter_AddRefs(mProxyConnectStream),
std::move(buf));
}
nsresult nsHttpConnection::StartShortLivedTCPKeepalives() {
if (mUsingSpdyVersion != SpdyVersion::NONE) {
return NS_OK;
@ -2503,7 +2493,7 @@ bool nsHttpConnection::CanAcceptWebsocket() {
}
bool nsHttpConnection::IsProxyConnectInProgress() {
return mProxyConnectInProgress;
return mState == SETTING_UP_TUNNEL;
}
bool nsHttpConnection::LastTransactionExpectedNoContent() {
@ -2694,5 +2684,72 @@ void nsHttpConnection::HandshakeDoneInternal() {
return;
}
void nsHttpConnection::SetTunnelSetupDone() {
MOZ_ASSERT(mProxyConnectStream);
MOZ_ASSERT(mState == HttpConnectionState::SETTING_UP_TUNNEL);
ChangeState(HttpConnectionState::TUNNEL_DONE);
mProxyConnectStream = nullptr;
}
nsresult nsHttpConnection::CheckTunnelIsNeeded() {
switch (mState) {
case HttpConnectionState::UNINITIALIZED: {
// This is is called first time. Check if we need a tunnel.
if (!mTransaction->ConnectionInfo()->UsingConnect()) {
ChangeState(HttpConnectionState::TUNNEL_NOT_USED);
return NS_OK;
}
ChangeState(HttpConnectionState::SETTING_UP_TUNNEL);
}
[[fallthrough]];
case HttpConnectionState::SETTING_UP_TUNNEL: {
// When a nsHttpConnection is in this state that means that an
// authentication was needed and we are resending a CONNECT
// request. This request will include authentication headers.
nsresult rv = SetupProxyConnectStream();
if (NS_FAILED(rv)) {
ChangeState(HttpConnectionState::UNINITIALIZED);
}
return rv;
}
case HttpConnectionState::TUNNEL_DONE:
case HttpConnectionState::TUNNEL_NOT_USED:
return NS_OK;
}
}
nsresult nsHttpConnection::SetupProxyConnectStream() {
LOG(("nsHttpConnection::SetupStream\n"));
NS_ENSURE_TRUE(!mProxyConnectStream, NS_ERROR_ALREADY_INITIALIZED);
MOZ_ASSERT(mState == HttpConnectionState::SETTING_UP_TUNNEL);
nsAutoCString buf;
nsHttpRequestHead request;
nsresult rv = MakeConnectString(mTransaction, &request, buf, false);
if (NS_FAILED(rv)) {
return rv;
}
rv = NS_NewCStringInputStream(getter_AddRefs(mProxyConnectStream),
std::move(buf));
return rv;
}
nsresult nsHttpConnection::ReadFromStream(nsIInputStream* input, void* closure,
const char* buf, uint32_t offset,
uint32_t count, uint32_t* countRead) {
// thunk for nsIInputStream instance
nsHttpConnection* conn = (nsHttpConnection*)closure;
return conn->OnReadSegment(buf, count, countRead);
}
nsresult nsHttpConnection::SendConnectRequest(void* closure,
uint32_t* transactionBytes) {
LOG((" writing CONNECT request stream\n"));
return mProxyConnectStream->ReadSegments(ReadFromStream, closure,
nsIOService::gDefaultSegmentSize,
transactionBytes);
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -124,10 +124,6 @@ class nsHttpConnection final : public HttpConnectionBase,
friend class HttpConnectionForceIO;
[[nodiscard]] static nsresult ReadFromStream(nsIInputStream*, void*,
const char*, uint32_t, uint32_t,
uint32_t*);
// When a persistent connection is in the connection manager idle
// connection pool, the nsHttpConnection still reads errors and hangups
// on the socket so that it can be proactively released if the server
@ -160,10 +156,6 @@ class nsHttpConnection final : public HttpConnectionBase,
int64_t ContentBytesWritten() { return mContentBytesWritten; }
[[nodiscard]] static nsresult MakeConnectString(nsAHttpTransaction* trans,
nsHttpRequestHead* request,
nsACString& result,
bool h2ws);
void SetupSecondaryTLS(nsAHttpTransaction* aSpdyConnectTransaction = nullptr);
void SetInSpdyTunnel(bool arg);
@ -197,7 +189,40 @@ class nsHttpConnection final : public HttpConnectionBase,
bool IsForWebSocket() { return mForWebSocket; }
// The following functions are related to setting up a tunnel.
[[nodiscard]] static nsresult MakeConnectString(nsAHttpTransaction* trans,
nsHttpRequestHead* request,
nsACString& result,
bool h2ws);
[[nodiscard]] static nsresult ReadFromStream(nsIInputStream*, void*,
const char*, uint32_t, uint32_t,
uint32_t*);
private:
enum HttpConnectionState {
UNINITIALIZED,
SETTING_UP_TUNNEL,
TUNNEL_DONE,
TUNNEL_NOT_USED,
} mState{HttpConnectionState::UNINITIALIZED};
void ChangeState(HttpConnectionState newState);
// Tunnel retated functions:
bool TunnelSetupInProgress() { return mState == SETTING_UP_TUNNEL; }
bool TunnelUsed() {
return mState == SETTING_UP_TUNNEL || mState == TUNNEL_DONE;
}
bool TunnelCompleted() { return mState == TUNNEL_DONE; }
void SetTunnelSetupDone();
nsresult CheckTunnelIsNeeded();
nsresult SetupProxyConnectStream();
nsresult SendConnectRequest(void* closure, uint32_t* transactionBytes);
void HandleTunnelResponse(uint16_t responseStatus, bool* reset);
void HandleWebSocketResponse(nsHttpRequestHead* requestHead,
nsHttpResponseHead* responseHead,
uint16_t responseStatus);
// Value (set in mTCPKeepaliveConfig) indicates which set of prefs to use.
enum TCPKeepaliveConfig {
kTCPKeepaliveDisabled = 0,
@ -214,8 +239,6 @@ class nsHttpConnection final : public HttpConnectionBase,
[[nodiscard]] nsresult OnSocketWritable();
[[nodiscard]] nsresult OnSocketReadable();
[[nodiscard]] nsresult SetupProxyConnect();
PRIntervalTime IdleTime();
bool IsAlive();
@ -263,9 +286,6 @@ class nsHttpConnection final : public HttpConnectionBase,
nsresult mSocketInCondition{NS_ERROR_NOT_INITIALIZED};
nsresult mSocketOutCondition{NS_ERROR_NOT_INITIALIZED};
nsCOMPtr<nsIInputStream> mProxyConnectStream;
nsCOMPtr<nsIInputStream> mRequestStream;
RefPtr<TLSFilterTransaction> mTLSFilter;
nsWeakPtr mWeakTrans; // SpdyConnectTransaction *
@ -296,10 +316,8 @@ class nsHttpConnection final : public HttpConnectionBase,
bool mKeepAliveMask{true};
bool mDontReuse{false};
bool mIsReused{false};
bool mCompletedProxyConnect{false};
bool mLastTransactionExpectedNoContent{false};
bool mIdleMonitoring{false};
bool mProxyConnectInProgress{false};
bool mInSpdyTunnel{false};
bool mForcePlainText{false};
@ -390,6 +408,8 @@ class nsHttpConnection final : public HttpConnectionBase,
private:
bool mThroughCaptivePortal;
int64_t mTotalBytesWritten = 0; // does not include CONNECT tunnel
nsCOMPtr<nsIInputStream> mProxyConnectStream;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsHttpConnection, NS_HTTPCONNECTION_IID)