diff options
Diffstat (limited to 'netwerk/protocol/http/nsHttpTransaction.cpp')
-rw-r--r-- | netwerk/protocol/http/nsHttpTransaction.cpp | 91 |
1 files changed, 86 insertions, 5 deletions
diff --git a/netwerk/protocol/http/nsHttpTransaction.cpp b/netwerk/protocol/http/nsHttpTransaction.cpp index ee3a88489..706710d89 100644 --- a/netwerk/protocol/http/nsHttpTransaction.cpp +++ b/netwerk/protocol/http/nsHttpTransaction.cpp @@ -39,6 +39,8 @@ #include "nsIOService.h" #include "nsIRequestContext.h" #include "nsIHttpAuthenticator.h" +#include "NSSErrorsService.h" +#include "sslerr.h" #include <algorithm> #ifdef MOZ_WIDGET_GONK @@ -144,6 +146,7 @@ nsHttpTransaction::nsHttpTransaction() , mIsInIsolatedMozBrowser(false) , mClassOfService(0) , m0RTTInProgress(false) + , mTransportStatus(NS_OK) { LOG(("Creating nsHttpTransaction @%p\n", this)); gHttpHandler->GetMaxPipelineObjectSize(&mMaxPipelineObjectSize); @@ -550,6 +553,50 @@ nsHttpTransaction::OnTransportStatus(nsITransport* transport, LOG(("nsHttpTransaction::OnSocketStatus [this=%p status=%x progress=%lld]\n", this, status, progress)); + // A transaction can given to multiple HalfOpen sockets (this is a bug in + // nsHttpConnectionMgr). We are going to fix it here as a work around to be + // able to uplift it. + switch(status) { + case NS_NET_STATUS_RESOLVING_HOST: + if (mTransportStatus != NS_OK) { + LOG(("nsHttpTransaction::OnSocketStatus - ignore socket events " + "from backup transport")); + return; + } + break; + case NS_NET_STATUS_RESOLVED_HOST: + if (mTransportStatus != NS_NET_STATUS_RESOLVING_HOST && + mTransportStatus != NS_OK) { + LOG(("nsHttpTransaction::OnSocketStatus - ignore socket events " + "from backup transport")); + return; + } + break; + case NS_NET_STATUS_CONNECTING_TO: + if (mTransportStatus != NS_NET_STATUS_RESOLVING_HOST && + mTransportStatus != NS_NET_STATUS_RESOLVED_HOST && + mTransportStatus != NS_OK) { + LOG(("nsHttpTransaction::OnSocketStatus - ignore socket events " + "from backup transport")); + return; + } + break; + case NS_NET_STATUS_CONNECTED_TO: + if (mTransportStatus != NS_NET_STATUS_RESOLVING_HOST && + mTransportStatus != NS_NET_STATUS_RESOLVED_HOST && + mTransportStatus != NS_NET_STATUS_CONNECTING_TO && + mTransportStatus != NS_OK) { + LOG(("nsHttpTransaction::OnSocketStatus - ignore socket events " + "from backup transport")); + return; + } + break; + default: + LOG(("nsHttpTransaction::OnSocketStatus - a new event")); + } + + mTransportStatus = status; + if (status == NS_NET_STATUS_CONNECTED_TO || status == NS_NET_STATUS_WAITING_FOR) { nsISocketTransport *socketTransport = @@ -574,7 +621,17 @@ nsHttpTransaction::OnTransportStatus(nsITransport* transport, } else if (status == NS_NET_STATUS_CONNECTING_TO) { SetConnectStart(TimeStamp::Now()); } else if (status == NS_NET_STATUS_CONNECTED_TO) { - SetConnectEnd(TimeStamp::Now()); + SetConnectEnd(TimeStamp::Now(), true); + } else if (status == NS_NET_STATUS_TLS_HANDSHAKE_ENDED) { + { + // before overwriting connectEnd, copy it to secureConnectionStart + MutexAutoLock lock(mLock); + if (mTimings.secureConnectionStart.IsNull() && + !mTimings.connectEnd.IsNull()) { + mTimings.secureConnectionStart = mTimings.connectEnd; + } + } + SetConnectEnd(TimeStamp::Now(), false); } } @@ -998,7 +1055,9 @@ nsHttpTransaction::Close(nsresult reason) // connection. It will break that connection and also confuse the channel's // auth provider, beliving the cached credentials are wrong and asking for // the password mistakenly again from the user. - if ((reason == NS_ERROR_NET_RESET || reason == NS_OK) && + if ((reason == NS_ERROR_NET_RESET || + reason == NS_OK || + reason == psm::GetXPCOMFromNSSError(SSL_ERROR_DOWNGRADE_WITH_EARLY_DATA)) && (!(mCaps & NS_HTTP_STICKY_CONNECTION) || (mCaps & NS_HTTP_CONNECTION_RESTARTABLE))) { if (mForceRestart && NS_SUCCEEDED(Restart())) { @@ -1027,9 +1086,10 @@ nsHttpTransaction::Close(nsresult reason) bool reallySentData = mSentData && (!mConnection || mConnection->BytesWritten()); - if (!mReceivedData && + if (reason == psm::GetXPCOMFromNSSError(SSL_ERROR_DOWNGRADE_WITH_EARLY_DATA) || + (!mReceivedData && ((mRequestHead && mRequestHead->IsSafeMethod()) || - !reallySentData || connReused)) { + !reallySentData || connReused))) { // if restarting fails, then we must proceed to close the pipe, // which will notify the channel that the transaction failed. @@ -1327,6 +1387,8 @@ nsHttpTransaction::Restart() } } + mTransportStatus = NS_OK; + return gHttpHandler->InitiateTransaction(this, mPriority); } @@ -2082,6 +2144,13 @@ nsHttpTransaction::Timings() } void +nsHttpTransaction::BootstrapTimings(TimingStruct times) +{ + mozilla::MutexAutoLock lock(mLock); + mTimings = times; +} + +void nsHttpTransaction::SetDomainLookupStart(mozilla::TimeStamp timeStamp, bool onlyIfNull) { mozilla::MutexAutoLock lock(mLock); @@ -2173,6 +2242,13 @@ nsHttpTransaction::GetConnectStart() } mozilla::TimeStamp +nsHttpTransaction::GetSecureConnectionStart() +{ + mozilla::MutexAutoLock lock(mLock); + return mTimings.secureConnectionStart; +} + +mozilla::TimeStamp nsHttpTransaction::GetConnectEnd() { mozilla::MutexAutoLock lock(mLock); @@ -2440,8 +2516,9 @@ nsHttpTransaction::Do0RTT() } nsresult -nsHttpTransaction::Finish0RTT(bool aRestart) +nsHttpTransaction::Finish0RTT(bool aRestart, bool aAlpnChanged /* ignored */) { + LOG(("nsHttpTransaction::Finish0RTT %p %d %d\n", this, aRestart, aAlpnChanged)); MOZ_ASSERT(m0RTTInProgress); m0RTTInProgress = false; if (aRestart) { @@ -2453,6 +2530,10 @@ nsHttpTransaction::Finish0RTT(bool aRestart) } else { return NS_ERROR_FAILURE; } + } else if (!mConnected) { + // this is code that was skipped in ::ReadSegments while in 0RTT + mConnected = true; + mConnection->GetSecurityInfo(getter_AddRefs(mSecurityInfo)); } return NS_OK; } |