зеркало из https://github.com/mozilla/gecko-dev.git
bug 871289 [2 of 2] fix trailing whitespace in netwerk/protocol/http/* r=jduell
This commit is contained in:
Родитель
68239ec0ca
Коммит
2e232b4bd1
|
@ -34,7 +34,7 @@ ASpdySession::NewSpdySession(uint32_t version,
|
||||||
// versions, so there is no risk of the server ignoring our prefs.
|
// versions, so there is no risk of the server ignoring our prefs.
|
||||||
|
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_VERSION2, version);
|
Telemetry::Accumulate(Telemetry::SPDY_VERSION2, version);
|
||||||
|
|
||||||
if (version == SpdyInformation::SPDY_VERSION_2)
|
if (version == SpdyInformation::SPDY_VERSION_2)
|
||||||
return new SpdySession2(aTransaction, aTransport, aPriority);
|
return new SpdySession2(aTransaction, aTransport, aPriority);
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,8 @@ nsHttpConnectionMgr::OnMsgPrintDiagnostics(int32_t, void *)
|
||||||
mLogData.AppendPrintf("mNumActiveConns = %d\n", mNumActiveConns);
|
mLogData.AppendPrintf("mNumActiveConns = %d\n", mNumActiveConns);
|
||||||
mLogData.AppendPrintf("mNumIdleConns = %d\n", mNumIdleConns);
|
mLogData.AppendPrintf("mNumIdleConns = %d\n", mNumIdleConns);
|
||||||
|
|
||||||
mCT.Enumerate(PrintDiagnosticsCB, this);
|
mCT.Enumerate(PrintDiagnosticsCB, this);
|
||||||
|
|
||||||
consoleService->LogStringMessage(NS_ConvertUTF8toUTF16(mLogData).Data());
|
consoleService->LogStringMessage(NS_ConvertUTF8toUTF16(mLogData).Data());
|
||||||
mLogData.Truncate();
|
mLogData.Truncate();
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ nsHttpConnectionMgr::PrintDiagnosticsCB(const nsACString &key,
|
||||||
self->mLogData.AppendPrintf(" :: Pending Transaction #%u\n", i);
|
self->mLogData.AppendPrintf(" :: Pending Transaction #%u\n", i);
|
||||||
ent->mPendingQ[i]->PrintDiagnostics(self->mLogData);
|
ent->mPendingQ[i]->PrintDiagnostics(self->mLogData);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PL_DHASH_NEXT;
|
return PL_DHASH_NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ nsHttpConnectionMgr::nsHalfOpenSocket::PrintDiagnostics(nsCString &log)
|
||||||
HasConnected(), IsSpeculative());
|
HasConnected(), IsSpeculative());
|
||||||
|
|
||||||
TimeStamp now = TimeStamp::Now();
|
TimeStamp now = TimeStamp::Now();
|
||||||
|
|
||||||
if (mPrimarySynStarted.IsNull())
|
if (mPrimarySynStarted.IsNull())
|
||||||
log.AppendPrintf(" primary not started\n");
|
log.AppendPrintf(" primary not started\n");
|
||||||
else
|
else
|
||||||
|
@ -114,7 +114,7 @@ nsHttpConnectionMgr::nsHalfOpenSocket::PrintDiagnostics(nsCString &log)
|
||||||
else
|
else
|
||||||
log.AppendPrintf(" backup started %.2f ago\n",
|
log.AppendPrintf(" backup started %.2f ago\n",
|
||||||
(now - mBackupSynStarted).ToMilliseconds());
|
(now - mBackupSynStarted).ToMilliseconds());
|
||||||
|
|
||||||
log.AppendPrintf(" primary transport %d, backup transport %d\n",
|
log.AppendPrintf(" primary transport %d, backup transport %d\n",
|
||||||
!!mSocketTransport.get(), !!mBackupTransport.get());
|
!!mSocketTransport.get(), !!mBackupTransport.get());
|
||||||
}
|
}
|
||||||
|
@ -142,15 +142,15 @@ nsHttpConnection::PrintDiagnostics(nsCString &log)
|
||||||
|
|
||||||
log.AppendPrintf(" max-read/read/written %lld/%lld/%lld\n",
|
log.AppendPrintf(" max-read/read/written %lld/%lld/%lld\n",
|
||||||
mMaxBytesRead, mTotalBytesRead, mTotalBytesWritten);
|
mMaxBytesRead, mTotalBytesRead, mTotalBytesWritten);
|
||||||
|
|
||||||
log.AppendPrintf(" rtt = %ums\n", PR_IntervalToMilliseconds(mRtt));
|
log.AppendPrintf(" rtt = %ums\n", PR_IntervalToMilliseconds(mRtt));
|
||||||
|
|
||||||
log.AppendPrintf(" idlemonitoring = %d transactionCount=%d\n",
|
log.AppendPrintf(" idlemonitoring = %d transactionCount=%d\n",
|
||||||
mIdleMonitoring, mHttp1xTransactionCount);
|
mIdleMonitoring, mHttp1xTransactionCount);
|
||||||
|
|
||||||
log.AppendPrintf(" supports pipeline = %d classification = 0x%x\n",
|
log.AppendPrintf(" supports pipeline = %d classification = 0x%x\n",
|
||||||
mSupportsPipelining, mClassification);
|
mSupportsPipelining, mClassification);
|
||||||
|
|
||||||
if (mSpdySession)
|
if (mSpdySession)
|
||||||
mSpdySession->PrintDiagnostics(log);
|
mSpdySession->PrintDiagnostics(log);
|
||||||
}
|
}
|
||||||
|
@ -164,26 +164,26 @@ SpdySession3::PrintDiagnostics(nsCString &log)
|
||||||
|
|
||||||
log.AppendPrintf(" concurrent = %d maxconcurrent = %d\n",
|
log.AppendPrintf(" concurrent = %d maxconcurrent = %d\n",
|
||||||
mConcurrent, mMaxConcurrent);
|
mConcurrent, mMaxConcurrent);
|
||||||
|
|
||||||
log.AppendPrintf(" roomformorestreams = %d roomformoreconcurrent = %d\n",
|
log.AppendPrintf(" roomformorestreams = %d roomformoreconcurrent = %d\n",
|
||||||
RoomForMoreStreams(), RoomForMoreConcurrent());
|
RoomForMoreStreams(), RoomForMoreConcurrent());
|
||||||
|
|
||||||
log.AppendPrintf(" transactionHashCount = %d streamIDHashCount = %d\n",
|
log.AppendPrintf(" transactionHashCount = %d streamIDHashCount = %d\n",
|
||||||
mStreamTransactionHash.Count(),
|
mStreamTransactionHash.Count(),
|
||||||
mStreamIDHash.Count());
|
mStreamIDHash.Count());
|
||||||
|
|
||||||
log.AppendPrintf(" Queued Stream Size = %d\n", mQueuedStreams.GetSize());
|
log.AppendPrintf(" Queued Stream Size = %d\n", mQueuedStreams.GetSize());
|
||||||
|
|
||||||
PRIntervalTime now = PR_IntervalNow();
|
PRIntervalTime now = PR_IntervalNow();
|
||||||
log.AppendPrintf(" Ping Threshold = %ums next ping id = 0x%X\n",
|
log.AppendPrintf(" Ping Threshold = %ums next ping id = 0x%X\n",
|
||||||
PR_IntervalToMilliseconds(mPingThreshold),
|
PR_IntervalToMilliseconds(mPingThreshold),
|
||||||
mNextPingID);
|
mNextPingID);
|
||||||
log.AppendPrintf(" Ping Timeout = %ums\n",
|
log.AppendPrintf(" Ping Timeout = %ums\n",
|
||||||
PR_IntervalToMilliseconds(gHttpHandler->SpdyPingTimeout()));
|
PR_IntervalToMilliseconds(gHttpHandler->SpdyPingTimeout()));
|
||||||
log.AppendPrintf(" Idle for Any Activity (ping) = %ums\n",
|
log.AppendPrintf(" Idle for Any Activity (ping) = %ums\n",
|
||||||
PR_IntervalToMilliseconds(now - mLastReadEpoch));
|
PR_IntervalToMilliseconds(now - mLastReadEpoch));
|
||||||
log.AppendPrintf(" Idle for Data Activity = %ums\n",
|
log.AppendPrintf(" Idle for Data Activity = %ums\n",
|
||||||
PR_IntervalToMilliseconds(now - mLastDataReadEpoch));
|
PR_IntervalToMilliseconds(now - mLastDataReadEpoch));
|
||||||
if (mPingSentEpoch)
|
if (mPingSentEpoch)
|
||||||
log.AppendPrintf(" Ping Outstanding (ping) = %ums, expired = %d\n",
|
log.AppendPrintf(" Ping Outstanding (ping) = %ums, expired = %d\n",
|
||||||
PR_IntervalToMilliseconds(now - mPingSentEpoch),
|
PR_IntervalToMilliseconds(now - mPingSentEpoch),
|
||||||
|
@ -201,26 +201,26 @@ SpdySession2::PrintDiagnostics(nsCString &log)
|
||||||
|
|
||||||
log.AppendPrintf(" concurrent = %d maxconcurrent = %d\n",
|
log.AppendPrintf(" concurrent = %d maxconcurrent = %d\n",
|
||||||
mConcurrent, mMaxConcurrent);
|
mConcurrent, mMaxConcurrent);
|
||||||
|
|
||||||
log.AppendPrintf(" roomformorestreams = %d roomformoreconcurrent = %d\n",
|
log.AppendPrintf(" roomformorestreams = %d roomformoreconcurrent = %d\n",
|
||||||
RoomForMoreStreams(), RoomForMoreConcurrent());
|
RoomForMoreStreams(), RoomForMoreConcurrent());
|
||||||
|
|
||||||
log.AppendPrintf(" transactionHashCount = %d streamIDHashCount = %d\n",
|
log.AppendPrintf(" transactionHashCount = %d streamIDHashCount = %d\n",
|
||||||
mStreamTransactionHash.Count(),
|
mStreamTransactionHash.Count(),
|
||||||
mStreamIDHash.Count());
|
mStreamIDHash.Count());
|
||||||
|
|
||||||
log.AppendPrintf(" Queued Stream Size = %d\n", mQueuedStreams.GetSize());
|
log.AppendPrintf(" Queued Stream Size = %d\n", mQueuedStreams.GetSize());
|
||||||
|
|
||||||
PRIntervalTime now = PR_IntervalNow();
|
PRIntervalTime now = PR_IntervalNow();
|
||||||
log.AppendPrintf(" Ping Threshold = %ums next ping id = 0x%X\n",
|
log.AppendPrintf(" Ping Threshold = %ums next ping id = 0x%X\n",
|
||||||
PR_IntervalToMilliseconds(mPingThreshold),
|
PR_IntervalToMilliseconds(mPingThreshold),
|
||||||
mNextPingID);
|
mNextPingID);
|
||||||
log.AppendPrintf(" Ping Timeout = %ums\n",
|
log.AppendPrintf(" Ping Timeout = %ums\n",
|
||||||
PR_IntervalToMilliseconds(gHttpHandler->SpdyPingTimeout()));
|
PR_IntervalToMilliseconds(gHttpHandler->SpdyPingTimeout()));
|
||||||
log.AppendPrintf(" Idle for Any Activity (ping) = %ums\n",
|
log.AppendPrintf(" Idle for Any Activity (ping) = %ums\n",
|
||||||
PR_IntervalToMilliseconds(now - mLastReadEpoch));
|
PR_IntervalToMilliseconds(now - mLastReadEpoch));
|
||||||
log.AppendPrintf(" Idle for Data Activity = %ums\n",
|
log.AppendPrintf(" Idle for Data Activity = %ums\n",
|
||||||
PR_IntervalToMilliseconds(now - mLastDataReadEpoch));
|
PR_IntervalToMilliseconds(now - mLastDataReadEpoch));
|
||||||
if (mPingSentEpoch)
|
if (mPingSentEpoch)
|
||||||
log.AppendPrintf(" Ping Outstanding (ping) = %ums, expired = %d\n",
|
log.AppendPrintf(" Ping Outstanding (ping) = %ums, expired = %d\n",
|
||||||
PR_IntervalToMilliseconds(now - mPingSentEpoch),
|
PR_IntervalToMilliseconds(now - mPingSentEpoch),
|
||||||
|
|
|
@ -334,7 +334,7 @@ HttpBaseChannel::SetContentType(const nsACString& aContentType)
|
||||||
net_ParseContentType(aContentType, mContentTypeHint, mContentCharsetHint,
|
net_ParseContentType(aContentType, mContentTypeHint, mContentCharsetHint,
|
||||||
&dummy);
|
&dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,7 +515,7 @@ HttpBaseChannel::ExplicitSetUploadStream(nsIInputStream *aStream,
|
||||||
const nsACString &aMethod,
|
const nsACString &aMethod,
|
||||||
bool aStreamHasHeaders)
|
bool aStreamHasHeaders)
|
||||||
{
|
{
|
||||||
// Ensure stream is set and method is valid
|
// Ensure stream is set and method is valid
|
||||||
NS_ENSURE_TRUE(aStream, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(aStream, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
if (aContentLength < 0 && !aStreamHasHeaders) {
|
if (aContentLength < 0 && !aStreamHasHeaders) {
|
||||||
|
@ -530,12 +530,12 @@ HttpBaseChannel::ExplicitSetUploadStream(nsIInputStream *aStream,
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
if (!aStreamHasHeaders) {
|
if (!aStreamHasHeaders) {
|
||||||
// SetRequestHeader propagates headers to chrome if HttpChannelChild
|
// SetRequestHeader propagates headers to chrome if HttpChannelChild
|
||||||
nsAutoCString contentLengthStr;
|
nsAutoCString contentLengthStr;
|
||||||
contentLengthStr.AppendInt(aContentLength);
|
contentLengthStr.AppendInt(aContentLength);
|
||||||
SetRequestHeader(NS_LITERAL_CSTRING("Content-Length"), contentLengthStr,
|
SetRequestHeader(NS_LITERAL_CSTRING("Content-Length"), contentLengthStr,
|
||||||
false);
|
false);
|
||||||
SetRequestHeader(NS_LITERAL_CSTRING("Content-Type"), aContentType,
|
SetRequestHeader(NS_LITERAL_CSTRING("Content-Type"), aContentType,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,7 +654,7 @@ HttpBaseChannel::GetContentEncodings(nsIUTF8StringEnumerator** aEncodings)
|
||||||
*aEncodings = nullptr;
|
*aEncodings = nullptr;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *encoding = mResponseHead->PeekHeader(nsHttp::Content_Encoding);
|
const char *encoding = mResponseHead->PeekHeader(nsHttp::Content_Encoding);
|
||||||
if (!encoding) {
|
if (!encoding) {
|
||||||
*aEncodings = nullptr;
|
*aEncodings = nullptr;
|
||||||
|
@ -678,7 +678,7 @@ HttpBaseChannel::nsContentEncodings::nsContentEncodings(nsIHttpChannel* aChannel
|
||||||
mCurEnd = aEncodingHeader + strlen(aEncodingHeader);
|
mCurEnd = aEncodingHeader + strlen(aEncodingHeader);
|
||||||
mCurStart = mCurEnd;
|
mCurStart = mCurEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpBaseChannel::nsContentEncodings::~nsContentEncodings()
|
HttpBaseChannel::nsContentEncodings::~nsContentEncodings()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -730,7 +730,7 @@ HttpBaseChannel::nsContentEncodings::GetNext(nsACString& aNextEncoding)
|
||||||
haveType = true;
|
haveType = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!haveType) {
|
if (!haveType) {
|
||||||
encoding.BeginReading(start);
|
encoding.BeginReading(start);
|
||||||
if (CaseInsensitiveFindInReadable(NS_LITERAL_CSTRING("deflate"), start, end)) {
|
if (CaseInsensitiveFindInReadable(NS_LITERAL_CSTRING("deflate"), start, end)) {
|
||||||
|
@ -742,7 +742,7 @@ HttpBaseChannel::nsContentEncodings::GetNext(nsACString& aNextEncoding)
|
||||||
// Prepare to fetch the next encoding
|
// Prepare to fetch the next encoding
|
||||||
mCurEnd = mCurStart;
|
mCurEnd = mCurStart;
|
||||||
mReady = false;
|
mReady = false;
|
||||||
|
|
||||||
if (haveType)
|
if (haveType)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
|
@ -764,10 +764,10 @@ nsresult
|
||||||
HttpBaseChannel::nsContentEncodings::PrepareForNext(void)
|
HttpBaseChannel::nsContentEncodings::PrepareForNext(void)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mCurStart == mCurEnd, "Indeterminate state");
|
MOZ_ASSERT(mCurStart == mCurEnd, "Indeterminate state");
|
||||||
|
|
||||||
// At this point both mCurStart and mCurEnd point to somewhere
|
// At this point both mCurStart and mCurEnd point to somewhere
|
||||||
// past the end of the next thing we want to return
|
// past the end of the next thing we want to return
|
||||||
|
|
||||||
while (mCurEnd != mEncodingHeader) {
|
while (mCurEnd != mEncodingHeader) {
|
||||||
--mCurEnd;
|
--mCurEnd;
|
||||||
if (*mCurEnd != ',' && !nsCRT::IsAsciiSpace(*mCurEnd))
|
if (*mCurEnd != ',' && !nsCRT::IsAsciiSpace(*mCurEnd))
|
||||||
|
@ -776,17 +776,17 @@ HttpBaseChannel::nsContentEncodings::PrepareForNext(void)
|
||||||
if (mCurEnd == mEncodingHeader)
|
if (mCurEnd == mEncodingHeader)
|
||||||
return NS_ERROR_NOT_AVAILABLE; // no more encodings
|
return NS_ERROR_NOT_AVAILABLE; // no more encodings
|
||||||
++mCurEnd;
|
++mCurEnd;
|
||||||
|
|
||||||
// At this point mCurEnd points to the first char _after_ the
|
// At this point mCurEnd points to the first char _after_ the
|
||||||
// header we want. Furthermore, mCurEnd - 1 != mEncodingHeader
|
// header we want. Furthermore, mCurEnd - 1 != mEncodingHeader
|
||||||
|
|
||||||
mCurStart = mCurEnd - 1;
|
mCurStart = mCurEnd - 1;
|
||||||
while (mCurStart != mEncodingHeader &&
|
while (mCurStart != mEncodingHeader &&
|
||||||
*mCurStart != ',' && !nsCRT::IsAsciiSpace(*mCurStart))
|
*mCurStart != ',' && !nsCRT::IsAsciiSpace(*mCurStart))
|
||||||
--mCurStart;
|
--mCurStart;
|
||||||
if (*mCurStart == ',' || nsCRT::IsAsciiSpace(*mCurStart))
|
if (*mCurStart == ',' || nsCRT::IsAsciiSpace(*mCurStart))
|
||||||
++mCurStart; // we stopped because of a weird char, so move up one
|
++mCurStart; // we stopped because of a weird char, so move up one
|
||||||
|
|
||||||
// At this point mCurStart and mCurEnd bracket the encoding string
|
// At this point mCurStart and mCurEnd bracket the encoding string
|
||||||
// we want. Check that it's not "identity"
|
// we want. Check that it's not "identity"
|
||||||
if (Substring(mCurStart, mCurEnd).Equals("identity",
|
if (Substring(mCurStart, mCurEnd).Equals("identity",
|
||||||
|
@ -794,7 +794,7 @@ HttpBaseChannel::nsContentEncodings::PrepareForNext(void)
|
||||||
mCurEnd = mCurStart;
|
mCurEnd = mCurStart;
|
||||||
return PrepareForNext();
|
return PrepareForNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
mReady = true;
|
mReady = true;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -871,7 +871,7 @@ HttpBaseChannel::SetReferrer(nsIURI *referrer)
|
||||||
// perhaps some sort of generic nsINestedURI could be used. then, if an URI
|
// perhaps some sort of generic nsINestedURI could be used. then, if an URI
|
||||||
// fails the whitelist test, then we could check for an inner URI and try
|
// fails the whitelist test, then we could check for an inner URI and try
|
||||||
// that instead. though, that might be too automatic.
|
// that instead. though, that might be too automatic.
|
||||||
//
|
//
|
||||||
rv = referrer->SchemeIs("wyciwyg", &match);
|
rv = referrer->SchemeIs("wyciwyg", &match);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
if (match) {
|
if (match) {
|
||||||
|
@ -883,7 +883,7 @@ HttpBaseChannel::SetReferrer(nsIURI *referrer)
|
||||||
if (pathLength <= 2) return NS_ERROR_FAILURE;
|
if (pathLength <= 2) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
// Path is of the form "//123/http://foo/bar", with a variable number of digits.
|
// Path is of the form "//123/http://foo/bar", with a variable number of digits.
|
||||||
// To figure out where the "real" URL starts, search path for a '/', starting at
|
// To figure out where the "real" URL starts, search path for a '/', starting at
|
||||||
// the third character.
|
// the third character.
|
||||||
int32_t slashIndex = path.FindChar('/', 2);
|
int32_t slashIndex = path.FindChar('/', 2);
|
||||||
if (slashIndex == kNotFound) return NS_ERROR_FAILURE;
|
if (slashIndex == kNotFound) return NS_ERROR_FAILURE;
|
||||||
|
@ -1001,7 +1001,7 @@ HttpBaseChannel::SetRequestHeader(const nsACString& aHeader,
|
||||||
// Header names are restricted to valid HTTP tokens.
|
// Header names are restricted to valid HTTP tokens.
|
||||||
if (!nsHttp::IsValidToken(flatHeader))
|
if (!nsHttp::IsValidToken(flatHeader))
|
||||||
return NS_ERROR_INVALID_ARG;
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
|
||||||
// Header values MUST NOT contain line-breaks. RFC 2616 technically
|
// Header values MUST NOT contain line-breaks. RFC 2616 technically
|
||||||
// permits CTL characters, including CR and LF, in header values provided
|
// permits CTL characters, including CR and LF, in header values provided
|
||||||
// they are quoted. However, this can lead to problems if servers do not
|
// they are quoted. However, this can lead to problems if servers do not
|
||||||
|
@ -1040,8 +1040,8 @@ HttpBaseChannel::GetResponseHeader(const nsACString &header, nsACString &value)
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpBaseChannel::SetResponseHeader(const nsACString& header,
|
HttpBaseChannel::SetResponseHeader(const nsACString& header,
|
||||||
const nsACString& value,
|
const nsACString& value,
|
||||||
bool merge)
|
bool merge)
|
||||||
{
|
{
|
||||||
LOG(("HttpBaseChannel::SetResponseHeader [this=%p header=\"%s\" value=\"%s\" merge=%u]\n",
|
LOG(("HttpBaseChannel::SetResponseHeader [this=%p header=\"%s\" value=\"%s\" merge=%u]\n",
|
||||||
|
@ -1054,7 +1054,7 @@ HttpBaseChannel::SetResponseHeader(const nsACString& header,
|
||||||
if (!atom)
|
if (!atom)
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
|
||||||
// these response headers must not be changed
|
// these response headers must not be changed
|
||||||
if (atom == nsHttp::Content_Type ||
|
if (atom == nsHttp::Content_Type ||
|
||||||
atom == nsHttp::Content_Length ||
|
atom == nsHttp::Content_Length ||
|
||||||
atom == nsHttp::Content_Encoding ||
|
atom == nsHttp::Content_Encoding ||
|
||||||
|
@ -1347,7 +1347,7 @@ HttpBaseChannel::HTTPUpgrade(const nsACString &aProtocolName,
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG(!aProtocolName.IsEmpty());
|
NS_ENSURE_ARG(!aProtocolName.IsEmpty());
|
||||||
NS_ENSURE_ARG_POINTER(aListener);
|
NS_ENSURE_ARG_POINTER(aListener);
|
||||||
|
|
||||||
mUpgradeProtocol = aProtocolName;
|
mUpgradeProtocol = aProtocolName;
|
||||||
mUpgradeProtocolCallback = aListener;
|
mUpgradeProtocolCallback = aListener;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -1524,7 +1524,7 @@ HttpBaseChannel::AddCookiesToRequest()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool useCookieService =
|
bool useCookieService =
|
||||||
(XRE_GetProcessType() == GeckoProcessType_Default);
|
(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||||
nsXPIDLCString cookie;
|
nsXPIDLCString cookie;
|
||||||
if (useCookieService) {
|
if (useCookieService) {
|
||||||
|
@ -1561,7 +1561,7 @@ CopyProperties(const nsAString& aKey, nsIVariant *aData, void *aClosure)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
|
HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
|
||||||
nsIChannel *newChannel,
|
nsIChannel *newChannel,
|
||||||
bool preserveMethod)
|
bool preserveMethod)
|
||||||
{
|
{
|
||||||
|
@ -1583,7 +1583,7 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
|
||||||
// Do not pass along LOAD_CHECK_OFFLINE_CACHE
|
// Do not pass along LOAD_CHECK_OFFLINE_CACHE
|
||||||
newLoadFlags &= ~nsICachingChannel::LOAD_CHECK_OFFLINE_CACHE;
|
newLoadFlags &= ~nsICachingChannel::LOAD_CHECK_OFFLINE_CACHE;
|
||||||
|
|
||||||
newChannel->SetLoadGroup(mLoadGroup);
|
newChannel->SetLoadGroup(mLoadGroup);
|
||||||
newChannel->SetNotificationCallbacks(mCallbacks);
|
newChannel->SetNotificationCallbacks(mCallbacks);
|
||||||
newChannel->SetLoadFlags(newLoadFlags);
|
newChannel->SetLoadFlags(newLoadFlags);
|
||||||
|
|
||||||
|
@ -1642,8 +1642,8 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// since preserveMethod is true, we need to ensure that the appropriate
|
// since preserveMethod is true, we need to ensure that the appropriate
|
||||||
// request method gets set on the channel, regardless of whether or not
|
// request method gets set on the channel, regardless of whether or not
|
||||||
// we set the upload stream above. This means SetRequestMethod() will
|
// we set the upload stream above. This means SetRequestMethod() will
|
||||||
// be called twice if ExplicitSetUploadStream() gets called above.
|
// be called twice if ExplicitSetUploadStream() gets called above.
|
||||||
|
|
||||||
|
@ -1681,7 +1681,7 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
|
||||||
httpInternal->SetCacheKeysRedirectChain(mRedirectedCachekeys.forget());
|
httpInternal->SetCacheKeysRedirectChain(mRedirectedCachekeys.forget());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// transfer application cache information
|
// transfer application cache information
|
||||||
nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =
|
nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =
|
||||||
do_QueryInterface(newChannel);
|
do_QueryInterface(newChannel);
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace net {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This class is a partial implementation of nsIHttpChannel. It contains code
|
* This class is a partial implementation of nsIHttpChannel. It contains code
|
||||||
* shared by nsHttpChannel and HttpChannelChild.
|
* shared by nsHttpChannel and HttpChannelChild.
|
||||||
* - Note that this class has nothing to do with nsBaseChannel, which is an
|
* - Note that this class has nothing to do with nsBaseChannel, which is an
|
||||||
* earlier effort at a base class for channels that somehow never made it all
|
* earlier effort at a base class for channels that somehow never made it all
|
||||||
* the way to the HTTP channel.
|
* the way to the HTTP channel.
|
||||||
|
@ -109,11 +109,11 @@ public:
|
||||||
NS_IMETHOD GetReferrer(nsIURI **referrer);
|
NS_IMETHOD GetReferrer(nsIURI **referrer);
|
||||||
NS_IMETHOD SetReferrer(nsIURI *referrer);
|
NS_IMETHOD SetReferrer(nsIURI *referrer);
|
||||||
NS_IMETHOD GetRequestHeader(const nsACString& aHeader, nsACString& aValue);
|
NS_IMETHOD GetRequestHeader(const nsACString& aHeader, nsACString& aValue);
|
||||||
NS_IMETHOD SetRequestHeader(const nsACString& aHeader,
|
NS_IMETHOD SetRequestHeader(const nsACString& aHeader,
|
||||||
const nsACString& aValue, bool aMerge);
|
const nsACString& aValue, bool aMerge);
|
||||||
NS_IMETHOD VisitRequestHeaders(nsIHttpHeaderVisitor *visitor);
|
NS_IMETHOD VisitRequestHeaders(nsIHttpHeaderVisitor *visitor);
|
||||||
NS_IMETHOD GetResponseHeader(const nsACString &header, nsACString &value);
|
NS_IMETHOD GetResponseHeader(const nsACString &header, nsACString &value);
|
||||||
NS_IMETHOD SetResponseHeader(const nsACString& header,
|
NS_IMETHOD SetResponseHeader(const nsACString& header,
|
||||||
const nsACString& value, bool merge);
|
const nsACString& value, bool merge);
|
||||||
NS_IMETHOD VisitResponseHeaders(nsIHttpHeaderVisitor *visitor);
|
NS_IMETHOD VisitResponseHeaders(nsIHttpHeaderVisitor *visitor);
|
||||||
NS_IMETHOD GetAllowPipelining(bool *value);
|
NS_IMETHOD GetAllowPipelining(bool *value);
|
||||||
|
@ -149,13 +149,13 @@ public:
|
||||||
NS_IMETHOD SetLoadAsBlocking(bool aLoadAsBlocking);
|
NS_IMETHOD SetLoadAsBlocking(bool aLoadAsBlocking);
|
||||||
NS_IMETHOD GetLoadUnblocked(bool *aLoadUnblocked);
|
NS_IMETHOD GetLoadUnblocked(bool *aLoadUnblocked);
|
||||||
NS_IMETHOD SetLoadUnblocked(bool aLoadUnblocked);
|
NS_IMETHOD SetLoadUnblocked(bool aLoadUnblocked);
|
||||||
|
|
||||||
inline void CleanRedirectCacheChainIfNecessary()
|
inline void CleanRedirectCacheChainIfNecessary()
|
||||||
{
|
{
|
||||||
mRedirectedCachekeys = nullptr;
|
mRedirectedCachekeys = nullptr;
|
||||||
}
|
}
|
||||||
NS_IMETHOD HTTPUpgrade(const nsACString & aProtocolName,
|
NS_IMETHOD HTTPUpgrade(const nsACString & aProtocolName,
|
||||||
nsIHttpUpgradeListener *aListener);
|
nsIHttpUpgradeListener *aListener);
|
||||||
|
|
||||||
// nsISupportsPriority
|
// nsISupportsPriority
|
||||||
NS_IMETHOD GetPriority(int32_t *value);
|
NS_IMETHOD GetPriority(int32_t *value);
|
||||||
|
@ -172,19 +172,19 @@ public:
|
||||||
|
|
||||||
nsContentEncodings(nsIHttpChannel* aChannel, const char* aEncodingHeader);
|
nsContentEncodings(nsIHttpChannel* aChannel, const char* aEncodingHeader);
|
||||||
virtual ~nsContentEncodings();
|
virtual ~nsContentEncodings();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsresult PrepareForNext(void);
|
nsresult PrepareForNext(void);
|
||||||
|
|
||||||
// We do not own the buffer. The channel owns it.
|
// We do not own the buffer. The channel owns it.
|
||||||
const char* mEncodingHeader;
|
const char* mEncodingHeader;
|
||||||
const char* mCurStart; // points to start of current header
|
const char* mCurStart; // points to start of current header
|
||||||
const char* mCurEnd; // points to end of current header
|
const char* mCurEnd; // points to end of current header
|
||||||
|
|
||||||
// Hold a ref to our channel so that it can't go away and take the
|
// Hold a ref to our channel so that it can't go away and take the
|
||||||
// header with it.
|
// header with it.
|
||||||
nsCOMPtr<nsIHttpChannel> mChannel;
|
nsCOMPtr<nsIHttpChannel> mChannel;
|
||||||
|
|
||||||
bool mReady;
|
bool mReady;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -189,8 +189,8 @@ class StartRequestEvent : public ChannelEvent
|
||||||
, mPeerAddr(peerAddr)
|
, mPeerAddr(peerAddr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void Run()
|
void Run()
|
||||||
{
|
{
|
||||||
mChild->OnStartRequest(mResponseHead, mUseResponseHead, mRequestHeaders,
|
mChild->OnStartRequest(mResponseHead, mUseResponseHead, mRequestHeaders,
|
||||||
mIsFromCache, mCacheEntryAvailable,
|
mIsFromCache, mCacheEntryAvailable,
|
||||||
mCacheExpirationTime, mCachedCharset,
|
mCacheExpirationTime, mCachedCharset,
|
||||||
|
@ -210,7 +210,7 @@ class StartRequestEvent : public ChannelEvent
|
||||||
NetAddr mPeerAddr;
|
NetAddr mPeerAddr;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HttpChannelChild::RecvOnStartRequest(const nsHttpResponseHead& responseHead,
|
HttpChannelChild::RecvOnStartRequest(const nsHttpResponseHead& responseHead,
|
||||||
const bool& useResponseHead,
|
const bool& useResponseHead,
|
||||||
const nsHttpHeaderArray& requestHeaders,
|
const nsHttpHeaderArray& requestHeaders,
|
||||||
|
@ -237,7 +237,7 @@ HttpChannelChild::RecvOnStartRequest(const nsHttpResponseHead& responseHead,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HttpChannelChild::OnStartRequest(const nsHttpResponseHead& responseHead,
|
HttpChannelChild::OnStartRequest(const nsHttpResponseHead& responseHead,
|
||||||
const bool& useResponseHead,
|
const bool& useResponseHead,
|
||||||
const nsHttpHeaderArray& requestHeaders,
|
const nsHttpHeaderArray& requestHeaders,
|
||||||
|
@ -255,7 +255,7 @@ HttpChannelChild::OnStartRequest(const nsHttpResponseHead& responseHead,
|
||||||
mResponseHead = new nsHttpResponseHead(responseHead);
|
mResponseHead = new nsHttpResponseHead(responseHead);
|
||||||
|
|
||||||
if (!securityInfoSerialization.IsEmpty()) {
|
if (!securityInfoSerialization.IsEmpty()) {
|
||||||
NS_DeserializeObject(securityInfoSerialization,
|
NS_DeserializeObject(securityInfoSerialization,
|
||||||
getter_AddRefs(mSecurityInfo));
|
getter_AddRefs(mSecurityInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ HttpChannelChild::RecvOnTransportAndData(const nsresult& status,
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ.ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new TransportAndDataEvent(this, status, progress,
|
mEventQ.Enqueue(new TransportAndDataEvent(this, status, progress,
|
||||||
progressMax, data, offset,
|
progressMax, data, offset,
|
||||||
count));
|
count));
|
||||||
} else {
|
} else {
|
||||||
OnTransportAndData(status, progress, progressMax, data, offset, count);
|
OnTransportAndData(status, progress, progressMax, data, offset, count);
|
||||||
|
@ -424,7 +424,7 @@ class StopRequestEvent : public ChannelEvent
|
||||||
nsresult mStatusCode;
|
nsresult mStatusCode;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HttpChannelChild::RecvOnStopRequest(const nsresult& statusCode)
|
HttpChannelChild::RecvOnStopRequest(const nsresult& statusCode)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ.ShouldEnqueue()) {
|
||||||
|
@ -435,10 +435,10 @@ HttpChannelChild::RecvOnStopRequest(const nsresult& statusCode)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HttpChannelChild::OnStopRequest(const nsresult& statusCode)
|
HttpChannelChild::OnStopRequest(const nsresult& statusCode)
|
||||||
{
|
{
|
||||||
LOG(("HttpChannelChild::OnStopRequest [this=%x status=%u]\n",
|
LOG(("HttpChannelChild::OnStopRequest [this=%x status=%u]\n",
|
||||||
this, statusCode));
|
this, statusCode));
|
||||||
|
|
||||||
mIsPending = false;
|
mIsPending = false;
|
||||||
|
@ -517,8 +517,8 @@ HttpChannelChild::OnProgress(const uint64_t& progress,
|
||||||
|
|
||||||
// block socket status event after Cancel or OnStopRequest has been called,
|
// block socket status event after Cancel or OnStopRequest has been called,
|
||||||
// or if channel has LOAD_BACKGROUND set
|
// or if channel has LOAD_BACKGROUND set
|
||||||
if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending &&
|
if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending &&
|
||||||
!(mLoadFlags & LOAD_BACKGROUND))
|
!(mLoadFlags & LOAD_BACKGROUND))
|
||||||
{
|
{
|
||||||
if (progress > 0) {
|
if (progress > 0) {
|
||||||
MOZ_ASSERT(progress <= progressMax, "unexpected progress values");
|
MOZ_ASSERT(progress <= progressMax, "unexpected progress values");
|
||||||
|
@ -568,8 +568,8 @@ HttpChannelChild::OnStatus(const nsresult& status)
|
||||||
|
|
||||||
// block socket status event after Cancel or OnStopRequest has been called,
|
// block socket status event after Cancel or OnStopRequest has been called,
|
||||||
// or if channel has LOAD_BACKGROUND set
|
// or if channel has LOAD_BACKGROUND set
|
||||||
if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending &&
|
if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending &&
|
||||||
!(mLoadFlags & LOAD_BACKGROUND))
|
!(mLoadFlags & LOAD_BACKGROUND))
|
||||||
{
|
{
|
||||||
nsAutoCString host;
|
nsAutoCString host;
|
||||||
mURI->GetHost(host);
|
mURI->GetHost(host);
|
||||||
|
@ -669,10 +669,10 @@ class Redirect1Event : public ChannelEvent
|
||||||
, mRedirectFlags(redirectFlags)
|
, mRedirectFlags(redirectFlags)
|
||||||
, mResponseHead(responseHead) {}
|
, mResponseHead(responseHead) {}
|
||||||
|
|
||||||
void Run()
|
void Run()
|
||||||
{
|
{
|
||||||
mChild->Redirect1Begin(mNewChannelId, mNewURI, mRedirectFlags,
|
mChild->Redirect1Begin(mNewChannelId, mNewURI, mRedirectFlags,
|
||||||
mResponseHead);
|
mResponseHead);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
HttpChannelChild* mChild;
|
HttpChannelChild* mChild;
|
||||||
|
@ -729,7 +729,7 @@ HttpChannelChild::Redirect1Begin(const uint32_t& newChannelId,
|
||||||
|
|
||||||
bool rewriteToGET = nsHttp::ShouldRewriteRedirectToGET(
|
bool rewriteToGET = nsHttp::ShouldRewriteRedirectToGET(
|
||||||
mResponseHead->Status(), mRequestHead.Method());
|
mResponseHead->Status(), mRequestHead.Method());
|
||||||
|
|
||||||
rv = SetupReplacementChannel(uri, newChannel, !rewriteToGET);
|
rv = SetupReplacementChannel(uri, newChannel, !rewriteToGET);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
// Veto redirect. nsHttpChannel decides to cancel or continue.
|
// Veto redirect. nsHttpChannel decides to cancel or continue.
|
||||||
|
@ -744,7 +744,7 @@ HttpChannelChild::Redirect1Begin(const uint32_t& newChannelId,
|
||||||
NS_ERROR("Redirecting to a protocol that doesn't support universal protocol redirect");
|
NS_ERROR("Redirecting to a protocol that doesn't support universal protocol redirect");
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = gHttpHandler->AsyncOnChannelRedirect(this,
|
rv = gHttpHandler->AsyncOnChannelRedirect(this,
|
||||||
newChannel,
|
newChannel,
|
||||||
redirectFlags);
|
redirectFlags);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
|
@ -825,7 +825,7 @@ HttpChannelChild::ConnectParent(uint32_t id)
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelChild::CompleteRedirectSetup(nsIStreamListener *listener,
|
HttpChannelChild::CompleteRedirectSetup(nsIStreamListener *listener,
|
||||||
nsISupports *aContext)
|
nsISupports *aContext)
|
||||||
{
|
{
|
||||||
LOG(("HttpChannelChild::FinishRedirectSetup [this=%x]\n", this));
|
LOG(("HttpChannelChild::FinishRedirectSetup [this=%x]\n", this));
|
||||||
|
@ -845,7 +845,7 @@ HttpChannelChild::CompleteRedirectSetup(nsIStreamListener *listener,
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
mListenerContext = aContext;
|
mListenerContext = aContext;
|
||||||
|
|
||||||
// add ourselves to the load group.
|
// add ourselves to the load group.
|
||||||
if (mLoadGroup)
|
if (mLoadGroup)
|
||||||
mLoadGroup->AddRequest(this, nullptr);
|
mLoadGroup->AddRequest(this, nullptr);
|
||||||
|
|
||||||
|
@ -1019,7 +1019,7 @@ HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
mListenerContext = aContext;
|
mListenerContext = aContext;
|
||||||
|
|
||||||
// add ourselves to the load group.
|
// add ourselves to the load group.
|
||||||
if (mLoadGroup)
|
if (mLoadGroup)
|
||||||
mLoadGroup->AddRequest(this, nullptr);
|
mLoadGroup->AddRequest(this, nullptr);
|
||||||
|
|
||||||
|
@ -1097,8 +1097,8 @@ HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelChild::SetRequestHeader(const nsACString& aHeader,
|
HttpChannelChild::SetRequestHeader(const nsACString& aHeader,
|
||||||
const nsACString& aValue,
|
const nsACString& aValue,
|
||||||
bool aMerge)
|
bool aMerge)
|
||||||
{
|
{
|
||||||
nsresult rv = HttpBaseChannel::SetRequestHeader(aHeader, aValue, aMerge);
|
nsresult rv = HttpBaseChannel::SetRequestHeader(aHeader, aValue, aMerge);
|
||||||
|
@ -1352,7 +1352,7 @@ HttpChannelChild::GetAssociatedContentSecurity(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* attribute unsigned long countSubRequestsBrokenSecurity; */
|
/* attribute unsigned long countSubRequestsBrokenSecurity; */
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelChild::GetCountSubRequestsBrokenSecurity(
|
HttpChannelChild::GetCountSubRequestsBrokenSecurity(
|
||||||
int32_t *aSubRequestsBrokenSecurity)
|
int32_t *aSubRequestsBrokenSecurity)
|
||||||
{
|
{
|
||||||
|
@ -1362,7 +1362,7 @@ HttpChannelChild::GetCountSubRequestsBrokenSecurity(
|
||||||
|
|
||||||
return assoc->GetCountSubRequestsBrokenSecurity(aSubRequestsBrokenSecurity);
|
return assoc->GetCountSubRequestsBrokenSecurity(aSubRequestsBrokenSecurity);
|
||||||
}
|
}
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelChild::SetCountSubRequestsBrokenSecurity(
|
HttpChannelChild::SetCountSubRequestsBrokenSecurity(
|
||||||
int32_t aSubRequestsBrokenSecurity)
|
int32_t aSubRequestsBrokenSecurity)
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,8 +67,8 @@ public:
|
||||||
NS_IMETHOD GetSecurityInfo(nsISupports **aSecurityInfo);
|
NS_IMETHOD GetSecurityInfo(nsISupports **aSecurityInfo);
|
||||||
NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext);
|
NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext);
|
||||||
// HttpBaseChannel::nsIHttpChannel
|
// HttpBaseChannel::nsIHttpChannel
|
||||||
NS_IMETHOD SetRequestHeader(const nsACString& aHeader,
|
NS_IMETHOD SetRequestHeader(const nsACString& aHeader,
|
||||||
const nsACString& aValue,
|
const nsACString& aValue,
|
||||||
bool aMerge);
|
bool aMerge);
|
||||||
NS_IMETHOD RedirectTo(nsIURI *newURI);
|
NS_IMETHOD RedirectTo(nsIURI *newURI);
|
||||||
// nsIHttpChannelInternal
|
// nsIHttpChannelInternal
|
||||||
|
|
|
@ -107,7 +107,7 @@ HttpChannelParent::GetInterface(const nsIID& aIID, void **result)
|
||||||
// HttpChannelParent::PHttpChannelParent
|
// HttpChannelParent::PHttpChannelParent
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HttpChannelParent::RecvAsyncOpen(const URIParams& aURI,
|
HttpChannelParent::RecvAsyncOpen(const URIParams& aURI,
|
||||||
const OptionalURIParams& aOriginalURI,
|
const OptionalURIParams& aOriginalURI,
|
||||||
const OptionalURIParams& aDocURI,
|
const OptionalURIParams& aDocURI,
|
||||||
|
@ -142,7 +142,7 @@ HttpChannelParent::RecvAsyncOpen(const URIParams& aURI,
|
||||||
|
|
||||||
nsCString uriSpec;
|
nsCString uriSpec;
|
||||||
uri->GetSpec(uriSpec);
|
uri->GetSpec(uriSpec);
|
||||||
LOG(("HttpChannelParent RecvAsyncOpen [this=%x uri=%s]\n",
|
LOG(("HttpChannelParent RecvAsyncOpen [this=%x uri=%s]\n",
|
||||||
this, uriSpec.get()));
|
this, uriSpec.get()));
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
@ -256,7 +256,7 @@ HttpChannelParent::RecvConnectChannel(const uint32_t& channelId)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HttpChannelParent::RecvSetPriority(const uint16_t& priority)
|
HttpChannelParent::RecvSetPriority(const uint16_t& priority)
|
||||||
{
|
{
|
||||||
if (mChannel) {
|
if (mChannel) {
|
||||||
|
@ -322,7 +322,7 @@ HttpChannelParent::RecvUpdateAssociatedContentSecurity(const int32_t& broken,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HttpChannelParent::RecvRedirect2Verify(const nsresult& result,
|
HttpChannelParent::RecvRedirect2Verify(const nsresult& result,
|
||||||
const RequestHeaderTuples& changedHeaders,
|
const RequestHeaderTuples& changedHeaders,
|
||||||
const OptionalURIParams& aAPIRedirectURI)
|
const OptionalURIParams& aAPIRedirectURI)
|
||||||
{
|
{
|
||||||
|
@ -380,7 +380,7 @@ HttpChannelParent::RecvDocumentChannelCleanup()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HttpChannelParent::RecvMarkOfflineCacheEntryAsForeign()
|
HttpChannelParent::RecvMarkOfflineCacheEntryAsForeign()
|
||||||
{
|
{
|
||||||
if (mOfflineForeignMarker) {
|
if (mOfflineForeignMarker) {
|
||||||
|
@ -420,7 +420,7 @@ HttpChannelParent::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
|
||||||
nsCString appCacheClientId;
|
nsCString appCacheClientId;
|
||||||
appCache->GetGroupID(appCacheGroupId);
|
appCache->GetGroupID(appCacheGroupId);
|
||||||
appCache->GetClientID(appCacheClientId);
|
appCache->GetClientID(appCacheClientId);
|
||||||
if (mIPCClosed ||
|
if (mIPCClosed ||
|
||||||
!SendAssociateApplicationCache(appCacheGroupId, appCacheClientId))
|
!SendAssociateApplicationCache(appCacheGroupId, appCacheClientId))
|
||||||
{
|
{
|
||||||
return NS_ERROR_UNEXPECTED;
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
@ -446,30 +446,30 @@ HttpChannelParent::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsHttpChannel *httpChan = static_cast<nsHttpChannel *>(mChannel.get());
|
nsHttpChannel *httpChan = static_cast<nsHttpChannel *>(mChannel.get());
|
||||||
if (mIPCClosed ||
|
if (mIPCClosed ||
|
||||||
!SendOnStartRequest(responseHead ? *responseHead : nsHttpResponseHead(),
|
!SendOnStartRequest(responseHead ? *responseHead : nsHttpResponseHead(),
|
||||||
!!responseHead,
|
!!responseHead,
|
||||||
requestHead->Headers(),
|
requestHead->Headers(),
|
||||||
isFromCache,
|
isFromCache,
|
||||||
mCacheDescriptor ? true : false,
|
mCacheDescriptor ? true : false,
|
||||||
expirationTime, cachedCharset, secInfoSerialization,
|
expirationTime, cachedCharset, secInfoSerialization,
|
||||||
httpChan->GetSelfAddr(), httpChan->GetPeerAddr()))
|
httpChan->GetSelfAddr(), httpChan->GetPeerAddr()))
|
||||||
{
|
{
|
||||||
return NS_ERROR_UNEXPECTED;
|
return NS_ERROR_UNEXPECTED;
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelParent::OnStopRequest(nsIRequest *aRequest,
|
HttpChannelParent::OnStopRequest(nsIRequest *aRequest,
|
||||||
nsISupports *aContext,
|
nsISupports *aContext,
|
||||||
nsresult aStatusCode)
|
nsresult aStatusCode)
|
||||||
{
|
{
|
||||||
LOG(("HttpChannelParent::OnStopRequest: [this=%x status=%ul]\n",
|
LOG(("HttpChannelParent::OnStopRequest: [this=%x status=%ul]\n",
|
||||||
this, aStatusCode));
|
this, aStatusCode));
|
||||||
|
|
||||||
if (mIPCClosed || !SendOnStopRequest(aStatusCode))
|
if (mIPCClosed || !SendOnStopRequest(aStatusCode))
|
||||||
return NS_ERROR_UNEXPECTED;
|
return NS_ERROR_UNEXPECTED;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,10 +478,10 @@ HttpChannelParent::OnStopRequest(nsIRequest *aRequest,
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelParent::OnDataAvailable(nsIRequest *aRequest,
|
HttpChannelParent::OnDataAvailable(nsIRequest *aRequest,
|
||||||
nsISupports *aContext,
|
nsISupports *aContext,
|
||||||
nsIInputStream *aInputStream,
|
nsIInputStream *aInputStream,
|
||||||
uint64_t aOffset,
|
uint64_t aOffset,
|
||||||
uint32_t aCount)
|
uint32_t aCount)
|
||||||
{
|
{
|
||||||
LOG(("HttpChannelParent::OnDataAvailable [this=%x]\n", this));
|
LOG(("HttpChannelParent::OnDataAvailable [this=%x]\n", this));
|
||||||
|
@ -508,9 +508,9 @@ HttpChannelParent::OnDataAvailable(nsIRequest *aRequest,
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelParent::OnProgress(nsIRequest *aRequest,
|
HttpChannelParent::OnProgress(nsIRequest *aRequest,
|
||||||
nsISupports *aContext,
|
nsISupports *aContext,
|
||||||
uint64_t aProgress,
|
uint64_t aProgress,
|
||||||
uint64_t aProgressMax)
|
uint64_t aProgressMax)
|
||||||
{
|
{
|
||||||
// OnStatus has always just set mStoredStatus. If it indicates this precedes
|
// OnStatus has always just set mStoredStatus. If it indicates this precedes
|
||||||
|
@ -532,9 +532,9 @@ HttpChannelParent::OnProgress(nsIRequest *aRequest,
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelParent::OnStatus(nsIRequest *aRequest,
|
HttpChannelParent::OnStatus(nsIRequest *aRequest,
|
||||||
nsISupports *aContext,
|
nsISupports *aContext,
|
||||||
nsresult aStatus,
|
nsresult aStatus,
|
||||||
const PRUnichar *aStatusArg)
|
const PRUnichar *aStatusArg)
|
||||||
{
|
{
|
||||||
// If this precedes OnDataAvailable, store and ODA will send to child.
|
// If this precedes OnDataAvailable, store and ODA will send to child.
|
||||||
|
|
|
@ -42,7 +42,7 @@ HttpChannelParentListener::~HttpChannelParentListener()
|
||||||
// HttpChannelParentListener::nsISupports
|
// HttpChannelParentListener::nsISupports
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS5(HttpChannelParentListener,
|
NS_IMPL_ISUPPORTS5(HttpChannelParentListener,
|
||||||
nsIInterfaceRequestor,
|
nsIInterfaceRequestor,
|
||||||
nsIStreamListener,
|
nsIStreamListener,
|
||||||
nsIRequestObserver,
|
nsIRequestObserver,
|
||||||
|
@ -64,14 +64,14 @@ HttpChannelParentListener::OnStartRequest(nsIRequest *aRequest, nsISupports *aCo
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelParentListener::OnStopRequest(nsIRequest *aRequest,
|
HttpChannelParentListener::OnStopRequest(nsIRequest *aRequest,
|
||||||
nsISupports *aContext,
|
nsISupports *aContext,
|
||||||
nsresult aStatusCode)
|
nsresult aStatusCode)
|
||||||
{
|
{
|
||||||
if (!mActiveChannel)
|
if (!mActiveChannel)
|
||||||
return NS_ERROR_UNEXPECTED;
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
|
||||||
LOG(("HttpChannelParentListener::OnStopRequest: [this=%x status=%ul]\n",
|
LOG(("HttpChannelParentListener::OnStopRequest: [this=%x status=%ul]\n",
|
||||||
this, aStatusCode));
|
this, aStatusCode));
|
||||||
nsresult rv = mActiveChannel->OnStopRequest(aRequest, aContext, aStatusCode);
|
nsresult rv = mActiveChannel->OnStopRequest(aRequest, aContext, aStatusCode);
|
||||||
|
|
||||||
|
@ -84,10 +84,10 @@ HttpChannelParentListener::OnStopRequest(nsIRequest *aRequest,
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelParentListener::OnDataAvailable(nsIRequest *aRequest,
|
HttpChannelParentListener::OnDataAvailable(nsIRequest *aRequest,
|
||||||
nsISupports *aContext,
|
nsISupports *aContext,
|
||||||
nsIInputStream *aInputStream,
|
nsIInputStream *aInputStream,
|
||||||
uint64_t aOffset,
|
uint64_t aOffset,
|
||||||
uint32_t aCount)
|
uint32_t aCount)
|
||||||
{
|
{
|
||||||
if (!mActiveChannel)
|
if (!mActiveChannel)
|
||||||
|
@ -101,7 +101,7 @@ HttpChannelParentListener::OnDataAvailable(nsIRequest *aRequest,
|
||||||
// HttpChannelParentListener::nsIInterfaceRequestor
|
// HttpChannelParentListener::nsIInterfaceRequestor
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelParentListener::GetInterface(const nsIID& aIID, void **result)
|
HttpChannelParentListener::GetInterface(const nsIID& aIID, void **result)
|
||||||
{
|
{
|
||||||
if (aIID.Equals(NS_GET_IID(nsIChannelEventSink)) ||
|
if (aIID.Equals(NS_GET_IID(nsIChannelEventSink)) ||
|
||||||
|
|
|
@ -127,7 +127,7 @@ NullHttpTransaction::RequestHead()
|
||||||
// the NullHttpTransaction and let them be retried from the pending queue
|
// the NullHttpTransaction and let them be retried from the pending queue
|
||||||
// with a bound transcation
|
// with a bound transcation
|
||||||
}
|
}
|
||||||
|
|
||||||
return mRequestHead;
|
return mRequestHead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ NullHttpTransaction::SetPipelinePosition(int32_t position)
|
||||||
{
|
{
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
NullHttpTransaction::PipelinePosition()
|
NullHttpTransaction::PipelinePosition()
|
||||||
{
|
{
|
||||||
|
|
|
@ -76,20 +76,20 @@ parent:
|
||||||
|
|
||||||
// For document loads we keep this protocol open after child's
|
// For document loads we keep this protocol open after child's
|
||||||
// OnStopRequest, and send this msg (instead of __delete__) to allow
|
// OnStopRequest, and send this msg (instead of __delete__) to allow
|
||||||
// partial cleanup on parent.
|
// partial cleanup on parent.
|
||||||
DocumentChannelCleanup();
|
DocumentChannelCleanup();
|
||||||
|
|
||||||
// This might have to be sync. If this fails we must fail the document load
|
// This might have to be sync. If this fails we must fail the document load
|
||||||
// to avoid endless loop.
|
// to avoid endless loop.
|
||||||
//
|
//
|
||||||
// Explanation: the document loaded was loaded from the offline cache. But
|
// Explanation: the document loaded was loaded from the offline cache. But
|
||||||
// the cache group id (the manifest URL) of the cache group it was loaded
|
// the cache group id (the manifest URL) of the cache group it was loaded
|
||||||
// from is different then the manifest the document refers to in the html
|
// from is different then the manifest the document refers to in the html
|
||||||
// tag. If we detect this during the cache selection algorithm, we must not
|
// tag. If we detect this during the cache selection algorithm, we must not
|
||||||
// load this document from the offline cache group it was just loaded from.
|
// load this document from the offline cache group it was just loaded from.
|
||||||
// Marking the cache entry as foreign in its cache group will prevent
|
// Marking the cache entry as foreign in its cache group will prevent
|
||||||
// the document to load from the bad offline cache group. After it is marked,
|
// the document to load from the bad offline cache group. After it is marked,
|
||||||
// we reload the document to take the effect. If we fail to mark the entry
|
// we reload the document to take the effect. If we fail to mark the entry
|
||||||
// as foreign, we will end up in the same situation and reload again and
|
// as foreign, we will end up in the same situation and reload again and
|
||||||
// again, indefinitely.
|
// again, indefinitely.
|
||||||
MarkOfflineCacheEntryAsForeign();
|
MarkOfflineCacheEntryAsForeign();
|
||||||
|
|
|
@ -19,7 +19,7 @@ CLASS BREAKDOWN
|
||||||
- initiates http transactions
|
- initiates http transactions
|
||||||
- processes http response codes
|
- processes http response codes
|
||||||
- intercepts progress notifications
|
- intercepts progress notifications
|
||||||
|
|
||||||
nsHttpConnection
|
nsHttpConnection
|
||||||
- implements nsIStreamListener & nsIStreamProvider
|
- implements nsIStreamListener & nsIStreamProvider
|
||||||
- talks to the socket transport service
|
- talks to the socket transport service
|
||||||
|
@ -37,7 +37,7 @@ CLASS BREAKDOWN
|
||||||
nsHttpChunkedDecoder
|
nsHttpChunkedDecoder
|
||||||
- owned by a transaction
|
- owned by a transaction
|
||||||
- removes chunked decoding
|
- removes chunked decoding
|
||||||
|
|
||||||
nsHttpRequestHead
|
nsHttpRequestHead
|
||||||
- owns a nsHttpHeaderArray
|
- owns a nsHttpHeaderArray
|
||||||
- knows how to fill a request buffer
|
- knows how to fill a request buffer
|
||||||
|
@ -70,7 +70,7 @@ TRANSACTION MODEL
|
||||||
InitiateTransaction -> ActivateConnection -> AsyncWrite, AsyncRead
|
InitiateTransaction -> ActivateConnection -> AsyncWrite, AsyncRead
|
||||||
|
|
||||||
The channel creates transactions, and passes them to the handler via
|
The channel creates transactions, and passes them to the handler via
|
||||||
InitiateTransaction along with a nsHttpConnectionInfo object
|
InitiateTransaction along with a nsHttpConnectionInfo object
|
||||||
identifying the requested connection. The handler either dispatches
|
identifying the requested connection. The handler either dispatches
|
||||||
the transaction immediately or queues it up to be dispatched later,
|
the transaction immediately or queues it up to be dispatched later,
|
||||||
depending on whether or not the limit on the number of connections
|
depending on whether or not the limit on the number of connections
|
||||||
|
|
|
@ -67,7 +67,7 @@ SpdySession2::SpdySession2(nsAHttpTransaction *aHttpTransaction,
|
||||||
|
|
||||||
LOG3(("SpdySession2::SpdySession2 %p transaction 1 = %p",
|
LOG3(("SpdySession2::SpdySession2 %p transaction 1 = %p",
|
||||||
this, aHttpTransaction));
|
this, aHttpTransaction));
|
||||||
|
|
||||||
mStreamIDHash.Init();
|
mStreamIDHash.Init();
|
||||||
mStreamTransactionHash.Init();
|
mStreamTransactionHash.Init();
|
||||||
mConnection = aHttpTransaction->Connection();
|
mConnection = aHttpTransaction->Connection();
|
||||||
|
@ -75,12 +75,12 @@ SpdySession2::SpdySession2(nsAHttpTransaction *aHttpTransaction,
|
||||||
mDecompressBuffer = new char[mDecompressBufferSize];
|
mDecompressBuffer = new char[mDecompressBufferSize];
|
||||||
mOutputQueueBuffer = new char[mOutputQueueSize];
|
mOutputQueueBuffer = new char[mOutputQueueSize];
|
||||||
zlibInit();
|
zlibInit();
|
||||||
|
|
||||||
mSendingChunkSize = gHttpHandler->SpdySendingChunkSize();
|
mSendingChunkSize = gHttpHandler->SpdySendingChunkSize();
|
||||||
if (!aHttpTransaction->IsNullTransaction())
|
if (!aHttpTransaction->IsNullTransaction())
|
||||||
AddStream(aHttpTransaction, firstPriority);
|
AddStream(aHttpTransaction, firstPriority);
|
||||||
mLastDataReadEpoch = mLastReadEpoch;
|
mLastDataReadEpoch = mLastReadEpoch;
|
||||||
|
|
||||||
mPingThreshold = gHttpHandler->SpdyPingThreshold();
|
mPingThreshold = gHttpHandler->SpdyPingThreshold();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ SpdySession2::ShutdownEnumerator(nsAHttpTransaction *key,
|
||||||
void *closure)
|
void *closure)
|
||||||
{
|
{
|
||||||
SpdySession2 *self = static_cast<SpdySession2 *>(closure);
|
SpdySession2 *self = static_cast<SpdySession2 *>(closure);
|
||||||
|
|
||||||
// On a clean server hangup the server sets the GoAwayID to be the ID of
|
// On a clean server hangup the server sets the GoAwayID to be the ID of
|
||||||
// the last transaction it processed. If the ID of stream in the
|
// the last transaction it processed. If the ID of stream in the
|
||||||
// local stream is greater than that it can safely be restarted because the
|
// local stream is greater than that it can safely be restarted because the
|
||||||
|
@ -129,7 +129,7 @@ SpdySession2::~SpdySession2()
|
||||||
|
|
||||||
inflateEnd(&mDownstreamZlib);
|
inflateEnd(&mDownstreamZlib);
|
||||||
deflateEnd(&mUpstreamZlib);
|
deflateEnd(&mUpstreamZlib);
|
||||||
|
|
||||||
mStreamTransactionHash.Enumerate(ShutdownEnumerator, this);
|
mStreamTransactionHash.Enumerate(ShutdownEnumerator, this);
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_PARALLEL_STREAMS, mConcurrentHighWater);
|
Telemetry::Accumulate(Telemetry::SPDY_PARALLEL_STREAMS, mConcurrentHighWater);
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_REQUEST_PER_CONN, (mNextStreamID - 1) / 2);
|
Telemetry::Accumulate(Telemetry::SPDY_REQUEST_PER_CONN, (mNextStreamID - 1) / 2);
|
||||||
|
@ -143,7 +143,7 @@ SpdySession2::LogIO(SpdySession2 *self, SpdyStream2 *stream, const char *label,
|
||||||
{
|
{
|
||||||
if (!LOG4_ENABLED())
|
if (!LOG4_ENABLED())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LOG4(("SpdySession2::LogIO %p stream=%p id=0x%X [%s]",
|
LOG4(("SpdySession2::LogIO %p stream=%p id=0x%X [%s]",
|
||||||
self, stream, stream ? stream->StreamID() : 0, label));
|
self, stream, stream ? stream->StreamID() : 0, label));
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ SpdySession2::LogIO(SpdySession2 *self, SpdyStream2 *stream, const char *label,
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef nsresult (*Control_FX) (SpdySession2 *self);
|
typedef nsresult (*Control_FX) (SpdySession2 *self);
|
||||||
static Control_FX sControlFunctions[] =
|
static Control_FX sControlFunctions[] =
|
||||||
{
|
{
|
||||||
nullptr,
|
nullptr,
|
||||||
SpdySession2::HandleSynStream,
|
SpdySession2::HandleSynStream,
|
||||||
|
@ -241,7 +241,7 @@ SpdySession2::ReadTimeoutTick(PRIntervalTime now)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(("SpdySession2::ReadTimeoutTick %p generating ping 0x%x\n",
|
LOG(("SpdySession2::ReadTimeoutTick %p generating ping 0x%x\n",
|
||||||
this, mNextPingID));
|
this, mNextPingID));
|
||||||
|
|
||||||
|
@ -274,7 +274,7 @@ SpdySession2::RegisterStreamID(SpdyStream2 *stream)
|
||||||
"concurrent=%d",this, stream, mNextStreamID, mConcurrent));
|
"concurrent=%d",this, stream, mNextStreamID, mConcurrent));
|
||||||
|
|
||||||
MOZ_ASSERT(mNextStreamID < 0xfffffff0, "should have stopped admitting streams");
|
MOZ_ASSERT(mNextStreamID < 0xfffffff0, "should have stopped admitting streams");
|
||||||
|
|
||||||
uint32_t result = mNextStreamID;
|
uint32_t result = mNextStreamID;
|
||||||
mNextStreamID += 2;
|
mNextStreamID += 2;
|
||||||
|
|
||||||
|
@ -317,7 +317,7 @@ SpdySession2::AddStream(nsAHttpTransaction *aHttpTransaction,
|
||||||
&mUpstreamZlib,
|
&mUpstreamZlib,
|
||||||
aPriority);
|
aPriority);
|
||||||
|
|
||||||
|
|
||||||
LOG3(("SpdySession2::AddStream session=%p stream=%p NextID=0x%X (tentative)",
|
LOG3(("SpdySession2::AddStream session=%p stream=%p NextID=0x%X (tentative)",
|
||||||
this, stream, mNextStreamID));
|
this, stream, mNextStreamID));
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ SpdySession2::AddStream(nsAHttpTransaction *aHttpTransaction,
|
||||||
this, stream));
|
this, stream));
|
||||||
mQueuedStreams.Push(stream);
|
mQueuedStreams.Push(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,7 +415,7 @@ SpdySession2::FlushOutputQueue()
|
||||||
{
|
{
|
||||||
if (!mSegmentReader || !mOutputQueueUsed)
|
if (!mSegmentReader || !mOutputQueueUsed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
uint32_t countRead;
|
uint32_t countRead;
|
||||||
uint32_t avail = mOutputQueueUsed - mOutputQueueSent;
|
uint32_t avail = mOutputQueueUsed - mOutputQueueSent;
|
||||||
|
@ -425,11 +425,11 @@ SpdySession2::FlushOutputQueue()
|
||||||
&countRead);
|
&countRead);
|
||||||
LOG3(("SpdySession2::FlushOutputQueue %p sz=%d rv=%x actual=%d",
|
LOG3(("SpdySession2::FlushOutputQueue %p sz=%d rv=%x actual=%d",
|
||||||
this, avail, rv, countRead));
|
this, avail, rv, countRead));
|
||||||
|
|
||||||
// Dont worry about errors on write, we will pick this up as a read error too
|
// Dont worry about errors on write, we will pick this up as a read error too
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (countRead == avail) {
|
if (countRead == avail) {
|
||||||
mOutputQueueUsed = 0;
|
mOutputQueueUsed = 0;
|
||||||
mOutputQueueSent = 0;
|
mOutputQueueSent = 0;
|
||||||
|
@ -440,7 +440,7 @@ SpdySession2::FlushOutputQueue()
|
||||||
|
|
||||||
// If the output queue is close to filling up and we have sent out a good
|
// If the output queue is close to filling up and we have sent out a good
|
||||||
// chunk of data from the beginning then realign it.
|
// chunk of data from the beginning then realign it.
|
||||||
|
|
||||||
if ((mOutputQueueSent >= kQueueMinimumCleanup) &&
|
if ((mOutputQueueSent >= kQueueMinimumCleanup) &&
|
||||||
((mOutputQueueSize - mOutputQueueUsed) < kQueueTailRoom)) {
|
((mOutputQueueSize - mOutputQueueUsed) < kQueueTailRoom)) {
|
||||||
RealignOutputQueue();
|
RealignOutputQueue();
|
||||||
|
@ -501,13 +501,13 @@ SpdySession2::EnsureBuffer(nsAutoArrayPtr<char> &buf,
|
||||||
{
|
{
|
||||||
if (objSize >= newSize)
|
if (objSize >= newSize)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Leave a little slop on the new allocation - add 2KB to
|
// Leave a little slop on the new allocation - add 2KB to
|
||||||
// what we need and then round the result up to a 4KB (page)
|
// what we need and then round the result up to a 4KB (page)
|
||||||
// boundary.
|
// boundary.
|
||||||
|
|
||||||
objSize = (newSize + 2048 + 4095) & ~4095;
|
objSize = (newSize + 2048 + 4095) & ~4095;
|
||||||
|
|
||||||
nsAutoArrayPtr<char> tmp(new char[objSize]);
|
nsAutoArrayPtr<char> tmp(new char[objSize]);
|
||||||
memcpy(tmp, buf, preserve);
|
memcpy(tmp, buf, preserve);
|
||||||
buf = tmp;
|
buf = tmp;
|
||||||
|
@ -557,20 +557,20 @@ SpdySession2::DownstreamUncompress(char *blockStart, uint32_t blockLen)
|
||||||
LOG3(("SpdySession2::DownstreamUncompress %p Dictionary Error\n", this));
|
LOG3(("SpdySession2::DownstreamUncompress %p Dictionary Error\n", this));
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
triedDictionary = true;
|
triedDictionary = true;
|
||||||
inflateSetDictionary(&mDownstreamZlib,
|
inflateSetDictionary(&mDownstreamZlib,
|
||||||
reinterpret_cast<const unsigned char *>
|
reinterpret_cast<const unsigned char *>
|
||||||
(SpdyStream2::kDictionary),
|
(SpdyStream2::kDictionary),
|
||||||
strlen(SpdyStream2::kDictionary) + 1);
|
strlen(SpdyStream2::kDictionary) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zlib_rv == Z_DATA_ERROR || zlib_rv == Z_MEM_ERROR)
|
if (zlib_rv == Z_DATA_ERROR || zlib_rv == Z_MEM_ERROR)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
mDecompressBufferUsed += mDecompressBufferSize - mDecompressBufferUsed -
|
mDecompressBufferUsed += mDecompressBufferSize - mDecompressBufferUsed -
|
||||||
mDownstreamZlib.avail_out;
|
mDownstreamZlib.avail_out;
|
||||||
|
|
||||||
// When there is no more output room, but input still available then
|
// When there is no more output room, but input still available then
|
||||||
// increase the output space
|
// increase the output space
|
||||||
if (zlib_rv == Z_OK &&
|
if (zlib_rv == Z_OK &&
|
||||||
|
@ -635,7 +635,7 @@ SpdySession2::ConvertHeaders(nsDependentCSubstring &status,
|
||||||
|
|
||||||
// Content-Length is 'advisory'.. we will not strip it because it can
|
// Content-Length is 'advisory'.. we will not strip it because it can
|
||||||
// create UI feedback.
|
// create UI feedback.
|
||||||
|
|
||||||
mFlatHTTPResponseHeaders.Append(version);
|
mFlatHTTPResponseHeaders.Append(version);
|
||||||
mFlatHTTPResponseHeaders.Append(NS_LITERAL_CSTRING(" "));
|
mFlatHTTPResponseHeaders.Append(NS_LITERAL_CSTRING(" "));
|
||||||
mFlatHTTPResponseHeaders.Append(status);
|
mFlatHTTPResponseHeaders.Append(status);
|
||||||
|
@ -713,7 +713,7 @@ SpdySession2::ConvertHeaders(nsDependentCSubstring &status,
|
||||||
Substring(reinterpret_cast<const char *>(nvpair) + 4 + nameLen,
|
Substring(reinterpret_cast<const char *>(nvpair) + 4 + nameLen,
|
||||||
reinterpret_cast<const char *>(nvpair) + 4 + nameLen +
|
reinterpret_cast<const char *>(nvpair) + 4 + nameLen +
|
||||||
valueLen);
|
valueLen);
|
||||||
|
|
||||||
mFlatHTTPResponseHeaders.Append(nameString);
|
mFlatHTTPResponseHeaders.Append(nameString);
|
||||||
mFlatHTTPResponseHeaders.Append(NS_LITERAL_CSTRING(": "));
|
mFlatHTTPResponseHeaders.Append(NS_LITERAL_CSTRING(": "));
|
||||||
|
|
||||||
|
@ -741,7 +741,7 @@ SpdySession2::ConvertHeaders(nsDependentCSubstring &status,
|
||||||
NS_LITERAL_CSTRING("X-Firefox-Spdy: 2\r\n\r\n"));
|
NS_LITERAL_CSTRING("X-Firefox-Spdy: 2\r\n\r\n"));
|
||||||
LOG (("decoded response headers are:\n%s",
|
LOG (("decoded response headers are:\n%s",
|
||||||
mFlatHTTPResponseHeaders.get()));
|
mFlatHTTPResponseHeaders.get()));
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -764,7 +764,7 @@ SpdySession2::GeneratePing(uint32_t aID)
|
||||||
packet[5] = 0;
|
packet[5] = 0;
|
||||||
packet[6] = 0;
|
packet[6] = 0;
|
||||||
packet[7] = 4; /* length */
|
packet[7] = 4; /* length */
|
||||||
|
|
||||||
aID = PR_htonl(aID);
|
aID = PR_htonl(aID);
|
||||||
memcpy(packet + 8, &aID, 4);
|
memcpy(packet + 8, &aID, 4);
|
||||||
|
|
||||||
|
@ -790,7 +790,7 @@ SpdySession2::GenerateRstStream(uint32_t aStatusCode, uint32_t aID)
|
||||||
packet[5] = 0;
|
packet[5] = 0;
|
||||||
packet[6] = 0;
|
packet[6] = 0;
|
||||||
packet[7] = 8; /* length */
|
packet[7] = 8; /* length */
|
||||||
|
|
||||||
aID = PR_htonl(aID);
|
aID = PR_htonl(aID);
|
||||||
memcpy(packet + 8, &aID, 4);
|
memcpy(packet + 8, &aID, 4);
|
||||||
aStatusCode = PR_htonl(aStatusCode);
|
aStatusCode = PR_htonl(aStatusCode);
|
||||||
|
@ -815,7 +815,7 @@ SpdySession2::GenerateGoAway()
|
||||||
packet[1] = 2; /* version 2 */
|
packet[1] = 2; /* version 2 */
|
||||||
packet[3] = CONTROL_TYPE_GOAWAY;
|
packet[3] = CONTROL_TYPE_GOAWAY;
|
||||||
packet[7] = 4; /* data length */
|
packet[7] = 4; /* data length */
|
||||||
|
|
||||||
// last-good-stream-id are bytes 8-11, when we accept server push this will
|
// last-good-stream-id are bytes 8-11, when we accept server push this will
|
||||||
// need to be set non zero
|
// need to be set non zero
|
||||||
|
|
||||||
|
@ -839,21 +839,21 @@ SpdySession2::VerifyStream(SpdyStream2 *aStream, uint32_t aOptionalID = 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
uint32_t test = 0;
|
uint32_t test = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (aStream->StreamID() == kDeadStreamID)
|
if (aStream->StreamID() == kDeadStreamID)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
nsAHttpTransaction *trans = aStream->Transaction();
|
nsAHttpTransaction *trans = aStream->Transaction();
|
||||||
|
|
||||||
test++;
|
test++;
|
||||||
if (!trans)
|
if (!trans)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
test++;
|
test++;
|
||||||
if (mStreamTransactionHash.Get(trans) != aStream)
|
if (mStreamTransactionHash.Get(trans) != aStream)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (aStream->StreamID()) {
|
if (aStream->StreamID()) {
|
||||||
SpdyStream2 *idStream = mStreamIDHash.Get(aStream->StreamID());
|
SpdyStream2 *idStream = mStreamIDHash.Get(aStream->StreamID());
|
||||||
|
|
||||||
|
@ -900,7 +900,7 @@ SpdySession2::CleanupStream(SpdyStream2 *aStream, nsresult aResult,
|
||||||
--mConcurrent;
|
--mConcurrent;
|
||||||
ProcessPending();
|
ProcessPending();
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseStream(aStream, aResult);
|
CloseStream(aStream, aResult);
|
||||||
|
|
||||||
// Remove the stream from the ID hash table. (this one isn't short, which is
|
// Remove the stream from the ID hash table. (this one isn't short, which is
|
||||||
|
@ -965,7 +965,7 @@ nsresult
|
||||||
SpdySession2::HandleSynStream(SpdySession2 *self)
|
SpdySession2::HandleSynStream(SpdySession2 *self)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(self->mFrameControlType == CONTROL_TYPE_SYN_STREAM);
|
MOZ_ASSERT(self->mFrameControlType == CONTROL_TYPE_SYN_STREAM);
|
||||||
|
|
||||||
if (self->mInputFrameDataSize < 18) {
|
if (self->mInputFrameDataSize < 18) {
|
||||||
LOG3(("SpdySession2::HandleSynStream %p SYN_STREAM too short data=%d",
|
LOG3(("SpdySession2::HandleSynStream %p SYN_STREAM too short data=%d",
|
||||||
self, self->mInputFrameDataSize));
|
self, self->mInputFrameDataSize));
|
||||||
|
@ -980,7 +980,7 @@ SpdySession2::HandleSynStream(SpdySession2 *self)
|
||||||
LOG3(("SpdySession2::HandleSynStream %p recv SYN_STREAM (push) "
|
LOG3(("SpdySession2::HandleSynStream %p recv SYN_STREAM (push) "
|
||||||
"for ID 0x%X associated with 0x%X.",
|
"for ID 0x%X associated with 0x%X.",
|
||||||
self, streamID, associatedID));
|
self, streamID, associatedID));
|
||||||
|
|
||||||
if (streamID & 0x01) { // test for odd stream ID
|
if (streamID & 0x01) { // test for odd stream ID
|
||||||
LOG3(("SpdySession2::HandleSynStream %p recvd SYN_STREAM id must be even.",
|
LOG3(("SpdySession2::HandleSynStream %p recvd SYN_STREAM id must be even.",
|
||||||
self));
|
self));
|
||||||
|
@ -1033,7 +1033,7 @@ SpdySession2::HandleSynReply(SpdySession2 *self)
|
||||||
// A framing error is a session wide error that cannot be recovered
|
// A framing error is a session wide error that cannot be recovered
|
||||||
return NS_ERROR_ILLEGAL_VALUE;
|
return NS_ERROR_ILLEGAL_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uncompress the headers into mDecompressBuffer, leaving them in
|
// Uncompress the headers into mDecompressBuffer, leaving them in
|
||||||
// spdy format for the time being. Make certain to do this
|
// spdy format for the time being. Make certain to do this
|
||||||
// step before any error handling that might abort the stream but not
|
// step before any error handling that might abort the stream but not
|
||||||
|
@ -1104,7 +1104,7 @@ SpdySession2::HandleSynReplyForValidStream()
|
||||||
LOG3(("SpdySession2::HandleSynReplyForValidStream %p SYN_REPLY for 0x%X "
|
LOG3(("SpdySession2::HandleSynReplyForValidStream %p SYN_REPLY for 0x%X "
|
||||||
"fin=%d",
|
"fin=%d",
|
||||||
this, mInputFrameDataStream->StreamID(), mInputFrameDataLast));
|
this, mInputFrameDataStream->StreamID(), mInputFrameDataLast));
|
||||||
|
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SYN_REPLY_SIZE,
|
Telemetry::Accumulate(Telemetry::SPDY_SYN_REPLY_SIZE,
|
||||||
mInputFrameDataSize - 6);
|
mInputFrameDataSize - 6);
|
||||||
if (mDecompressBufferUsed) {
|
if (mDecompressBufferUsed) {
|
||||||
|
@ -1165,7 +1165,7 @@ SpdySession2::HandleRstStream(SpdySession2 *self)
|
||||||
self));
|
self));
|
||||||
return NS_ERROR_ILLEGAL_VALUE;
|
return NS_ERROR_ILLEGAL_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->mDownstreamRstReason == RST_INVALID_STREAM ||
|
if (self->mDownstreamRstReason == RST_INVALID_STREAM ||
|
||||||
self->mDownstreamRstReason == RST_FLOW_CONTROL_ERROR) {
|
self->mDownstreamRstReason == RST_FLOW_CONTROL_ERROR) {
|
||||||
// basically just ignore this
|
// basically just ignore this
|
||||||
|
@ -1174,7 +1174,7 @@ SpdySession2::HandleRstStream(SpdySession2 *self)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv = self->SetInputFrameDataStream(streamID);
|
nsresult rv = self->SetInputFrameDataStream(streamID);
|
||||||
|
|
||||||
if (!self->mInputFrameDataStream) {
|
if (!self->mInputFrameDataStream) {
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
LOG(("SpdySession2::HandleRstStream %p lookup streamID for RST Frame "
|
LOG(("SpdySession2::HandleRstStream %p lookup streamID for RST Frame "
|
||||||
|
@ -1223,7 +1223,7 @@ SpdySession2::HandleSettings(SpdySession2 *self)
|
||||||
// Each entry is a 24 bits of a little endian id
|
// Each entry is a 24 bits of a little endian id
|
||||||
// followed by 8 bits of flags
|
// followed by 8 bits of flags
|
||||||
// followed by a 32 bit big endian value
|
// followed by a 32 bit big endian value
|
||||||
|
|
||||||
unsigned char *setting = reinterpret_cast<unsigned char *>
|
unsigned char *setting = reinterpret_cast<unsigned char *>
|
||||||
(self->mInputFrameBuffer.get()) + 12 + index * 8;
|
(self->mInputFrameBuffer.get()) + 12 + index * 8;
|
||||||
|
|
||||||
|
@ -1238,38 +1238,38 @@ SpdySession2::HandleSettings(SpdySession2 *self)
|
||||||
case SETTINGS_TYPE_UPLOAD_BW:
|
case SETTINGS_TYPE_UPLOAD_BW:
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_UL_BW, value);
|
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_UL_BW, value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETTINGS_TYPE_DOWNLOAD_BW:
|
case SETTINGS_TYPE_DOWNLOAD_BW:
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_DL_BW, value);
|
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_DL_BW, value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETTINGS_TYPE_RTT:
|
case SETTINGS_TYPE_RTT:
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_RTT, value);
|
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_RTT, value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETTINGS_TYPE_MAX_CONCURRENT:
|
case SETTINGS_TYPE_MAX_CONCURRENT:
|
||||||
self->mMaxConcurrent = value;
|
self->mMaxConcurrent = value;
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_MAX_STREAMS, value);
|
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_MAX_STREAMS, value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETTINGS_TYPE_CWND:
|
case SETTINGS_TYPE_CWND:
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_CWND, value);
|
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_CWND, value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETTINGS_TYPE_DOWNLOAD_RETRANS_RATE:
|
case SETTINGS_TYPE_DOWNLOAD_RETRANS_RATE:
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_RETRANS, value);
|
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_RETRANS, value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETTINGS_TYPE_INITIAL_WINDOW:
|
case SETTINGS_TYPE_INITIAL_WINDOW:
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_IW, value >> 10);
|
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_IW, value >> 10);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self->ResetDownstreamState();
|
self->ResetDownstreamState();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -1315,7 +1315,7 @@ SpdySession2::HandlePing(SpdySession2 *self)
|
||||||
// Servers initiate even numbered pings, go ahead and echo it back
|
// Servers initiate even numbered pings, go ahead and echo it back
|
||||||
self->GeneratePing(pingID);
|
self->GeneratePing(pingID);
|
||||||
}
|
}
|
||||||
|
|
||||||
self->ResetDownstreamState();
|
self->ResetDownstreamState();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -1336,7 +1336,7 @@ SpdySession2::HandleGoAway(SpdySession2 *self)
|
||||||
PR_ntohl(reinterpret_cast<uint32_t *>(self->mInputFrameBuffer.get())[2]);
|
PR_ntohl(reinterpret_cast<uint32_t *>(self->mInputFrameBuffer.get())[2]);
|
||||||
self->mCleanShutdown = true;
|
self->mCleanShutdown = true;
|
||||||
|
|
||||||
// Find streams greater than the last-good ID and mark them for deletion
|
// Find streams greater than the last-good ID and mark them for deletion
|
||||||
// in the mGoAwayStreamsToRestart queue with the GoAwayEnumerator. They can
|
// in the mGoAwayStreamsToRestart queue with the GoAwayEnumerator. They can
|
||||||
// be restarted.
|
// be restarted.
|
||||||
self->mStreamTransactionHash.Enumerate(GoAwayEnumerator, self);
|
self->mStreamTransactionHash.Enumerate(GoAwayEnumerator, self);
|
||||||
|
@ -1479,7 +1479,7 @@ SpdySession2::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
uint32_t *countRead)
|
uint32_t *countRead)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
|
|
||||||
MOZ_ASSERT(!mSegmentReader || !reader || (mSegmentReader == reader),
|
MOZ_ASSERT(!mSegmentReader || !reader || (mSegmentReader == reader),
|
||||||
"Inconsistent Write Function Callback");
|
"Inconsistent Write Function Callback");
|
||||||
|
|
||||||
|
@ -1498,7 +1498,7 @@ SpdySession2::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
LOG3(("SpdySession2::ReadSegments %p", this));
|
LOG3(("SpdySession2::ReadSegments %p", this));
|
||||||
|
|
||||||
SpdyStream2 *stream;
|
SpdyStream2 *stream;
|
||||||
|
|
||||||
stream = static_cast<SpdyStream2 *>(mUrgentForWrite.PopFront());
|
stream = static_cast<SpdyStream2 *>(mUrgentForWrite.PopFront());
|
||||||
if (!stream)
|
if (!stream)
|
||||||
stream = static_cast<SpdyStream2 *>(mReadyForWrite.PopFront());
|
stream = static_cast<SpdyStream2 *>(mReadyForWrite.PopFront());
|
||||||
|
@ -1509,7 +1509,7 @@ SpdySession2::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
SetWriteCallbacks();
|
SetWriteCallbacks();
|
||||||
return NS_BASE_STREAM_WOULD_BLOCK;
|
return NS_BASE_STREAM_WOULD_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG3(("SpdySession2 %p will write from SpdyStream2 %p", this, stream));
|
LOG3(("SpdySession2 %p will write from SpdyStream2 %p", this, stream));
|
||||||
|
|
||||||
rv = stream->ReadSegments(this, count, countRead);
|
rv = stream->ReadSegments(this, count, countRead);
|
||||||
|
@ -1521,11 +1521,11 @@ SpdySession2::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
FlushOutputQueue();
|
FlushOutputQueue();
|
||||||
|
|
||||||
if (stream->RequestBlockedOnRead()) {
|
if (stream->RequestBlockedOnRead()) {
|
||||||
|
|
||||||
// We are blocked waiting for input - either more http headers or
|
// We are blocked waiting for input - either more http headers or
|
||||||
// any request body data. When more data from the request stream
|
// any request body data. When more data from the request stream
|
||||||
// becomes available the httptransaction will call conn->ResumeSend().
|
// becomes available the httptransaction will call conn->ResumeSend().
|
||||||
|
|
||||||
LOG3(("SpdySession2::ReadSegments %p dealing with block on read", this));
|
LOG3(("SpdySession2::ReadSegments %p dealing with block on read", this));
|
||||||
|
|
||||||
// call readsegments again if there are other streams ready
|
// call readsegments again if there are other streams ready
|
||||||
|
@ -1537,7 +1537,7 @@ SpdySession2::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
SetWriteCallbacks();
|
SetWriteCallbacks();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
LOG3(("SpdySession2::ReadSegments %p returning FAIL code %X",
|
LOG3(("SpdySession2::ReadSegments %p returning FAIL code %X",
|
||||||
this, rv));
|
this, rv));
|
||||||
|
@ -1545,7 +1545,7 @@ SpdySession2::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
CleanupStream(stream, rv, RST_CANCEL);
|
CleanupStream(stream, rv, RST_CANCEL);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*countRead > 0) {
|
if (*countRead > 0) {
|
||||||
LOG3(("SpdySession2::ReadSegments %p stream=%p generated end of frame %d",
|
LOG3(("SpdySession2::ReadSegments %p stream=%p generated end of frame %d",
|
||||||
this, stream, *countRead));
|
this, stream, *countRead));
|
||||||
|
@ -1553,10 +1553,10 @@ SpdySession2::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
SetWriteCallbacks();
|
SetWriteCallbacks();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG3(("SpdySession2::ReadSegments %p stream=%p stream send complete",
|
LOG3(("SpdySession2::ReadSegments %p stream=%p stream send complete",
|
||||||
this, stream));
|
this, stream));
|
||||||
|
|
||||||
/* we now want to recv data */
|
/* we now want to recv data */
|
||||||
ResumeRecv();
|
ResumeRecv();
|
||||||
|
|
||||||
|
@ -1574,7 +1574,7 @@ SpdySession2::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
// OnWriteSegment(). That function will gateway it into http and feed
|
// OnWriteSegment(). That function will gateway it into http and feed
|
||||||
// it to the appropriate transaction.
|
// it to the appropriate transaction.
|
||||||
|
|
||||||
// we call writer->OnWriteSegment via NetworkRead() to get a spdy header..
|
// we call writer->OnWriteSegment via NetworkRead() to get a spdy header..
|
||||||
// and decide if it is data or control.. if it is control, just deal with it.
|
// and decide if it is data or control.. if it is control, just deal with it.
|
||||||
// if it is data, identify the spdy stream
|
// if it is data, identify the spdy stream
|
||||||
// call stream->WriteSegemnts which can call this::OnWriteSegment to get the
|
// call stream->WriteSegemnts which can call this::OnWriteSegment to get the
|
||||||
|
@ -1586,7 +1586,7 @@ SpdySession2::WriteSegments(nsAHttpSegmentWriter *writer,
|
||||||
uint32_t *countWritten)
|
uint32_t *countWritten)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
*countWritten = 0;
|
*countWritten = 0;
|
||||||
|
|
||||||
|
@ -1594,16 +1594,16 @@ SpdySession2::WriteSegments(nsAHttpSegmentWriter *writer,
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
SetWriteCallbacks();
|
SetWriteCallbacks();
|
||||||
|
|
||||||
// We buffer all control frames and act on them in this layer.
|
// We buffer all control frames and act on them in this layer.
|
||||||
// We buffer the first 8 bytes of data frames (the header) but
|
// We buffer the first 8 bytes of data frames (the header) but
|
||||||
// the actual data is passed through unprocessed.
|
// the actual data is passed through unprocessed.
|
||||||
|
|
||||||
if (mDownstreamState == BUFFERING_FRAME_HEADER) {
|
if (mDownstreamState == BUFFERING_FRAME_HEADER) {
|
||||||
// The first 8 bytes of every frame is header information that
|
// The first 8 bytes of every frame is header information that
|
||||||
// we are going to want to strip before passing to http. That is
|
// we are going to want to strip before passing to http. That is
|
||||||
// true of both control and data packets.
|
// true of both control and data packets.
|
||||||
|
|
||||||
MOZ_ASSERT(mInputFrameBufferUsed < 8,
|
MOZ_ASSERT(mInputFrameBufferUsed < 8,
|
||||||
"Frame Buffer Used Too Large for State");
|
"Frame Buffer Used Too Large for State");
|
||||||
|
|
||||||
|
@ -1638,21 +1638,21 @@ SpdySession2::WriteSegments(nsAHttpSegmentWriter *writer,
|
||||||
PR_ntohl(reinterpret_cast<uint32_t *>(mInputFrameBuffer.get())[1]);
|
PR_ntohl(reinterpret_cast<uint32_t *>(mInputFrameBuffer.get())[1]);
|
||||||
mInputFrameDataSize &= 0x00ffffff;
|
mInputFrameDataSize &= 0x00ffffff;
|
||||||
mInputFrameDataRead = 0;
|
mInputFrameDataRead = 0;
|
||||||
|
|
||||||
if (mInputFrameBuffer[0] & kFlag_Control) {
|
if (mInputFrameBuffer[0] & kFlag_Control) {
|
||||||
EnsureBuffer(mInputFrameBuffer, mInputFrameDataSize + 8, 8,
|
EnsureBuffer(mInputFrameBuffer, mInputFrameDataSize + 8, 8,
|
||||||
mInputFrameBufferSize);
|
mInputFrameBufferSize);
|
||||||
ChangeDownstreamState(BUFFERING_CONTROL_FRAME);
|
ChangeDownstreamState(BUFFERING_CONTROL_FRAME);
|
||||||
|
|
||||||
// The first 32 bit word of the header is
|
// The first 32 bit word of the header is
|
||||||
// 1 ctrl - 15 version - 16 type
|
// 1 ctrl - 15 version - 16 type
|
||||||
uint16_t version =
|
uint16_t version =
|
||||||
PR_ntohs(reinterpret_cast<uint16_t *>(mInputFrameBuffer.get())[0]);
|
PR_ntohs(reinterpret_cast<uint16_t *>(mInputFrameBuffer.get())[0]);
|
||||||
version &= 0x7fff;
|
version &= 0x7fff;
|
||||||
|
|
||||||
mFrameControlType =
|
mFrameControlType =
|
||||||
PR_ntohs(reinterpret_cast<uint16_t *>(mInputFrameBuffer.get())[1]);
|
PR_ntohs(reinterpret_cast<uint16_t *>(mInputFrameBuffer.get())[1]);
|
||||||
|
|
||||||
LOG3(("SpdySession2::WriteSegments %p - Control Frame Identified "
|
LOG3(("SpdySession2::WriteSegments %p - Control Frame Identified "
|
||||||
"type %d version %d data len %d",
|
"type %d version %d data len %d",
|
||||||
this, mFrameControlType, version, mInputFrameDataSize));
|
this, mFrameControlType, version, mInputFrameDataSize));
|
||||||
|
@ -1757,7 +1757,7 @@ SpdySession2::WriteSegments(nsAHttpSegmentWriter *writer,
|
||||||
mNeedsCleanup = nullptr; /* just in case */
|
mNeedsCleanup = nullptr; /* just in case */
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mNeedsCleanup) {
|
if (mNeedsCleanup) {
|
||||||
LOG3(("SpdySession2::WriteSegments session=%p stream=%p 0x%X "
|
LOG3(("SpdySession2::WriteSegments session=%p stream=%p 0x%X "
|
||||||
"cleanup stream based on mNeedsCleanup.\n",
|
"cleanup stream based on mNeedsCleanup.\n",
|
||||||
|
@ -1799,7 +1799,7 @@ SpdySession2::WriteSegments(nsAHttpSegmentWriter *writer,
|
||||||
ResetDownstreamState();
|
ResetDownstreamState();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDownstreamState != BUFFERING_CONTROL_FRAME) {
|
if (mDownstreamState != BUFFERING_CONTROL_FRAME) {
|
||||||
// this cannot happen
|
// this cannot happen
|
||||||
MOZ_ASSERT(false, "Not in Bufering Control Frame State");
|
MOZ_ASSERT(false, "Not in Bufering Control Frame State");
|
||||||
|
@ -1833,7 +1833,7 @@ SpdySession2::WriteSegments(nsAHttpSegmentWriter *writer,
|
||||||
// checked to make sure it was in range, but we will check it again
|
// checked to make sure it was in range, but we will check it again
|
||||||
// at time of use to make sure a regression doesn't creep in.
|
// at time of use to make sure a regression doesn't creep in.
|
||||||
if (mFrameControlType >= CONTROL_TYPE_LAST ||
|
if (mFrameControlType >= CONTROL_TYPE_LAST ||
|
||||||
mFrameControlType <= CONTROL_TYPE_FIRST)
|
mFrameControlType <= CONTROL_TYPE_FIRST)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(false, "control type out of range");
|
MOZ_ASSERT(false, "control type out of range");
|
||||||
return NS_ERROR_ILLEGAL_VALUE;
|
return NS_ERROR_ILLEGAL_VALUE;
|
||||||
|
@ -1906,9 +1906,9 @@ SpdySession2::OnReadSegment(const char *buf,
|
||||||
uint32_t *countRead)
|
uint32_t *countRead)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
// If we can release old queued data then we can try and write the new
|
// If we can release old queued data then we can try and write the new
|
||||||
// data directly to the network without using the output queue at all
|
// data directly to the network without using the output queue at all
|
||||||
if (mOutputQueueUsed)
|
if (mOutputQueueUsed)
|
||||||
|
@ -1922,7 +1922,7 @@ SpdySession2::OnReadSegment(const char *buf,
|
||||||
*countRead = 0;
|
*countRead = 0;
|
||||||
else if (NS_FAILED(rv))
|
else if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
if (*countRead < count) {
|
if (*countRead < count) {
|
||||||
uint32_t required = count - *countRead;
|
uint32_t required = count - *countRead;
|
||||||
// assuming a commitment() happened, this ensurebuffer is a nop
|
// assuming a commitment() happened, this ensurebuffer is a nop
|
||||||
|
@ -1932,7 +1932,7 @@ SpdySession2::OnReadSegment(const char *buf,
|
||||||
memcpy(mOutputQueueBuffer.get(), buf + *countRead, required);
|
memcpy(mOutputQueueBuffer.get(), buf + *countRead, required);
|
||||||
mOutputQueueUsed = required;
|
mOutputQueueUsed = required;
|
||||||
}
|
}
|
||||||
|
|
||||||
*countRead = count;
|
*countRead = count;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -1948,7 +1948,7 @@ SpdySession2::OnReadSegment(const char *buf,
|
||||||
|
|
||||||
if ((mOutputQueueUsed + count) > (mOutputQueueSize - kQueueReserved))
|
if ((mOutputQueueUsed + count) > (mOutputQueueSize - kQueueReserved))
|
||||||
return NS_BASE_STREAM_WOULD_BLOCK;
|
return NS_BASE_STREAM_WOULD_BLOCK;
|
||||||
|
|
||||||
memcpy(mOutputQueueBuffer.get() + mOutputQueueUsed, buf, count);
|
memcpy(mOutputQueueBuffer.get() + mOutputQueueUsed, buf, count);
|
||||||
mOutputQueueUsed += count;
|
mOutputQueueUsed += count;
|
||||||
*countRead = count;
|
*countRead = count;
|
||||||
|
@ -2010,7 +2010,7 @@ SpdySession2::OnWriteSegment(char *buf,
|
||||||
// stack with WriteSegments()
|
// stack with WriteSegments()
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDownstreamState == PROCESSING_DATA_FRAME) {
|
if (mDownstreamState == PROCESSING_DATA_FRAME) {
|
||||||
|
|
||||||
if (mInputFrameDataLast &&
|
if (mInputFrameDataLast &&
|
||||||
|
@ -2019,7 +2019,7 @@ SpdySession2::OnWriteSegment(char *buf,
|
||||||
SetNeedsCleanup();
|
SetNeedsCleanup();
|
||||||
return NS_BASE_STREAM_CLOSED;
|
return NS_BASE_STREAM_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = std::min(count, mInputFrameDataSize - mInputFrameDataRead);
|
count = std::min(count, mInputFrameDataSize - mInputFrameDataRead);
|
||||||
rv = NetworkRead(mSegmentWriter, buf, count, countWritten);
|
rv = NetworkRead(mSegmentWriter, buf, count, countWritten);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
|
@ -2029,23 +2029,23 @@ SpdySession2::OnWriteSegment(char *buf,
|
||||||
buf, *countWritten);
|
buf, *countWritten);
|
||||||
|
|
||||||
mInputFrameDataRead += *countWritten;
|
mInputFrameDataRead += *countWritten;
|
||||||
|
|
||||||
mInputFrameDataStream->UpdateTransportReadEvents(*countWritten);
|
mInputFrameDataStream->UpdateTransportReadEvents(*countWritten);
|
||||||
if ((mInputFrameDataRead == mInputFrameDataSize) && !mInputFrameDataLast)
|
if ((mInputFrameDataRead == mInputFrameDataSize) && !mInputFrameDataLast)
|
||||||
ResetDownstreamState();
|
ResetDownstreamState();
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDownstreamState == PROCESSING_CONTROL_SYN_REPLY) {
|
if (mDownstreamState == PROCESSING_CONTROL_SYN_REPLY) {
|
||||||
|
|
||||||
if (mFlatHTTPResponseHeaders.Length() == mFlatHTTPResponseHeadersOut &&
|
if (mFlatHTTPResponseHeaders.Length() == mFlatHTTPResponseHeadersOut &&
|
||||||
mInputFrameDataLast) {
|
mInputFrameDataLast) {
|
||||||
*countWritten = 0;
|
*countWritten = 0;
|
||||||
SetNeedsCleanup();
|
SetNeedsCleanup();
|
||||||
return NS_BASE_STREAM_CLOSED;
|
return NS_BASE_STREAM_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = std::min(count,
|
count = std::min(count,
|
||||||
mFlatHTTPResponseHeaders.Length() -
|
mFlatHTTPResponseHeaders.Length() -
|
||||||
mFlatHTTPResponseHeadersOut);
|
mFlatHTTPResponseHeadersOut);
|
||||||
|
@ -2096,7 +2096,7 @@ SpdySession2::TransactionHasDataToWrite(nsAHttpTransaction *caller)
|
||||||
this, caller));
|
this, caller));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG3(("SpdySession2::TransactionHasDataToWrite %p ID is %x",
|
LOG3(("SpdySession2::TransactionHasDataToWrite %p ID is %x",
|
||||||
this, stream->StreamID()));
|
this, stream->StreamID()));
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ public:
|
||||||
|
|
||||||
// When the connection is active this is called every 1 second
|
// When the connection is active this is called every 1 second
|
||||||
void ReadTimeoutTick(PRIntervalTime now);
|
void ReadTimeoutTick(PRIntervalTime now);
|
||||||
|
|
||||||
// Idle time represents time since "goodput".. e.g. a data or header frame
|
// Idle time represents time since "goodput".. e.g. a data or header frame
|
||||||
PRIntervalTime IdleTime();
|
PRIntervalTime IdleTime();
|
||||||
|
|
||||||
|
@ -57,10 +57,10 @@ public:
|
||||||
const static uint8_t kFlag_Data_FIN = 0x01;
|
const static uint8_t kFlag_Data_FIN = 0x01;
|
||||||
const static uint8_t kFlag_Data_UNI = 0x02;
|
const static uint8_t kFlag_Data_UNI = 0x02;
|
||||||
const static uint8_t kFlag_Data_ZLIB = 0x02;
|
const static uint8_t kFlag_Data_ZLIB = 0x02;
|
||||||
|
|
||||||
// The protocol document for v2 specifies that the
|
// The protocol document for v2 specifies that the
|
||||||
// highest value (3) is the highest priority, but in
|
// highest value (3) is the highest priority, but in
|
||||||
// reality 0 is the highest priority.
|
// reality 0 is the highest priority.
|
||||||
//
|
//
|
||||||
// Draft 3 notes here https://sites.google.com/a/chromium.org/dev/spdy/spdy-protocol/
|
// Draft 3 notes here https://sites.google.com/a/chromium.org/dev/spdy/spdy-protocol/
|
||||||
// are the best guide to the mistake. Also see
|
// are the best guide to the mistake. Also see
|
||||||
|
@ -124,11 +124,11 @@ public:
|
||||||
|
|
||||||
const static uint32_t kDefaultMaxConcurrent = 100;
|
const static uint32_t kDefaultMaxConcurrent = 100;
|
||||||
const static uint32_t kMaxStreamID = 0x7800000;
|
const static uint32_t kMaxStreamID = 0x7800000;
|
||||||
|
|
||||||
// This is a sentinel for a deleted stream. It is not a valid
|
// This is a sentinel for a deleted stream. It is not a valid
|
||||||
// 31 bit stream ID.
|
// 31 bit stream ID.
|
||||||
const static uint32_t kDeadStreamID = 0xffffdead;
|
const static uint32_t kDeadStreamID = 0xffffdead;
|
||||||
|
|
||||||
static nsresult HandleSynStream(SpdySession2 *);
|
static nsresult HandleSynStream(SpdySession2 *);
|
||||||
static nsresult HandleSynReply(SpdySession2 *);
|
static nsresult HandleSynReply(SpdySession2 *);
|
||||||
static nsresult HandleRstStream(SpdySession2 *);
|
static nsresult HandleRstStream(SpdySession2 *);
|
||||||
|
@ -154,7 +154,7 @@ public:
|
||||||
|
|
||||||
// an overload of nsAHttpSegementReader
|
// an overload of nsAHttpSegementReader
|
||||||
virtual nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment);
|
virtual nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment);
|
||||||
|
|
||||||
void PrintDiagnostics (nsCString &log);
|
void PrintDiagnostics (nsCString &log);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -197,7 +197,7 @@ private:
|
||||||
// a wrapper for all calls to the nshttpconnection level segment writer. Used
|
// a wrapper for all calls to the nshttpconnection level segment writer. Used
|
||||||
// to track network I/O for timeout purposes
|
// to track network I/O for timeout purposes
|
||||||
nsresult NetworkRead(nsAHttpSegmentWriter *, char *, uint32_t, uint32_t *);
|
nsresult NetworkRead(nsAHttpSegmentWriter *, char *, uint32_t, uint32_t *);
|
||||||
|
|
||||||
static PLDHashOperator ShutdownEnumerator(nsAHttpTransaction *,
|
static PLDHashOperator ShutdownEnumerator(nsAHttpTransaction *,
|
||||||
nsAutoPtr<SpdyStream2> &,
|
nsAutoPtr<SpdyStream2> &,
|
||||||
void *);
|
void *);
|
||||||
|
@ -256,7 +256,7 @@ private:
|
||||||
uint32_t mInputFrameBufferSize;
|
uint32_t mInputFrameBufferSize;
|
||||||
uint32_t mInputFrameBufferUsed;
|
uint32_t mInputFrameBufferUsed;
|
||||||
nsAutoArrayPtr<char> mInputFrameBuffer;
|
nsAutoArrayPtr<char> mInputFrameBuffer;
|
||||||
|
|
||||||
// mInputFrameDataSize/Read are used for tracking the amount of data consumed
|
// mInputFrameDataSize/Read are used for tracking the amount of data consumed
|
||||||
// in a data frame. the data itself is not buffered in spdy
|
// in a data frame. the data itself is not buffered in spdy
|
||||||
// The frame size is mInputFrameDataSize + the constant 8 byte header
|
// The frame size is mInputFrameDataSize + the constant 8 byte header
|
||||||
|
@ -268,7 +268,7 @@ private:
|
||||||
// (e.g. a data frame after the stream-id has been decoded), this points
|
// (e.g. a data frame after the stream-id has been decoded), this points
|
||||||
// to the stream.
|
// to the stream.
|
||||||
SpdyStream2 *mInputFrameDataStream;
|
SpdyStream2 *mInputFrameDataStream;
|
||||||
|
|
||||||
// mNeedsCleanup is a state variable to defer cleanup of a closed stream
|
// mNeedsCleanup is a state variable to defer cleanup of a closed stream
|
||||||
// If needed, It is set in session::OnWriteSegments() and acted on and
|
// If needed, It is set in session::OnWriteSegments() and acted on and
|
||||||
// cleared when the stack returns to session::WriteSegments(). The stream
|
// cleared when the stack returns to session::WriteSegments(). The stream
|
||||||
|
|
|
@ -67,21 +67,21 @@ SpdySession3::SpdySession3(nsAHttpTransaction *aHttpTransaction,
|
||||||
|
|
||||||
LOG3(("SpdySession3::SpdySession3 %p transaction 1 = %p",
|
LOG3(("SpdySession3::SpdySession3 %p transaction 1 = %p",
|
||||||
this, aHttpTransaction));
|
this, aHttpTransaction));
|
||||||
|
|
||||||
mStreamIDHash.Init();
|
mStreamIDHash.Init();
|
||||||
mStreamTransactionHash.Init();
|
mStreamTransactionHash.Init();
|
||||||
mConnection = aHttpTransaction->Connection();
|
mConnection = aHttpTransaction->Connection();
|
||||||
mInputFrameBuffer = new char[mInputFrameBufferSize];
|
mInputFrameBuffer = new char[mInputFrameBufferSize];
|
||||||
mOutputQueueBuffer = new char[mOutputQueueSize];
|
mOutputQueueBuffer = new char[mOutputQueueSize];
|
||||||
zlibInit();
|
zlibInit();
|
||||||
|
|
||||||
mSendingChunkSize = gHttpHandler->SpdySendingChunkSize();
|
mSendingChunkSize = gHttpHandler->SpdySendingChunkSize();
|
||||||
GenerateSettings();
|
GenerateSettings();
|
||||||
|
|
||||||
if (!aHttpTransaction->IsNullTransaction())
|
if (!aHttpTransaction->IsNullTransaction())
|
||||||
AddStream(aHttpTransaction, firstPriority);
|
AddStream(aHttpTransaction, firstPriority);
|
||||||
mLastDataReadEpoch = mLastReadEpoch;
|
mLastDataReadEpoch = mLastReadEpoch;
|
||||||
|
|
||||||
mPingThreshold = gHttpHandler->SpdyPingThreshold();
|
mPingThreshold = gHttpHandler->SpdyPingThreshold();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ SpdySession3::ShutdownEnumerator(nsAHttpTransaction *key,
|
||||||
void *closure)
|
void *closure)
|
||||||
{
|
{
|
||||||
SpdySession3 *self = static_cast<SpdySession3 *>(closure);
|
SpdySession3 *self = static_cast<SpdySession3 *>(closure);
|
||||||
|
|
||||||
// On a clean server hangup the server sets the GoAwayID to be the ID of
|
// On a clean server hangup the server sets the GoAwayID to be the ID of
|
||||||
// the last transaction it processed. If the ID of stream in the
|
// the last transaction it processed. If the ID of stream in the
|
||||||
// local stream is greater than that it can safely be restarted because the
|
// local stream is greater than that it can safely be restarted because the
|
||||||
|
@ -130,7 +130,7 @@ SpdySession3::~SpdySession3()
|
||||||
|
|
||||||
inflateEnd(&mDownstreamZlib);
|
inflateEnd(&mDownstreamZlib);
|
||||||
deflateEnd(&mUpstreamZlib);
|
deflateEnd(&mUpstreamZlib);
|
||||||
|
|
||||||
mStreamTransactionHash.Enumerate(ShutdownEnumerator, this);
|
mStreamTransactionHash.Enumerate(ShutdownEnumerator, this);
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_PARALLEL_STREAMS, mConcurrentHighWater);
|
Telemetry::Accumulate(Telemetry::SPDY_PARALLEL_STREAMS, mConcurrentHighWater);
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_REQUEST_PER_CONN, (mNextStreamID - 1) / 2);
|
Telemetry::Accumulate(Telemetry::SPDY_REQUEST_PER_CONN, (mNextStreamID - 1) / 2);
|
||||||
|
@ -144,7 +144,7 @@ SpdySession3::LogIO(SpdySession3 *self, SpdyStream3 *stream, const char *label,
|
||||||
{
|
{
|
||||||
if (!LOG4_ENABLED())
|
if (!LOG4_ENABLED())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LOG4(("SpdySession3::LogIO %p stream=%p id=0x%X [%s]",
|
LOG4(("SpdySession3::LogIO %p stream=%p id=0x%X [%s]",
|
||||||
self, stream, stream ? stream->StreamID() : 0, label));
|
self, stream, stream ? stream->StreamID() : 0, label));
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ SpdySession3::LogIO(SpdySession3 *self, SpdyStream3 *stream, const char *label,
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef nsresult (*Control_FX) (SpdySession3 *self);
|
typedef nsresult (*Control_FX) (SpdySession3 *self);
|
||||||
static Control_FX sControlFunctions[] =
|
static Control_FX sControlFunctions[] =
|
||||||
{
|
{
|
||||||
nullptr,
|
nullptr,
|
||||||
SpdySession3::HandleSynStream,
|
SpdySession3::HandleSynStream,
|
||||||
|
@ -242,7 +242,7 @@ SpdySession3::ReadTimeoutTick(PRIntervalTime now)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(("SpdySession3::ReadTimeoutTick %p generating ping 0x%X\n",
|
LOG(("SpdySession3::ReadTimeoutTick %p generating ping 0x%X\n",
|
||||||
this, mNextPingID));
|
this, mNextPingID));
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ SpdySession3::RegisterStreamID(SpdyStream3 *stream)
|
||||||
|
|
||||||
MOZ_ASSERT(mNextStreamID < 0xfffffff0,
|
MOZ_ASSERT(mNextStreamID < 0xfffffff0,
|
||||||
"should have stopped admitting streams");
|
"should have stopped admitting streams");
|
||||||
|
|
||||||
uint32_t result = mNextStreamID;
|
uint32_t result = mNextStreamID;
|
||||||
mNextStreamID += 2;
|
mNextStreamID += 2;
|
||||||
|
|
||||||
|
@ -334,7 +334,7 @@ SpdySession3::AddStream(nsAHttpTransaction *aHttpTransaction,
|
||||||
this, stream));
|
this, stream));
|
||||||
mQueuedStreams.Push(stream);
|
mQueuedStreams.Push(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,7 +416,7 @@ SpdySession3::FlushOutputQueue()
|
||||||
{
|
{
|
||||||
if (!mSegmentReader || !mOutputQueueUsed)
|
if (!mSegmentReader || !mOutputQueueUsed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
uint32_t countRead;
|
uint32_t countRead;
|
||||||
uint32_t avail = mOutputQueueUsed - mOutputQueueSent;
|
uint32_t avail = mOutputQueueUsed - mOutputQueueSent;
|
||||||
|
@ -426,11 +426,11 @@ SpdySession3::FlushOutputQueue()
|
||||||
&countRead);
|
&countRead);
|
||||||
LOG3(("SpdySession3::FlushOutputQueue %p sz=%d rv=%x actual=%d",
|
LOG3(("SpdySession3::FlushOutputQueue %p sz=%d rv=%x actual=%d",
|
||||||
this, avail, rv, countRead));
|
this, avail, rv, countRead));
|
||||||
|
|
||||||
// Dont worry about errors on write, we will pick this up as a read error too
|
// Dont worry about errors on write, we will pick this up as a read error too
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (countRead == avail) {
|
if (countRead == avail) {
|
||||||
mOutputQueueUsed = 0;
|
mOutputQueueUsed = 0;
|
||||||
mOutputQueueSent = 0;
|
mOutputQueueSent = 0;
|
||||||
|
@ -441,7 +441,7 @@ SpdySession3::FlushOutputQueue()
|
||||||
|
|
||||||
// If the output queue is close to filling up and we have sent out a good
|
// If the output queue is close to filling up and we have sent out a good
|
||||||
// chunk of data from the beginning then realign it.
|
// chunk of data from the beginning then realign it.
|
||||||
|
|
||||||
if ((mOutputQueueSent >= kQueueMinimumCleanup) &&
|
if ((mOutputQueueSent >= kQueueMinimumCleanup) &&
|
||||||
((mOutputQueueSize - mOutputQueueUsed) < kQueueTailRoom)) {
|
((mOutputQueueSize - mOutputQueueUsed) < kQueueTailRoom)) {
|
||||||
RealignOutputQueue();
|
RealignOutputQueue();
|
||||||
|
@ -502,7 +502,7 @@ SpdySession3::EnsureBuffer(nsAutoArrayPtr<T> &buf,
|
||||||
{
|
{
|
||||||
if (objSize >= newSize)
|
if (objSize >= newSize)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Leave a little slop on the new allocation - add 2KB to
|
// Leave a little slop on the new allocation - add 2KB to
|
||||||
// what we need and then round the result up to a 4KB (page)
|
// what we need and then round the result up to a 4KB (page)
|
||||||
// boundary.
|
// boundary.
|
||||||
|
@ -571,7 +571,7 @@ SpdySession3::UncompressAndDiscard(uint32_t offset,
|
||||||
LOG3(("SpdySession3::UncompressAndDiscard %p Dictionary Error\n", this));
|
LOG3(("SpdySession3::UncompressAndDiscard %p Dictionary Error\n", this));
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
triedDictionary = true;
|
triedDictionary = true;
|
||||||
inflateSetDictionary(&mDownstreamZlib, SpdyStream3::kDictionary,
|
inflateSetDictionary(&mDownstreamZlib, SpdyStream3::kDictionary,
|
||||||
sizeof(SpdyStream3::kDictionary));
|
sizeof(SpdyStream3::kDictionary));
|
||||||
|
@ -603,7 +603,7 @@ SpdySession3::GeneratePing(uint32_t aID)
|
||||||
packet[5] = 0;
|
packet[5] = 0;
|
||||||
packet[6] = 0;
|
packet[6] = 0;
|
||||||
packet[7] = 4; /* length */
|
packet[7] = 4; /* length */
|
||||||
|
|
||||||
aID = PR_htonl(aID);
|
aID = PR_htonl(aID);
|
||||||
memcpy(packet + 8, &aID, 4);
|
memcpy(packet + 8, &aID, 4);
|
||||||
|
|
||||||
|
@ -630,7 +630,7 @@ SpdySession3::GenerateRstStream(uint32_t aStatusCode, uint32_t aID)
|
||||||
packet[5] = 0;
|
packet[5] = 0;
|
||||||
packet[6] = 0;
|
packet[6] = 0;
|
||||||
packet[7] = 8; /* length */
|
packet[7] = 8; /* length */
|
||||||
|
|
||||||
aID = PR_htonl(aID);
|
aID = PR_htonl(aID);
|
||||||
memcpy(packet + 8, &aID, 4);
|
memcpy(packet + 8, &aID, 4);
|
||||||
aStatusCode = PR_htonl(aStatusCode);
|
aStatusCode = PR_htonl(aStatusCode);
|
||||||
|
@ -656,7 +656,7 @@ SpdySession3::GenerateGoAway(uint32_t aStatusCode)
|
||||||
packet[1] = kVersion;
|
packet[1] = kVersion;
|
||||||
packet[3] = CONTROL_TYPE_GOAWAY;
|
packet[3] = CONTROL_TYPE_GOAWAY;
|
||||||
packet[7] = 8; /* data length */
|
packet[7] = 8; /* data length */
|
||||||
|
|
||||||
// last-good-stream-id are bytes 8-11, when we accept server push this will
|
// last-good-stream-id are bytes 8-11, when we accept server push this will
|
||||||
// need to be set non zero
|
// need to be set non zero
|
||||||
|
|
||||||
|
@ -710,7 +710,7 @@ SpdySession3::GenerateSettings()
|
||||||
memcpy(packet + 16 + 8 * numberOfEntries, &cwnd, 4);
|
memcpy(packet + 16 + 8 * numberOfEntries, &cwnd, 4);
|
||||||
numberOfEntries++;
|
numberOfEntries++;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet[15 + 8 * numberOfEntries] = SETTINGS_TYPE_INITIAL_WINDOW;
|
packet[15 + 8 * numberOfEntries] = SETTINGS_TYPE_INITIAL_WINDOW;
|
||||||
uint32_t rwin = PR_htonl(kInitialRwin);
|
uint32_t rwin = PR_htonl(kInitialRwin);
|
||||||
memcpy(packet + 16 + 8 * numberOfEntries, &rwin, 4);
|
memcpy(packet + 16 + 8 * numberOfEntries, &rwin, 4);
|
||||||
|
@ -742,21 +742,21 @@ SpdySession3::VerifyStream(SpdyStream3 *aStream, uint32_t aOptionalID = 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
uint32_t test = 0;
|
uint32_t test = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (aStream->StreamID() == kDeadStreamID)
|
if (aStream->StreamID() == kDeadStreamID)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
nsAHttpTransaction *trans = aStream->Transaction();
|
nsAHttpTransaction *trans = aStream->Transaction();
|
||||||
|
|
||||||
test++;
|
test++;
|
||||||
if (!trans)
|
if (!trans)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
test++;
|
test++;
|
||||||
if (mStreamTransactionHash.Get(trans) != aStream)
|
if (mStreamTransactionHash.Get(trans) != aStream)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (aStream->StreamID()) {
|
if (aStream->StreamID()) {
|
||||||
SpdyStream3 *idStream = mStreamIDHash.Get(aStream->StreamID());
|
SpdyStream3 *idStream = mStreamIDHash.Get(aStream->StreamID());
|
||||||
|
|
||||||
|
@ -803,7 +803,7 @@ SpdySession3::CleanupStream(SpdyStream3 *aStream, nsresult aResult,
|
||||||
--mConcurrent;
|
--mConcurrent;
|
||||||
ProcessPending();
|
ProcessPending();
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseStream(aStream, aResult);
|
CloseStream(aStream, aResult);
|
||||||
|
|
||||||
// Remove the stream from the ID hash table. (this one isn't short, which is
|
// Remove the stream from the ID hash table. (this one isn't short, which is
|
||||||
|
@ -859,7 +859,7 @@ nsresult
|
||||||
SpdySession3::HandleSynStream(SpdySession3 *self)
|
SpdySession3::HandleSynStream(SpdySession3 *self)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(self->mFrameControlType == CONTROL_TYPE_SYN_STREAM);
|
MOZ_ASSERT(self->mFrameControlType == CONTROL_TYPE_SYN_STREAM);
|
||||||
|
|
||||||
if (self->mInputFrameDataSize < 18) {
|
if (self->mInputFrameDataSize < 18) {
|
||||||
LOG3(("SpdySession3::HandleSynStream %p SYN_STREAM too short data=%d",
|
LOG3(("SpdySession3::HandleSynStream %p SYN_STREAM too short data=%d",
|
||||||
self, self->mInputFrameDataSize));
|
self, self->mInputFrameDataSize));
|
||||||
|
@ -874,7 +874,7 @@ SpdySession3::HandleSynStream(SpdySession3 *self)
|
||||||
LOG3(("SpdySession3::HandleSynStream %p recv SYN_STREAM (push) "
|
LOG3(("SpdySession3::HandleSynStream %p recv SYN_STREAM (push) "
|
||||||
"for ID 0x%X associated with 0x%X.",
|
"for ID 0x%X associated with 0x%X.",
|
||||||
self, streamID, associatedID));
|
self, streamID, associatedID));
|
||||||
|
|
||||||
if (streamID & 0x01) { // test for odd stream ID
|
if (streamID & 0x01) { // test for odd stream ID
|
||||||
LOG3(("SpdySession3::HandleSynStream %p recvd SYN_STREAM id must be even.",
|
LOG3(("SpdySession3::HandleSynStream %p recvd SYN_STREAM id must be even.",
|
||||||
self));
|
self));
|
||||||
|
@ -927,7 +927,7 @@ SpdySession3::HandleSynReply(SpdySession3 *self)
|
||||||
// A framing error is a session wide error that cannot be recovered
|
// A framing error is a session wide error that cannot be recovered
|
||||||
return NS_ERROR_ILLEGAL_VALUE;
|
return NS_ERROR_ILLEGAL_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG3(("SpdySession3::HandleSynReply %p lookup via streamID in syn_reply.\n",
|
LOG3(("SpdySession3::HandleSynReply %p lookup via streamID in syn_reply.\n",
|
||||||
self));
|
self));
|
||||||
uint32_t streamID =
|
uint32_t streamID =
|
||||||
|
@ -946,7 +946,7 @@ SpdySession3::HandleSynReply(SpdySession3 *self)
|
||||||
|
|
||||||
if (streamID >= self->mNextStreamID)
|
if (streamID >= self->mNextStreamID)
|
||||||
self->GenerateRstStream(RST_INVALID_STREAM, streamID);
|
self->GenerateRstStream(RST_INVALID_STREAM, streamID);
|
||||||
|
|
||||||
if (NS_FAILED(self->UncompressAndDiscard(12,
|
if (NS_FAILED(self->UncompressAndDiscard(12,
|
||||||
self->mInputFrameDataSize - 4))) {
|
self->mInputFrameDataSize - 4))) {
|
||||||
LOG(("SpdySession3::HandleSynReply uncompress failed\n"));
|
LOG(("SpdySession3::HandleSynReply uncompress failed\n"));
|
||||||
|
@ -989,7 +989,7 @@ SpdySession3::HandleSynReply(SpdySession3 *self)
|
||||||
self->mInputFrameDataStream->RecvdFin()));
|
self->mInputFrameDataStream->RecvdFin()));
|
||||||
|
|
||||||
self->CleanupStream(self->mInputFrameDataStream, NS_ERROR_ALREADY_OPENED,
|
self->CleanupStream(self->mInputFrameDataStream, NS_ERROR_ALREADY_OPENED,
|
||||||
self->mInputFrameDataStream->RecvdFin() ?
|
self->mInputFrameDataStream->RecvdFin() ?
|
||||||
RST_STREAM_ALREADY_CLOSED : RST_STREAM_IN_USE);
|
RST_STREAM_ALREADY_CLOSED : RST_STREAM_IN_USE);
|
||||||
self->ResetDownstreamState();
|
self->ResetDownstreamState();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -1076,7 +1076,7 @@ SpdySession3::HandleRstStream(SpdySession3 *self)
|
||||||
self));
|
self));
|
||||||
return NS_ERROR_ILLEGAL_VALUE;
|
return NS_ERROR_ILLEGAL_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->mDownstreamRstReason == RST_INVALID_STREAM ||
|
if (self->mDownstreamRstReason == RST_INVALID_STREAM ||
|
||||||
self->mDownstreamRstReason == RST_STREAM_IN_USE ||
|
self->mDownstreamRstReason == RST_STREAM_IN_USE ||
|
||||||
self->mDownstreamRstReason == RST_FLOW_CONTROL_ERROR) {
|
self->mDownstreamRstReason == RST_FLOW_CONTROL_ERROR) {
|
||||||
|
@ -1155,21 +1155,21 @@ SpdySession3::HandleSettings(SpdySession3 *self)
|
||||||
case SETTINGS_TYPE_UPLOAD_BW:
|
case SETTINGS_TYPE_UPLOAD_BW:
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_UL_BW, value);
|
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_UL_BW, value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETTINGS_TYPE_DOWNLOAD_BW:
|
case SETTINGS_TYPE_DOWNLOAD_BW:
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_DL_BW, value);
|
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_DL_BW, value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETTINGS_TYPE_RTT:
|
case SETTINGS_TYPE_RTT:
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_RTT, value);
|
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_RTT, value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETTINGS_TYPE_MAX_CONCURRENT:
|
case SETTINGS_TYPE_MAX_CONCURRENT:
|
||||||
self->mMaxConcurrent = value;
|
self->mMaxConcurrent = value;
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_MAX_STREAMS, value);
|
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_MAX_STREAMS, value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETTINGS_TYPE_CWND:
|
case SETTINGS_TYPE_CWND:
|
||||||
if (flags & PERSIST_VALUE)
|
if (flags & PERSIST_VALUE)
|
||||||
{
|
{
|
||||||
nsRefPtr<nsHttpConnectionInfo> ci;
|
nsRefPtr<nsHttpConnectionInfo> ci;
|
||||||
|
@ -1183,7 +1183,7 @@ SpdySession3::HandleSettings(SpdySession3 *self)
|
||||||
case SETTINGS_TYPE_DOWNLOAD_RETRANS_RATE:
|
case SETTINGS_TYPE_DOWNLOAD_RETRANS_RATE:
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_RETRANS, value);
|
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_RETRANS, value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETTINGS_TYPE_INITIAL_WINDOW:
|
case SETTINGS_TYPE_INITIAL_WINDOW:
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_IW, value >> 10);
|
Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_IW, value >> 10);
|
||||||
{
|
{
|
||||||
|
@ -1195,13 +1195,13 @@ SpdySession3::HandleSettings(SpdySession3 *self)
|
||||||
&delta);
|
&delta);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self->ResetDownstreamState();
|
self->ResetDownstreamState();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -1244,7 +1244,7 @@ SpdySession3::HandlePing(SpdySession3 *self)
|
||||||
// Servers initiate even numbered pings, go ahead and echo it back
|
// Servers initiate even numbered pings, go ahead and echo it back
|
||||||
self->GeneratePing(pingID);
|
self->GeneratePing(pingID);
|
||||||
}
|
}
|
||||||
|
|
||||||
self->ResetDownstreamState();
|
self->ResetDownstreamState();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -1265,7 +1265,7 @@ SpdySession3::HandleGoAway(SpdySession3 *self)
|
||||||
PR_ntohl(reinterpret_cast<uint32_t *>(self->mInputFrameBuffer.get())[2]);
|
PR_ntohl(reinterpret_cast<uint32_t *>(self->mInputFrameBuffer.get())[2]);
|
||||||
self->mCleanShutdown = true;
|
self->mCleanShutdown = true;
|
||||||
|
|
||||||
// Find streams greater than the last-good ID and mark them for deletion
|
// Find streams greater than the last-good ID and mark them for deletion
|
||||||
// in the mGoAwayStreamsToRestart queue with the GoAwayEnumerator. They can
|
// in the mGoAwayStreamsToRestart queue with the GoAwayEnumerator. They can
|
||||||
// be restarted.
|
// be restarted.
|
||||||
self->mStreamTransactionHash.Enumerate(GoAwayEnumerator, self);
|
self->mStreamTransactionHash.Enumerate(GoAwayEnumerator, self);
|
||||||
|
@ -1294,7 +1294,7 @@ SpdySession3::HandleGoAway(SpdySession3 *self)
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG3(("SpdySession3::HandleGoAway %p GOAWAY Last-Good-ID 0x%X status 0x%X "
|
LOG3(("SpdySession3::HandleGoAway %p GOAWAY Last-Good-ID 0x%X status 0x%X "
|
||||||
"live streams=%d\n", self, self->mGoAwayID,
|
"live streams=%d\n", self, self->mGoAwayID,
|
||||||
PR_ntohl(reinterpret_cast<uint32_t *>(self->mInputFrameBuffer.get())[3]),
|
PR_ntohl(reinterpret_cast<uint32_t *>(self->mInputFrameBuffer.get())[3]),
|
||||||
self->mStreamTransactionHash.Count()));
|
self->mStreamTransactionHash.Count()));
|
||||||
|
|
||||||
|
@ -1416,7 +1416,7 @@ SpdySession3::HandleWindowUpdate(SpdySession3 *self)
|
||||||
|
|
||||||
int64_t oldRemoteWindow = self->mInputFrameDataStream->RemoteWindow();
|
int64_t oldRemoteWindow = self->mInputFrameDataStream->RemoteWindow();
|
||||||
self->mInputFrameDataStream->UpdateRemoteWindow(delta);
|
self->mInputFrameDataStream->UpdateRemoteWindow(delta);
|
||||||
|
|
||||||
LOG3(("SpdySession3::HandleWindowUpdate %p stream 0x%X window "
|
LOG3(("SpdySession3::HandleWindowUpdate %p stream 0x%X window "
|
||||||
"%d increased by %d.\n", self, streamID, oldRemoteWindow, delta));
|
"%d increased by %d.\n", self, streamID, oldRemoteWindow, delta));
|
||||||
|
|
||||||
|
@ -1499,7 +1499,7 @@ SpdySession3::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
uint32_t *countRead)
|
uint32_t *countRead)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
|
|
||||||
MOZ_ASSERT(!mSegmentReader || !reader || (mSegmentReader == reader),
|
MOZ_ASSERT(!mSegmentReader || !reader || (mSegmentReader == reader),
|
||||||
"Inconsistent Write Function Callback");
|
"Inconsistent Write Function Callback");
|
||||||
|
|
||||||
|
@ -1519,7 +1519,7 @@ SpdySession3::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
SetWriteCallbacks();
|
SetWriteCallbacks();
|
||||||
return NS_BASE_STREAM_WOULD_BLOCK;
|
return NS_BASE_STREAM_WOULD_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG3(("SpdySession3 %p will write from SpdyStream3 %p 0x%X "
|
LOG3(("SpdySession3 %p will write from SpdyStream3 %p 0x%X "
|
||||||
"block-input=%d block-output=%d\n", this, stream, stream->StreamID(),
|
"block-input=%d block-output=%d\n", this, stream, stream->StreamID(),
|
||||||
stream->RequestBlockedOnRead(), stream->BlockedOnRwin()));
|
stream->RequestBlockedOnRead(), stream->BlockedOnRwin()));
|
||||||
|
@ -1537,11 +1537,11 @@ SpdySession3::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
ResumeRecv();
|
ResumeRecv();
|
||||||
|
|
||||||
if (stream->RequestBlockedOnRead()) {
|
if (stream->RequestBlockedOnRead()) {
|
||||||
|
|
||||||
// We are blocked waiting for input - either more http headers or
|
// We are blocked waiting for input - either more http headers or
|
||||||
// any request body data. When more data from the request stream
|
// any request body data. When more data from the request stream
|
||||||
// becomes available the httptransaction will call conn->ResumeSend().
|
// becomes available the httptransaction will call conn->ResumeSend().
|
||||||
|
|
||||||
LOG3(("SpdySession3::ReadSegments %p dealing with block on read", this));
|
LOG3(("SpdySession3::ReadSegments %p dealing with block on read", this));
|
||||||
|
|
||||||
// call readsegments again if there are other streams ready
|
// call readsegments again if there are other streams ready
|
||||||
|
@ -1553,7 +1553,7 @@ SpdySession3::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
SetWriteCallbacks();
|
SetWriteCallbacks();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
LOG3(("SpdySession3::ReadSegments %p returning FAIL code %X",
|
LOG3(("SpdySession3::ReadSegments %p returning FAIL code %X",
|
||||||
this, rv));
|
this, rv));
|
||||||
|
@ -1561,7 +1561,7 @@ SpdySession3::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
CleanupStream(stream, rv, RST_CANCEL);
|
CleanupStream(stream, rv, RST_CANCEL);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*countRead > 0) {
|
if (*countRead > 0) {
|
||||||
LOG3(("SpdySession3::ReadSegments %p stream=%p countread=%d",
|
LOG3(("SpdySession3::ReadSegments %p stream=%p countread=%d",
|
||||||
this, stream, *countRead));
|
this, stream, *countRead));
|
||||||
|
@ -1575,10 +1575,10 @@ SpdySession3::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
this, stream, stream->StreamID()));
|
this, stream, stream->StreamID()));
|
||||||
return NS_BASE_STREAM_WOULD_BLOCK;
|
return NS_BASE_STREAM_WOULD_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG3(("SpdySession3::ReadSegments %p stream=%p stream send complete",
|
LOG3(("SpdySession3::ReadSegments %p stream=%p stream send complete",
|
||||||
this, stream));
|
this, stream));
|
||||||
|
|
||||||
// call readsegments again if there are other streams ready
|
// call readsegments again if there are other streams ready
|
||||||
// to go in this session
|
// to go in this session
|
||||||
SetWriteCallbacks();
|
SetWriteCallbacks();
|
||||||
|
@ -1593,7 +1593,7 @@ SpdySession3::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
// OnWriteSegment(). That function will gateway it into http and feed
|
// OnWriteSegment(). That function will gateway it into http and feed
|
||||||
// it to the appropriate transaction.
|
// it to the appropriate transaction.
|
||||||
|
|
||||||
// we call writer->OnWriteSegment via NetworkRead() to get a spdy header..
|
// we call writer->OnWriteSegment via NetworkRead() to get a spdy header..
|
||||||
// and decide if it is data or control.. if it is control, just deal with it.
|
// and decide if it is data or control.. if it is control, just deal with it.
|
||||||
// if it is data, identify the spdy stream
|
// if it is data, identify the spdy stream
|
||||||
// call stream->WriteSegemnts which can call this::OnWriteSegment to get the
|
// call stream->WriteSegemnts which can call this::OnWriteSegment to get the
|
||||||
|
@ -1605,7 +1605,7 @@ SpdySession3::WriteSegments(nsAHttpSegmentWriter *writer,
|
||||||
uint32_t *countWritten)
|
uint32_t *countWritten)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
*countWritten = 0;
|
*countWritten = 0;
|
||||||
|
|
||||||
|
@ -1613,16 +1613,16 @@ SpdySession3::WriteSegments(nsAHttpSegmentWriter *writer,
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
SetWriteCallbacks();
|
SetWriteCallbacks();
|
||||||
|
|
||||||
// We buffer all control frames and act on them in this layer.
|
// We buffer all control frames and act on them in this layer.
|
||||||
// We buffer the first 8 bytes of data frames (the header) but
|
// We buffer the first 8 bytes of data frames (the header) but
|
||||||
// the actual data is passed through unprocessed.
|
// the actual data is passed through unprocessed.
|
||||||
|
|
||||||
if (mDownstreamState == BUFFERING_FRAME_HEADER) {
|
if (mDownstreamState == BUFFERING_FRAME_HEADER) {
|
||||||
// The first 8 bytes of every frame is header information that
|
// The first 8 bytes of every frame is header information that
|
||||||
// we are going to want to strip before passing to http. That is
|
// we are going to want to strip before passing to http. That is
|
||||||
// true of both control and data packets.
|
// true of both control and data packets.
|
||||||
|
|
||||||
MOZ_ASSERT(mInputFrameBufferUsed < 8,
|
MOZ_ASSERT(mInputFrameBufferUsed < 8,
|
||||||
"Frame Buffer Used Too Large for State");
|
"Frame Buffer Used Too Large for State");
|
||||||
|
|
||||||
|
@ -1657,21 +1657,21 @@ SpdySession3::WriteSegments(nsAHttpSegmentWriter *writer,
|
||||||
PR_ntohl(reinterpret_cast<uint32_t *>(mInputFrameBuffer.get())[1]);
|
PR_ntohl(reinterpret_cast<uint32_t *>(mInputFrameBuffer.get())[1]);
|
||||||
mInputFrameDataSize &= 0x00ffffff;
|
mInputFrameDataSize &= 0x00ffffff;
|
||||||
mInputFrameDataRead = 0;
|
mInputFrameDataRead = 0;
|
||||||
|
|
||||||
if (mInputFrameBuffer[0] & kFlag_Control) {
|
if (mInputFrameBuffer[0] & kFlag_Control) {
|
||||||
EnsureBuffer(mInputFrameBuffer, mInputFrameDataSize + 8, 8,
|
EnsureBuffer(mInputFrameBuffer, mInputFrameDataSize + 8, 8,
|
||||||
mInputFrameBufferSize);
|
mInputFrameBufferSize);
|
||||||
ChangeDownstreamState(BUFFERING_CONTROL_FRAME);
|
ChangeDownstreamState(BUFFERING_CONTROL_FRAME);
|
||||||
|
|
||||||
// The first 32 bit word of the header is
|
// The first 32 bit word of the header is
|
||||||
// 1 ctrl - 15 version - 16 type
|
// 1 ctrl - 15 version - 16 type
|
||||||
uint16_t version =
|
uint16_t version =
|
||||||
PR_ntohs(reinterpret_cast<uint16_t *>(mInputFrameBuffer.get())[0]);
|
PR_ntohs(reinterpret_cast<uint16_t *>(mInputFrameBuffer.get())[0]);
|
||||||
version &= 0x7fff;
|
version &= 0x7fff;
|
||||||
|
|
||||||
mFrameControlType =
|
mFrameControlType =
|
||||||
PR_ntohs(reinterpret_cast<uint16_t *>(mInputFrameBuffer.get())[1]);
|
PR_ntohs(reinterpret_cast<uint16_t *>(mInputFrameBuffer.get())[1]);
|
||||||
|
|
||||||
LOG3(("SpdySession3::WriteSegments %p - Control Frame Identified "
|
LOG3(("SpdySession3::WriteSegments %p - Control Frame Identified "
|
||||||
"type %d version %d data len %d",
|
"type %d version %d data len %d",
|
||||||
this, mFrameControlType, version, mInputFrameDataSize));
|
this, mFrameControlType, version, mInputFrameDataSize));
|
||||||
|
@ -1800,7 +1800,7 @@ SpdySession3::WriteSegments(nsAHttpSegmentWriter *writer,
|
||||||
mNeedsCleanup = nullptr; /* just in case */
|
mNeedsCleanup = nullptr; /* just in case */
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mNeedsCleanup) {
|
if (mNeedsCleanup) {
|
||||||
LOG3(("SpdySession3::WriteSegments session=%p stream=%p 0x%X "
|
LOG3(("SpdySession3::WriteSegments session=%p stream=%p 0x%X "
|
||||||
"cleanup stream based on mNeedsCleanup.\n",
|
"cleanup stream based on mNeedsCleanup.\n",
|
||||||
|
@ -1840,7 +1840,7 @@ SpdySession3::WriteSegments(nsAHttpSegmentWriter *writer,
|
||||||
ResetDownstreamState();
|
ResetDownstreamState();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDownstreamState != BUFFERING_CONTROL_FRAME) {
|
if (mDownstreamState != BUFFERING_CONTROL_FRAME) {
|
||||||
// this cannot happen
|
// this cannot happen
|
||||||
MOZ_ASSERT(false, "Not in Bufering Control Frame State");
|
MOZ_ASSERT(false, "Not in Bufering Control Frame State");
|
||||||
|
@ -1874,7 +1874,7 @@ SpdySession3::WriteSegments(nsAHttpSegmentWriter *writer,
|
||||||
// checked to make sure it was in range, but we will check it again
|
// checked to make sure it was in range, but we will check it again
|
||||||
// at time of use to make sure a regression doesn't creep in.
|
// at time of use to make sure a regression doesn't creep in.
|
||||||
if (mFrameControlType >= CONTROL_TYPE_LAST ||
|
if (mFrameControlType >= CONTROL_TYPE_LAST ||
|
||||||
mFrameControlType <= CONTROL_TYPE_FIRST)
|
mFrameControlType <= CONTROL_TYPE_FIRST)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(false, "control type out of range");
|
MOZ_ASSERT(false, "control type out of range");
|
||||||
return NS_ERROR_ILLEGAL_VALUE;
|
return NS_ERROR_ILLEGAL_VALUE;
|
||||||
|
@ -1918,11 +1918,11 @@ SpdySession3::UpdateLocalRwin(SpdyStream3 *stream,
|
||||||
// Generate window updates directly out of spdysession instead of the stream
|
// Generate window updates directly out of spdysession instead of the stream
|
||||||
// in order to avoid queue delays in getting the ACK out.
|
// in order to avoid queue delays in getting the ACK out.
|
||||||
uint32_t toack = unacked & 0x7fffffff;
|
uint32_t toack = unacked & 0x7fffffff;
|
||||||
|
|
||||||
LOG3(("SpdySession3::UpdateLocalRwin Ack %p 0x%X %d\n",
|
LOG3(("SpdySession3::UpdateLocalRwin Ack %p 0x%X %d\n",
|
||||||
this, stream->StreamID(), toack));
|
this, stream->StreamID(), toack));
|
||||||
stream->IncrementLocalWindow(toack);
|
stream->IncrementLocalWindow(toack);
|
||||||
|
|
||||||
static const uint32_t dataLen = 8;
|
static const uint32_t dataLen = 8;
|
||||||
EnsureBuffer(mOutputQueueBuffer, mOutputQueueUsed + 8 + dataLen,
|
EnsureBuffer(mOutputQueueBuffer, mOutputQueueUsed + 8 + dataLen,
|
||||||
mOutputQueueUsed, mOutputQueueSize);
|
mOutputQueueUsed, mOutputQueueSize);
|
||||||
|
@ -1934,7 +1934,7 @@ SpdySession3::UpdateLocalRwin(SpdyStream3 *stream,
|
||||||
packet[1] = kVersion;
|
packet[1] = kVersion;
|
||||||
packet[3] = CONTROL_TYPE_WINDOW_UPDATE;
|
packet[3] = CONTROL_TYPE_WINDOW_UPDATE;
|
||||||
packet[7] = dataLen;
|
packet[7] = dataLen;
|
||||||
|
|
||||||
uint32_t id = PR_htonl(stream->StreamID());
|
uint32_t id = PR_htonl(stream->StreamID());
|
||||||
memcpy(packet + 8, &id, 4);
|
memcpy(packet + 8, &id, 4);
|
||||||
toack = PR_htonl(toack);
|
toack = PR_htonl(toack);
|
||||||
|
@ -2001,9 +2001,9 @@ SpdySession3::OnReadSegment(const char *buf,
|
||||||
uint32_t *countRead)
|
uint32_t *countRead)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
// If we can release old queued data then we can try and write the new
|
// If we can release old queued data then we can try and write the new
|
||||||
// data directly to the network without using the output queue at all
|
// data directly to the network without using the output queue at all
|
||||||
if (mOutputQueueUsed)
|
if (mOutputQueueUsed)
|
||||||
|
@ -2017,7 +2017,7 @@ SpdySession3::OnReadSegment(const char *buf,
|
||||||
*countRead = 0;
|
*countRead = 0;
|
||||||
else if (NS_FAILED(rv))
|
else if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
if (*countRead < count) {
|
if (*countRead < count) {
|
||||||
uint32_t required = count - *countRead;
|
uint32_t required = count - *countRead;
|
||||||
// assuming a commitment() happened, this ensurebuffer is a nop
|
// assuming a commitment() happened, this ensurebuffer is a nop
|
||||||
|
@ -2027,7 +2027,7 @@ SpdySession3::OnReadSegment(const char *buf,
|
||||||
memcpy(mOutputQueueBuffer.get(), buf + *countRead, required);
|
memcpy(mOutputQueueBuffer.get(), buf + *countRead, required);
|
||||||
mOutputQueueUsed = required;
|
mOutputQueueUsed = required;
|
||||||
}
|
}
|
||||||
|
|
||||||
*countRead = count;
|
*countRead = count;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -2043,7 +2043,7 @@ SpdySession3::OnReadSegment(const char *buf,
|
||||||
|
|
||||||
if ((mOutputQueueUsed + count) > (mOutputQueueSize - kQueueReserved))
|
if ((mOutputQueueUsed + count) > (mOutputQueueSize - kQueueReserved))
|
||||||
return NS_BASE_STREAM_WOULD_BLOCK;
|
return NS_BASE_STREAM_WOULD_BLOCK;
|
||||||
|
|
||||||
memcpy(mOutputQueueBuffer.get() + mOutputQueueUsed, buf, count);
|
memcpy(mOutputQueueBuffer.get() + mOutputQueueUsed, buf, count);
|
||||||
mOutputQueueUsed += count;
|
mOutputQueueUsed += count;
|
||||||
*countRead = count;
|
*countRead = count;
|
||||||
|
@ -2105,7 +2105,7 @@ SpdySession3::OnWriteSegment(char *buf,
|
||||||
// stack with WriteSegments()
|
// stack with WriteSegments()
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDownstreamState == PROCESSING_DATA_FRAME) {
|
if (mDownstreamState == PROCESSING_DATA_FRAME) {
|
||||||
|
|
||||||
if (mInputFrameDataLast &&
|
if (mInputFrameDataLast &&
|
||||||
|
@ -2114,7 +2114,7 @@ SpdySession3::OnWriteSegment(char *buf,
|
||||||
SetNeedsCleanup();
|
SetNeedsCleanup();
|
||||||
return NS_BASE_STREAM_CLOSED;
|
return NS_BASE_STREAM_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = std::min(count, mInputFrameDataSize - mInputFrameDataRead);
|
count = std::min(count, mInputFrameDataSize - mInputFrameDataRead);
|
||||||
rv = NetworkRead(mSegmentWriter, buf, count, countWritten);
|
rv = NetworkRead(mSegmentWriter, buf, count, countWritten);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
|
@ -2124,23 +2124,23 @@ SpdySession3::OnWriteSegment(char *buf,
|
||||||
buf, *countWritten);
|
buf, *countWritten);
|
||||||
|
|
||||||
mInputFrameDataRead += *countWritten;
|
mInputFrameDataRead += *countWritten;
|
||||||
|
|
||||||
mInputFrameDataStream->UpdateTransportReadEvents(*countWritten);
|
mInputFrameDataStream->UpdateTransportReadEvents(*countWritten);
|
||||||
if ((mInputFrameDataRead == mInputFrameDataSize) && !mInputFrameDataLast)
|
if ((mInputFrameDataRead == mInputFrameDataSize) && !mInputFrameDataLast)
|
||||||
ResetDownstreamState();
|
ResetDownstreamState();
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDownstreamState == PROCESSING_COMPLETE_HEADERS) {
|
if (mDownstreamState == PROCESSING_COMPLETE_HEADERS) {
|
||||||
|
|
||||||
if (mFlatHTTPResponseHeaders.Length() == mFlatHTTPResponseHeadersOut &&
|
if (mFlatHTTPResponseHeaders.Length() == mFlatHTTPResponseHeadersOut &&
|
||||||
mInputFrameDataLast) {
|
mInputFrameDataLast) {
|
||||||
*countWritten = 0;
|
*countWritten = 0;
|
||||||
SetNeedsCleanup();
|
SetNeedsCleanup();
|
||||||
return NS_BASE_STREAM_CLOSED;
|
return NS_BASE_STREAM_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = std::min(count,
|
count = std::min(count,
|
||||||
mFlatHTTPResponseHeaders.Length() -
|
mFlatHTTPResponseHeaders.Length() -
|
||||||
mFlatHTTPResponseHeadersOut);
|
mFlatHTTPResponseHeadersOut);
|
||||||
|
@ -2166,7 +2166,7 @@ SpdySession3::OnWriteSegment(char *buf,
|
||||||
ResetDownstreamState();
|
ResetDownstreamState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2205,7 +2205,7 @@ SpdySession3::TransactionHasDataToWrite(nsAHttpTransaction *caller)
|
||||||
this, caller));
|
this, caller));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG3(("SpdySession3::TransactionHasDataToWrite %p ID is 0x%X\n",
|
LOG3(("SpdySession3::TransactionHasDataToWrite %p ID is 0x%X\n",
|
||||||
this, stream->StreamID()));
|
this, stream->StreamID()));
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ public:
|
||||||
|
|
||||||
// When the connection is active this is called every 1 second
|
// When the connection is active this is called every 1 second
|
||||||
void ReadTimeoutTick(PRIntervalTime now);
|
void ReadTimeoutTick(PRIntervalTime now);
|
||||||
|
|
||||||
// Idle time represents time since "goodput".. e.g. a data or header frame
|
// Idle time represents time since "goodput".. e.g. a data or header frame
|
||||||
PRIntervalTime IdleTime();
|
PRIntervalTime IdleTime();
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ public:
|
||||||
|
|
||||||
const static uint8_t kFlag_Data_FIN = 0x01;
|
const static uint8_t kFlag_Data_FIN = 0x01;
|
||||||
const static uint8_t kFlag_Data_UNI = 0x02;
|
const static uint8_t kFlag_Data_UNI = 0x02;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
CONTROL_TYPE_FIRST = 0,
|
CONTROL_TYPE_FIRST = 0,
|
||||||
|
@ -170,7 +170,7 @@ public:
|
||||||
|
|
||||||
// an overload of nsAHttpSegementReader
|
// an overload of nsAHttpSegementReader
|
||||||
virtual nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment);
|
virtual nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment);
|
||||||
|
|
||||||
uint32_t GetServerInitialWindow() { return mServerInitialWindow; }
|
uint32_t GetServerInitialWindow() { return mServerInitialWindow; }
|
||||||
|
|
||||||
void PrintDiagnostics (nsCString &log);
|
void PrintDiagnostics (nsCString &log);
|
||||||
|
@ -215,7 +215,7 @@ private:
|
||||||
// a wrapper for all calls to the nshttpconnection level segment writer. Used
|
// a wrapper for all calls to the nshttpconnection level segment writer. Used
|
||||||
// to track network I/O for timeout purposes
|
// to track network I/O for timeout purposes
|
||||||
nsresult NetworkRead(nsAHttpSegmentWriter *, char *, uint32_t, uint32_t *);
|
nsresult NetworkRead(nsAHttpSegmentWriter *, char *, uint32_t, uint32_t *);
|
||||||
|
|
||||||
static PLDHashOperator ShutdownEnumerator(nsAHttpTransaction *,
|
static PLDHashOperator ShutdownEnumerator(nsAHttpTransaction *,
|
||||||
nsAutoPtr<SpdyStream3> &,
|
nsAutoPtr<SpdyStream3> &,
|
||||||
void *);
|
void *);
|
||||||
|
@ -273,7 +273,7 @@ private:
|
||||||
uint32_t mInputFrameBufferSize;
|
uint32_t mInputFrameBufferSize;
|
||||||
uint32_t mInputFrameBufferUsed;
|
uint32_t mInputFrameBufferUsed;
|
||||||
nsAutoArrayPtr<char> mInputFrameBuffer;
|
nsAutoArrayPtr<char> mInputFrameBuffer;
|
||||||
|
|
||||||
// mInputFrameDataSize/Read are used for tracking the amount of data consumed
|
// mInputFrameDataSize/Read are used for tracking the amount of data consumed
|
||||||
// in a data frame. the data itself is not buffered in spdy
|
// in a data frame. the data itself is not buffered in spdy
|
||||||
// The frame size is mInputFrameDataSize + the constant 8 byte header
|
// The frame size is mInputFrameDataSize + the constant 8 byte header
|
||||||
|
@ -285,7 +285,7 @@ private:
|
||||||
// (e.g. a data frame after the stream-id has been decoded), this points
|
// (e.g. a data frame after the stream-id has been decoded), this points
|
||||||
// to the stream.
|
// to the stream.
|
||||||
SpdyStream3 *mInputFrameDataStream;
|
SpdyStream3 *mInputFrameDataStream;
|
||||||
|
|
||||||
// mNeedsCleanup is a state variable to defer cleanup of a closed stream
|
// mNeedsCleanup is a state variable to defer cleanup of a closed stream
|
||||||
// If needed, It is set in session::OnWriteSegments() and acted on and
|
// If needed, It is set in session::OnWriteSegments() and acted on and
|
||||||
// cleared when the stack returns to session::WriteSegments(). The stream
|
// cleared when the stack returns to session::WriteSegments(). The stream
|
||||||
|
|
|
@ -80,7 +80,7 @@ SpdyStream2::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
this, reader, count, mUpstreamState));
|
this, reader, count, mUpstreamState));
|
||||||
|
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
|
|
||||||
nsresult rv = NS_ERROR_UNEXPECTED;
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
||||||
mRequestBlockedOnRead = 0;
|
mRequestBlockedOnRead = 0;
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ SpdyStream2::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
mUpstreamState == GENERATING_SYN_STREAM &&
|
mUpstreamState == GENERATING_SYN_STREAM &&
|
||||||
!mSynFrameComplete)
|
!mSynFrameComplete)
|
||||||
mSession->TransactionHasDataToWrite(this);
|
mSession->TransactionHasDataToWrite(this);
|
||||||
|
|
||||||
// mTxinlineFrameUsed represents any queued un-sent frame. It might
|
// mTxinlineFrameUsed represents any queued un-sent frame. It might
|
||||||
// be 0 if there is no such frame, which is not a gurantee that we
|
// be 0 if there is no such frame, which is not a gurantee that we
|
||||||
// don't have more request body to send - just that any data that was
|
// don't have more request body to send - just that any data that was
|
||||||
|
@ -146,7 +146,7 @@ SpdyStream2::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
mTxInlineFrameUsed = 0; // cancel fin data packet
|
mTxInlineFrameUsed = 0; // cancel fin data packet
|
||||||
ChangeState(UPSTREAM_COMPLETE);
|
ChangeState(UPSTREAM_COMPLETE);
|
||||||
}
|
}
|
||||||
|
|
||||||
*countRead = 0;
|
*countRead = 0;
|
||||||
|
|
||||||
// don't change OK to WOULD BLOCK. we are really done sending if OK
|
// don't change OK to WOULD BLOCK. we are really done sending if OK
|
||||||
|
@ -177,7 +177,7 @@ SpdyStream2::WriteSegments(nsAHttpSegmentWriter *writer,
|
||||||
{
|
{
|
||||||
LOG3(("SpdyStream2::WriteSegments %p count=%d state=%x",
|
LOG3(("SpdyStream2::WriteSegments %p count=%d state=%x",
|
||||||
this, count, mUpstreamState));
|
this, count, mUpstreamState));
|
||||||
|
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
MOZ_ASSERT(!mSegmentWriter, "segment writer in progress");
|
MOZ_ASSERT(!mSegmentWriter, "segment writer in progress");
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ SpdyStream2::ParseHttpRequestHeaders(const char *buf,
|
||||||
// We can use the simple double crlf because firefox is the
|
// We can use the simple double crlf because firefox is the
|
||||||
// only client we are parsing
|
// only client we are parsing
|
||||||
int32_t endHeader = mFlatHttpRequestHeaders.Find("\r\n\r\n");
|
int32_t endHeader = mFlatHttpRequestHeaders.Find("\r\n\r\n");
|
||||||
|
|
||||||
if (endHeader == kNotFound) {
|
if (endHeader == kNotFound) {
|
||||||
// We don't have all the headers yet
|
// We don't have all the headers yet
|
||||||
LOG3(("SpdyStream2::ParseHttpRequestHeaders %p "
|
LOG3(("SpdyStream2::ParseHttpRequestHeaders %p "
|
||||||
|
@ -227,7 +227,7 @@ SpdyStream2::ParseHttpRequestHeaders(const char *buf,
|
||||||
*countUsed = avail;
|
*countUsed = avail;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have recvd all the headers, trim the local
|
// We have recvd all the headers, trim the local
|
||||||
// buffer of the final empty line, and set countUsed to reflect
|
// buffer of the final empty line, and set countUsed to reflect
|
||||||
// the whole header has been consumed.
|
// the whole header has been consumed.
|
||||||
|
@ -264,10 +264,10 @@ SpdyStream2::ParseHttpRequestHeaders(const char *buf,
|
||||||
mTxInlineFrame[2] = 0;
|
mTxInlineFrame[2] = 0;
|
||||||
mTxInlineFrame[3] = SpdySession2::CONTROL_TYPE_SYN_STREAM;
|
mTxInlineFrame[3] = SpdySession2::CONTROL_TYPE_SYN_STREAM;
|
||||||
// 4 to 7 are length and flags, we'll fill that in later
|
// 4 to 7 are length and flags, we'll fill that in later
|
||||||
|
|
||||||
uint32_t networkOrderID = PR_htonl(mStreamID);
|
uint32_t networkOrderID = PR_htonl(mStreamID);
|
||||||
memcpy(mTxInlineFrame + 8, &networkOrderID, 4);
|
memcpy(mTxInlineFrame + 8, &networkOrderID, 4);
|
||||||
|
|
||||||
// this is the associated-to field, which is not used sending
|
// this is the associated-to field, which is not used sending
|
||||||
// from the client in the http binding
|
// from the client in the http binding
|
||||||
memset (mTxInlineFrame + 12, 0, 4);
|
memset (mTxInlineFrame + 12, 0, 4);
|
||||||
|
@ -291,7 +291,7 @@ SpdyStream2::ParseHttpRequestHeaders(const char *buf,
|
||||||
mTxInlineFrame[16] = SpdySession2::kPri00;
|
mTxInlineFrame[16] = SpdySession2::kPri00;
|
||||||
|
|
||||||
mTxInlineFrame[17] = 0; /* unused */
|
mTxInlineFrame[17] = 0; /* unused */
|
||||||
|
|
||||||
const char *methodHeader = mTransaction->RequestHead()->Method().get();
|
const char *methodHeader = mTransaction->RequestHead()->Method().get();
|
||||||
|
|
||||||
nsCString hostHeader;
|
nsCString hostHeader;
|
||||||
|
@ -304,12 +304,12 @@ SpdyStream2::ParseHttpRequestHeaders(const char *buf,
|
||||||
versionHeader = NS_LITERAL_CSTRING("HTTP/1.0");
|
versionHeader = NS_LITERAL_CSTRING("HTTP/1.0");
|
||||||
|
|
||||||
nsClassHashtable<nsCStringHashKey, nsCString> hdrHash;
|
nsClassHashtable<nsCStringHashKey, nsCString> hdrHash;
|
||||||
|
|
||||||
// use mRequestHead() to get a sense of how big to make the hash,
|
// use mRequestHead() to get a sense of how big to make the hash,
|
||||||
// even though we are parsing the actual text stream because
|
// even though we are parsing the actual text stream because
|
||||||
// it is legit to append headers.
|
// it is legit to append headers.
|
||||||
hdrHash.Init(1 + (mTransaction->RequestHead()->Headers().Count() * 2));
|
hdrHash.Init(1 + (mTransaction->RequestHead()->Headers().Count() * 2));
|
||||||
|
|
||||||
const char *beginBuffer = mFlatHttpRequestHeaders.BeginReading();
|
const char *beginBuffer = mFlatHttpRequestHeaders.BeginReading();
|
||||||
|
|
||||||
// need to hash all the headers together to remove duplicates, special
|
// need to hash all the headers together to remove duplicates, special
|
||||||
|
@ -322,12 +322,12 @@ SpdyStream2::ParseHttpRequestHeaders(const char *buf,
|
||||||
crlfIndex = mFlatHttpRequestHeaders.Find("\r\n", false, startIndex);
|
crlfIndex = mFlatHttpRequestHeaders.Find("\r\n", false, startIndex);
|
||||||
if (crlfIndex == -1)
|
if (crlfIndex == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
int32_t colonIndex = mFlatHttpRequestHeaders.Find(":", false, startIndex,
|
int32_t colonIndex = mFlatHttpRequestHeaders.Find(":", false, startIndex,
|
||||||
crlfIndex - startIndex);
|
crlfIndex - startIndex);
|
||||||
if (colonIndex == -1)
|
if (colonIndex == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
nsDependentCSubstring name = Substring(beginBuffer + startIndex,
|
nsDependentCSubstring name = Substring(beginBuffer + startIndex,
|
||||||
beginBuffer + colonIndex);
|
beginBuffer + colonIndex);
|
||||||
// all header names are lower case in spdy
|
// all header names are lower case in spdy
|
||||||
|
@ -342,7 +342,7 @@ SpdyStream2::ParseHttpRequestHeaders(const char *buf,
|
||||||
name.Equals("connection") ||
|
name.Equals("connection") ||
|
||||||
name.Equals("url"))
|
name.Equals("url"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
nsCString *val = hdrHash.Get(name);
|
nsCString *val = hdrHash.Get(name);
|
||||||
if (!val) {
|
if (!val) {
|
||||||
val = new nsCString();
|
val = new nsCString();
|
||||||
|
@ -352,7 +352,7 @@ SpdyStream2::ParseHttpRequestHeaders(const char *buf,
|
||||||
int32_t valueIndex = colonIndex + 1;
|
int32_t valueIndex = colonIndex + 1;
|
||||||
while (valueIndex < crlfIndex && beginBuffer[valueIndex] == ' ')
|
while (valueIndex < crlfIndex && beginBuffer[valueIndex] == ' ')
|
||||||
++valueIndex;
|
++valueIndex;
|
||||||
|
|
||||||
nsDependentCSubstring v = Substring(beginBuffer + valueIndex,
|
nsDependentCSubstring v = Substring(beginBuffer + valueIndex,
|
||||||
beginBuffer + crlfIndex);
|
beginBuffer + crlfIndex);
|
||||||
if (!val->IsEmpty())
|
if (!val->IsEmpty())
|
||||||
|
@ -365,7 +365,7 @@ SpdyStream2::ParseHttpRequestHeaders(const char *buf,
|
||||||
mRequestBodyLenRemaining = len;
|
mRequestBodyLenRemaining = len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mTxInlineFrameUsed = 18;
|
mTxInlineFrameUsed = 18;
|
||||||
|
|
||||||
// Do not naively log the request headers here beacuse they might
|
// Do not naively log the request headers here beacuse they might
|
||||||
|
@ -386,17 +386,17 @@ SpdyStream2::ParseHttpRequestHeaders(const char *buf,
|
||||||
CompressToFrame(mTransaction->RequestHead()->RequestURI());
|
CompressToFrame(mTransaction->RequestHead()->RequestURI());
|
||||||
CompressToFrame(NS_LITERAL_CSTRING("version"));
|
CompressToFrame(NS_LITERAL_CSTRING("version"));
|
||||||
CompressToFrame(versionHeader);
|
CompressToFrame(versionHeader);
|
||||||
|
|
||||||
hdrHash.Enumerate(hdrHashEnumerate, this);
|
hdrHash.Enumerate(hdrHashEnumerate, this);
|
||||||
CompressFlushFrame();
|
CompressFlushFrame();
|
||||||
|
|
||||||
// 4 to 7 are length and flags, which we can now fill in
|
// 4 to 7 are length and flags, which we can now fill in
|
||||||
(reinterpret_cast<uint32_t *>(mTxInlineFrame.get()))[1] =
|
(reinterpret_cast<uint32_t *>(mTxInlineFrame.get()))[1] =
|
||||||
PR_htonl(mTxInlineFrameUsed - 8);
|
PR_htonl(mTxInlineFrameUsed - 8);
|
||||||
|
|
||||||
MOZ_ASSERT(!mTxInlineFrame[4],
|
MOZ_ASSERT(!mTxInlineFrame[4],
|
||||||
"Size greater than 24 bits");
|
"Size greater than 24 bits");
|
||||||
|
|
||||||
// Determine whether to put the fin bit on the syn stream frame or whether
|
// Determine whether to put the fin bit on the syn stream frame or whether
|
||||||
// to wait for a data packet to put it on.
|
// to wait for a data packet to put it on.
|
||||||
|
|
||||||
|
@ -421,7 +421,7 @@ SpdyStream2::ParseHttpRequestHeaders(const char *buf,
|
||||||
mSentFinOnData = 1;
|
mSentFinOnData = 1;
|
||||||
mTxInlineFrame[4] = SpdySession2::kFlag_Data_FIN;
|
mTxInlineFrame[4] = SpdySession2::kFlag_Data_FIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SYN_SIZE, mTxInlineFrameUsed - 18);
|
Telemetry::Accumulate(Telemetry::SPDY_SYN_SIZE, mTxInlineFrameUsed - 18);
|
||||||
|
|
||||||
// The size of the input headers is approximate
|
// The size of the input headers is approximate
|
||||||
|
@ -429,7 +429,7 @@ SpdyStream2::ParseHttpRequestHeaders(const char *buf,
|
||||||
(mTxInlineFrameUsed - 18) * 100 /
|
(mTxInlineFrameUsed - 18) * 100 /
|
||||||
(11 + mTransaction->RequestHead()->RequestURI().Length() +
|
(11 + mTransaction->RequestHead()->RequestURI().Length() +
|
||||||
mFlatHttpRequestHeaders.Length());
|
mFlatHttpRequestHeaders.Length());
|
||||||
|
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SYN_RATIO, ratio);
|
Telemetry::Accumulate(Telemetry::SPDY_SYN_RATIO, ratio);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -499,7 +499,7 @@ SpdyStream2::TransmitFrame(const char *buf,
|
||||||
|
|
||||||
uint32_t transmittedCount;
|
uint32_t transmittedCount;
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
LOG3(("SpdyStream2::TransmitFrame %p inline=%d stream=%d",
|
LOG3(("SpdyStream2::TransmitFrame %p inline=%d stream=%d",
|
||||||
this, mTxInlineFrameUsed, mTxStreamFrameSize));
|
this, mTxInlineFrameUsed, mTxStreamFrameSize));
|
||||||
if (countUsed)
|
if (countUsed)
|
||||||
|
@ -536,7 +536,7 @@ SpdyStream2::TransmitFrame(const char *buf,
|
||||||
// bytes through to the SpdySession2 and then the HttpConnection which calls
|
// bytes through to the SpdySession2 and then the HttpConnection which calls
|
||||||
// the socket write function. It will accept all of the inline and stream
|
// the socket write function. It will accept all of the inline and stream
|
||||||
// data because of the above 'commitment' even if it has to buffer
|
// data because of the above 'commitment' even if it has to buffer
|
||||||
|
|
||||||
rv = mSegmentReader->OnReadSegment(mTxInlineFrame, mTxInlineFrameUsed,
|
rv = mSegmentReader->OnReadSegment(mTxInlineFrame, mTxInlineFrameUsed,
|
||||||
&transmittedCount);
|
&transmittedCount);
|
||||||
LOG3(("SpdyStream2::TransmitFrame for inline session=%p "
|
LOG3(("SpdyStream2::TransmitFrame for inline session=%p "
|
||||||
|
@ -551,7 +551,7 @@ SpdyStream2::TransmitFrame(const char *buf,
|
||||||
|
|
||||||
MOZ_ASSERT(transmittedCount == mTxInlineFrameUsed,
|
MOZ_ASSERT(transmittedCount == mTxInlineFrameUsed,
|
||||||
"inconsistent inline commitment count");
|
"inconsistent inline commitment count");
|
||||||
|
|
||||||
SpdySession2::LogIO(mSession, this, "Writing from Inline Buffer",
|
SpdySession2::LogIO(mSession, this, "Writing from Inline Buffer",
|
||||||
mTxInlineFrame, transmittedCount);
|
mTxInlineFrame, transmittedCount);
|
||||||
|
|
||||||
|
@ -570,7 +570,7 @@ SpdyStream2::TransmitFrame(const char *buf,
|
||||||
LOG3(("SpdyStream2::TransmitFrame for regular session=%p "
|
LOG3(("SpdyStream2::TransmitFrame for regular session=%p "
|
||||||
"stream=%p result %x len=%d",
|
"stream=%p result %x len=%d",
|
||||||
mSession, this, rv, transmittedCount));
|
mSession, this, rv, transmittedCount));
|
||||||
|
|
||||||
MOZ_ASSERT(rv != NS_BASE_STREAM_WOULD_BLOCK,
|
MOZ_ASSERT(rv != NS_BASE_STREAM_WOULD_BLOCK,
|
||||||
"inconsistent stream commitment result");
|
"inconsistent stream commitment result");
|
||||||
|
|
||||||
|
@ -579,13 +579,13 @@ SpdyStream2::TransmitFrame(const char *buf,
|
||||||
|
|
||||||
MOZ_ASSERT(transmittedCount == mTxStreamFrameSize,
|
MOZ_ASSERT(transmittedCount == mTxStreamFrameSize,
|
||||||
"inconsistent stream commitment count");
|
"inconsistent stream commitment count");
|
||||||
|
|
||||||
SpdySession2::LogIO(mSession, this, "Writing from Transaction Buffer",
|
SpdySession2::LogIO(mSession, this, "Writing from Transaction Buffer",
|
||||||
buf, transmittedCount);
|
buf, transmittedCount);
|
||||||
|
|
||||||
*countUsed += mTxStreamFrameSize;
|
*countUsed += mTxStreamFrameSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// calling this will trigger waiting_for if mRequestBodyLenRemaining is 0
|
// calling this will trigger waiting_for if mRequestBodyLenRemaining is 0
|
||||||
UpdateTransportSendEvents(mTxInlineFrameUsed + mTxStreamFrameSize);
|
UpdateTransportSendEvents(mTxInlineFrameUsed + mTxStreamFrameSize);
|
||||||
|
|
||||||
|
@ -614,14 +614,14 @@ SpdyStream2::GenerateDataFrameHeader(uint32_t dataLength, bool lastFrame)
|
||||||
MOZ_ASSERT(!mTxInlineFrameUsed, "inline frame not empty");
|
MOZ_ASSERT(!mTxInlineFrameUsed, "inline frame not empty");
|
||||||
MOZ_ASSERT(!mTxStreamFrameSize, "stream frame not empty");
|
MOZ_ASSERT(!mTxStreamFrameSize, "stream frame not empty");
|
||||||
MOZ_ASSERT(!(dataLength & 0xff000000), "datalength > 24 bits");
|
MOZ_ASSERT(!(dataLength & 0xff000000), "datalength > 24 bits");
|
||||||
|
|
||||||
(reinterpret_cast<uint32_t *>(mTxInlineFrame.get()))[0] = PR_htonl(mStreamID);
|
(reinterpret_cast<uint32_t *>(mTxInlineFrame.get()))[0] = PR_htonl(mStreamID);
|
||||||
(reinterpret_cast<uint32_t *>(mTxInlineFrame.get()))[1] =
|
(reinterpret_cast<uint32_t *>(mTxInlineFrame.get()))[1] =
|
||||||
PR_htonl(dataLength);
|
PR_htonl(dataLength);
|
||||||
|
|
||||||
MOZ_ASSERT(!(mTxInlineFrame[0] & 0x80), "control bit set unexpectedly");
|
MOZ_ASSERT(!(mTxInlineFrame[0] & 0x80), "control bit set unexpectedly");
|
||||||
MOZ_ASSERT(!mTxInlineFrame[4], "flag bits set unexpectedly");
|
MOZ_ASSERT(!mTxInlineFrame[4], "flag bits set unexpectedly");
|
||||||
|
|
||||||
mTxInlineFrameUsed = 8;
|
mTxInlineFrameUsed = 8;
|
||||||
mTxStreamFrameSize = dataLength;
|
mTxStreamFrameSize = dataLength;
|
||||||
|
|
||||||
|
@ -645,7 +645,7 @@ SpdyStream2::CompressToFrame(const nsACString *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dictionary taken from
|
// Dictionary taken from
|
||||||
// http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft2
|
// http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft2
|
||||||
// Name/Value Header Block Format
|
// Name/Value Header Block Format
|
||||||
// spec indicates that the compression dictionary is not null terminated
|
// spec indicates that the compression dictionary is not null terminated
|
||||||
// but in reality it is. see:
|
// but in reality it is. see:
|
||||||
|
@ -710,7 +710,7 @@ SpdyStream2::CompressToFrame(uint16_t data)
|
||||||
{
|
{
|
||||||
// convert the data to network byte order and write that
|
// convert the data to network byte order and write that
|
||||||
// to the compressed stream
|
// to the compressed stream
|
||||||
|
|
||||||
data = PR_htons(data);
|
data = PR_htons(data);
|
||||||
|
|
||||||
mZlib->next_in = reinterpret_cast<unsigned char *> (&data);
|
mZlib->next_in = reinterpret_cast<unsigned char *> (&data);
|
||||||
|
@ -731,12 +731,12 @@ SpdyStream2::CompressToFrame(const char *data, uint32_t len)
|
||||||
len = 0xffff;
|
len = 0xffff;
|
||||||
|
|
||||||
uint16_t networkLen = PR_htons(len);
|
uint16_t networkLen = PR_htons(len);
|
||||||
|
|
||||||
// write out the length
|
// write out the length
|
||||||
mZlib->next_in = reinterpret_cast<unsigned char *> (&networkLen);
|
mZlib->next_in = reinterpret_cast<unsigned char *> (&networkLen);
|
||||||
mZlib->avail_in = 2;
|
mZlib->avail_in = 2;
|
||||||
ExecuteCompress(Z_NO_FLUSH);
|
ExecuteCompress(Z_NO_FLUSH);
|
||||||
|
|
||||||
// write out the data
|
// write out the data
|
||||||
mZlib->next_in = (unsigned char *)data;
|
mZlib->next_in = (unsigned char *)data;
|
||||||
mZlib->avail_in = len;
|
mZlib->avail_in = len;
|
||||||
|
@ -771,7 +771,7 @@ SpdyStream2::OnReadSegment(const char *buf,
|
||||||
|
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
MOZ_ASSERT(mSegmentReader);
|
MOZ_ASSERT(mSegmentReader);
|
||||||
|
|
||||||
nsresult rv = NS_ERROR_UNEXPECTED;
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
||||||
uint32_t dataLength;
|
uint32_t dataLength;
|
||||||
|
|
||||||
|
@ -840,12 +840,12 @@ SpdyStream2::OnReadSegment(const char *buf,
|
||||||
case SENDING_FIN_STREAM:
|
case SENDING_FIN_STREAM:
|
||||||
MOZ_ASSERT(false, "resuming partial fin stream out of OnReadSegment");
|
MOZ_ASSERT(false, "resuming partial fin stream out of OnReadSegment");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
MOZ_ASSERT(false, "SpdyStream2::OnReadSegment non-write state");
|
MOZ_ASSERT(false, "SpdyStream2::OnReadSegment non-write state");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
|
|
||||||
// returns false if called more than once
|
// returns false if called more than once
|
||||||
bool GetFullyOpen() {return mFullyOpen;}
|
bool GetFullyOpen() {return mFullyOpen;}
|
||||||
void SetFullyOpen()
|
void SetFullyOpen()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!mFullyOpen);
|
MOZ_ASSERT(!mFullyOpen);
|
||||||
mFullyOpen = 1;
|
mFullyOpen = 1;
|
||||||
|
@ -93,7 +93,7 @@ private:
|
||||||
void CompressToFrame(uint16_t);
|
void CompressToFrame(uint16_t);
|
||||||
void CompressFlushFrame();
|
void CompressFlushFrame();
|
||||||
void ExecuteCompress(uint32_t);
|
void ExecuteCompress(uint32_t);
|
||||||
|
|
||||||
// Each stream goes from syn_stream to upstream_complete, perhaps
|
// Each stream goes from syn_stream to upstream_complete, perhaps
|
||||||
// looping on multiple instances of generating_request_body and
|
// looping on multiple instances of generating_request_body and
|
||||||
// sending_request_body for each SPDY chunk in the upload.
|
// sending_request_body for each SPDY chunk in the upload.
|
||||||
|
|
|
@ -89,7 +89,7 @@ SpdyStream3::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
this, reader, count, mUpstreamState));
|
this, reader, count, mUpstreamState));
|
||||||
|
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
|
|
||||||
nsresult rv = NS_ERROR_UNEXPECTED;
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
||||||
mRequestBlockedOnRead = 0;
|
mRequestBlockedOnRead = 0;
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ SpdyStream3::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
mUpstreamState == GENERATING_SYN_STREAM &&
|
mUpstreamState == GENERATING_SYN_STREAM &&
|
||||||
!mSynFrameComplete)
|
!mSynFrameComplete)
|
||||||
mSession->TransactionHasDataToWrite(this);
|
mSession->TransactionHasDataToWrite(this);
|
||||||
|
|
||||||
// mTxinlineFrameUsed represents any queued un-sent frame. It might
|
// mTxinlineFrameUsed represents any queued un-sent frame. It might
|
||||||
// be 0 if there is no such frame, which is not a gurantee that we
|
// be 0 if there is no such frame, which is not a gurantee that we
|
||||||
// don't have more request body to send - just that any data that was
|
// don't have more request body to send - just that any data that was
|
||||||
|
@ -157,7 +157,7 @@ SpdyStream3::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
mTxInlineFrameUsed = 0; // cancel fin data packet
|
mTxInlineFrameUsed = 0; // cancel fin data packet
|
||||||
ChangeState(UPSTREAM_COMPLETE);
|
ChangeState(UPSTREAM_COMPLETE);
|
||||||
}
|
}
|
||||||
|
|
||||||
*countRead = 0;
|
*countRead = 0;
|
||||||
|
|
||||||
// don't change OK to WOULD BLOCK. we are really done sending if OK
|
// don't change OK to WOULD BLOCK. we are really done sending if OK
|
||||||
|
@ -188,7 +188,7 @@ SpdyStream3::WriteSegments(nsAHttpSegmentWriter *writer,
|
||||||
{
|
{
|
||||||
LOG3(("SpdyStream3::WriteSegments %p count=%d state=%x",
|
LOG3(("SpdyStream3::WriteSegments %p count=%d state=%x",
|
||||||
this, count, mUpstreamState));
|
this, count, mUpstreamState));
|
||||||
|
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
MOZ_ASSERT(!mSegmentWriter, "segment writer in progress");
|
MOZ_ASSERT(!mSegmentWriter, "segment writer in progress");
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ SpdyStream3::ParseHttpRequestHeaders(const char *buf,
|
||||||
// We can use the simple double crlf because firefox is the
|
// We can use the simple double crlf because firefox is the
|
||||||
// only client we are parsing
|
// only client we are parsing
|
||||||
int32_t endHeader = mFlatHttpRequestHeaders.Find("\r\n\r\n");
|
int32_t endHeader = mFlatHttpRequestHeaders.Find("\r\n\r\n");
|
||||||
|
|
||||||
if (endHeader == kNotFound) {
|
if (endHeader == kNotFound) {
|
||||||
// We don't have all the headers yet
|
// We don't have all the headers yet
|
||||||
LOG3(("SpdyStream3::ParseHttpRequestHeaders %p "
|
LOG3(("SpdyStream3::ParseHttpRequestHeaders %p "
|
||||||
|
@ -238,7 +238,7 @@ SpdyStream3::ParseHttpRequestHeaders(const char *buf,
|
||||||
*countUsed = avail;
|
*countUsed = avail;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have recvd all the headers, trim the local
|
// We have recvd all the headers, trim the local
|
||||||
// buffer of the final empty line, and set countUsed to reflect
|
// buffer of the final empty line, and set countUsed to reflect
|
||||||
// the whole header has been consumed.
|
// the whole header has been consumed.
|
||||||
|
@ -274,10 +274,10 @@ SpdyStream3::ParseHttpRequestHeaders(const char *buf,
|
||||||
mTxInlineFrame[2] = 0;
|
mTxInlineFrame[2] = 0;
|
||||||
mTxInlineFrame[3] = SpdySession3::CONTROL_TYPE_SYN_STREAM;
|
mTxInlineFrame[3] = SpdySession3::CONTROL_TYPE_SYN_STREAM;
|
||||||
// 4 to 7 are length and flags, we'll fill that in later
|
// 4 to 7 are length and flags, we'll fill that in later
|
||||||
|
|
||||||
uint32_t networkOrderID = PR_htonl(mStreamID);
|
uint32_t networkOrderID = PR_htonl(mStreamID);
|
||||||
memcpy(mTxInlineFrame + 8, &networkOrderID, 4);
|
memcpy(mTxInlineFrame + 8, &networkOrderID, 4);
|
||||||
|
|
||||||
// this is the associated-to field, which is not used sending
|
// this is the associated-to field, which is not used sending
|
||||||
// from the client in the http binding
|
// from the client in the http binding
|
||||||
memset (mTxInlineFrame + 12, 0, 4);
|
memset (mTxInlineFrame + 12, 0, 4);
|
||||||
|
@ -285,7 +285,7 @@ SpdyStream3::ParseHttpRequestHeaders(const char *buf,
|
||||||
// Priority flags are the E0 mask of byte 16.
|
// Priority flags are the E0 mask of byte 16.
|
||||||
// 0 is highest priority, 7 is lowest.
|
// 0 is highest priority, 7 is lowest.
|
||||||
// The other 5 bits of byte 16 are unused.
|
// The other 5 bits of byte 16 are unused.
|
||||||
|
|
||||||
if (mPriority >= nsISupportsPriority::PRIORITY_LOWEST)
|
if (mPriority >= nsISupportsPriority::PRIORITY_LOWEST)
|
||||||
mTxInlineFrame[16] = 7 << 5;
|
mTxInlineFrame[16] = 7 << 5;
|
||||||
else if (mPriority <= nsISupportsPriority::PRIORITY_HIGHEST)
|
else if (mPriority <= nsISupportsPriority::PRIORITY_HIGHEST)
|
||||||
|
@ -299,7 +299,7 @@ SpdyStream3::ParseHttpRequestHeaders(const char *buf,
|
||||||
// Add one to the priority so that values such as -10 and -11
|
// Add one to the priority so that values such as -10 and -11
|
||||||
// get different spdy priorities - this appears to be an important
|
// get different spdy priorities - this appears to be an important
|
||||||
// breaking line in the priorities content assigns to
|
// breaking line in the priorities content assigns to
|
||||||
// transactions.
|
// transactions.
|
||||||
uint8_t calculatedPriority = 3 + ((mPriority + 1) / 5);
|
uint8_t calculatedPriority = 3 + ((mPriority + 1) / 5);
|
||||||
MOZ_ASSERT (!(calculatedPriority & 0xf8),
|
MOZ_ASSERT (!(calculatedPriority & 0xf8),
|
||||||
"Calculated Priority Out Of Range");
|
"Calculated Priority Out Of Range");
|
||||||
|
@ -308,7 +308,7 @@ SpdyStream3::ParseHttpRequestHeaders(const char *buf,
|
||||||
|
|
||||||
// The client cert "slot". Right now we don't send client certs
|
// The client cert "slot". Right now we don't send client certs
|
||||||
mTxInlineFrame[17] = 0;
|
mTxInlineFrame[17] = 0;
|
||||||
|
|
||||||
const char *methodHeader = mTransaction->RequestHead()->Method().get();
|
const char *methodHeader = mTransaction->RequestHead()->Method().get();
|
||||||
|
|
||||||
nsCString hostHeader;
|
nsCString hostHeader;
|
||||||
|
@ -321,12 +321,12 @@ SpdyStream3::ParseHttpRequestHeaders(const char *buf,
|
||||||
versionHeader = NS_LITERAL_CSTRING("HTTP/1.0");
|
versionHeader = NS_LITERAL_CSTRING("HTTP/1.0");
|
||||||
|
|
||||||
nsClassHashtable<nsCStringHashKey, nsCString> hdrHash;
|
nsClassHashtable<nsCStringHashKey, nsCString> hdrHash;
|
||||||
|
|
||||||
// use mRequestHead() to get a sense of how big to make the hash,
|
// use mRequestHead() to get a sense of how big to make the hash,
|
||||||
// even though we are parsing the actual text stream because
|
// even though we are parsing the actual text stream because
|
||||||
// it is legit to append headers.
|
// it is legit to append headers.
|
||||||
hdrHash.Init(1 + (mTransaction->RequestHead()->Headers().Count() * 2));
|
hdrHash.Init(1 + (mTransaction->RequestHead()->Headers().Count() * 2));
|
||||||
|
|
||||||
const char *beginBuffer = mFlatHttpRequestHeaders.BeginReading();
|
const char *beginBuffer = mFlatHttpRequestHeaders.BeginReading();
|
||||||
|
|
||||||
// need to hash all the headers together to remove duplicates, special
|
// need to hash all the headers together to remove duplicates, special
|
||||||
|
@ -339,12 +339,12 @@ SpdyStream3::ParseHttpRequestHeaders(const char *buf,
|
||||||
crlfIndex = mFlatHttpRequestHeaders.Find("\r\n", false, startIndex);
|
crlfIndex = mFlatHttpRequestHeaders.Find("\r\n", false, startIndex);
|
||||||
if (crlfIndex == -1)
|
if (crlfIndex == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
int32_t colonIndex = mFlatHttpRequestHeaders.Find(":", false, startIndex,
|
int32_t colonIndex = mFlatHttpRequestHeaders.Find(":", false, startIndex,
|
||||||
crlfIndex - startIndex);
|
crlfIndex - startIndex);
|
||||||
if (colonIndex == -1)
|
if (colonIndex == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
nsDependentCSubstring name = Substring(beginBuffer + startIndex,
|
nsDependentCSubstring name = Substring(beginBuffer + startIndex,
|
||||||
beginBuffer + colonIndex);
|
beginBuffer + colonIndex);
|
||||||
// all header names are lower case in spdy
|
// all header names are lower case in spdy
|
||||||
|
@ -368,7 +368,7 @@ SpdyStream3::ParseHttpRequestHeaders(const char *buf,
|
||||||
int32_t valueIndex = colonIndex + 1;
|
int32_t valueIndex = colonIndex + 1;
|
||||||
while (valueIndex < crlfIndex && beginBuffer[valueIndex] == ' ')
|
while (valueIndex < crlfIndex && beginBuffer[valueIndex] == ' ')
|
||||||
++valueIndex;
|
++valueIndex;
|
||||||
|
|
||||||
nsDependentCSubstring v = Substring(beginBuffer + valueIndex,
|
nsDependentCSubstring v = Substring(beginBuffer + valueIndex,
|
||||||
beginBuffer + crlfIndex);
|
beginBuffer + crlfIndex);
|
||||||
if (!val->IsEmpty())
|
if (!val->IsEmpty())
|
||||||
|
@ -381,7 +381,7 @@ SpdyStream3::ParseHttpRequestHeaders(const char *buf,
|
||||||
mRequestBodyLenRemaining = len;
|
mRequestBodyLenRemaining = len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mTxInlineFrameUsed = 18;
|
mTxInlineFrameUsed = 18;
|
||||||
|
|
||||||
// Do not naively log the request headers here beacuse they might
|
// Do not naively log the request headers here beacuse they might
|
||||||
|
@ -408,13 +408,13 @@ SpdyStream3::ParseHttpRequestHeaders(const char *buf,
|
||||||
|
|
||||||
hdrHash.Enumerate(hdrHashEnumerate, this);
|
hdrHash.Enumerate(hdrHashEnumerate, this);
|
||||||
CompressFlushFrame();
|
CompressFlushFrame();
|
||||||
|
|
||||||
// 4 to 7 are length and flags, which we can now fill in
|
// 4 to 7 are length and flags, which we can now fill in
|
||||||
(reinterpret_cast<uint32_t *>(mTxInlineFrame.get()))[1] =
|
(reinterpret_cast<uint32_t *>(mTxInlineFrame.get()))[1] =
|
||||||
PR_htonl(mTxInlineFrameUsed - 8);
|
PR_htonl(mTxInlineFrameUsed - 8);
|
||||||
|
|
||||||
MOZ_ASSERT(!mTxInlineFrame[4], "Size greater than 24 bits");
|
MOZ_ASSERT(!mTxInlineFrame[4], "Size greater than 24 bits");
|
||||||
|
|
||||||
// Determine whether to put the fin bit on the syn stream frame or whether
|
// Determine whether to put the fin bit on the syn stream frame or whether
|
||||||
// to wait for a data packet to put it on.
|
// to wait for a data packet to put it on.
|
||||||
|
|
||||||
|
@ -439,7 +439,7 @@ SpdyStream3::ParseHttpRequestHeaders(const char *buf,
|
||||||
mSentFinOnData = 1;
|
mSentFinOnData = 1;
|
||||||
mTxInlineFrame[4] = SpdySession3::kFlag_Data_FIN;
|
mTxInlineFrame[4] = SpdySession3::kFlag_Data_FIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SYN_SIZE, mTxInlineFrameUsed - 18);
|
Telemetry::Accumulate(Telemetry::SPDY_SYN_SIZE, mTxInlineFrameUsed - 18);
|
||||||
|
|
||||||
// The size of the input headers is approximate
|
// The size of the input headers is approximate
|
||||||
|
@ -447,7 +447,7 @@ SpdyStream3::ParseHttpRequestHeaders(const char *buf,
|
||||||
(mTxInlineFrameUsed - 18) * 100 /
|
(mTxInlineFrameUsed - 18) * 100 /
|
||||||
(11 + mTransaction->RequestHead()->RequestURI().Length() +
|
(11 + mTransaction->RequestHead()->RequestURI().Length() +
|
||||||
mFlatHttpRequestHeaders.Length());
|
mFlatHttpRequestHeaders.Length());
|
||||||
|
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_SYN_RATIO, ratio);
|
Telemetry::Accumulate(Telemetry::SPDY_SYN_RATIO, ratio);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -517,7 +517,7 @@ SpdyStream3::TransmitFrame(const char *buf,
|
||||||
|
|
||||||
uint32_t transmittedCount;
|
uint32_t transmittedCount;
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
LOG3(("SpdyStream3::TransmitFrame %p inline=%d stream=%d",
|
LOG3(("SpdyStream3::TransmitFrame %p inline=%d stream=%d",
|
||||||
this, mTxInlineFrameUsed, mTxStreamFrameSize));
|
this, mTxInlineFrameUsed, mTxStreamFrameSize));
|
||||||
if (countUsed)
|
if (countUsed)
|
||||||
|
@ -590,7 +590,7 @@ SpdyStream3::TransmitFrame(const char *buf,
|
||||||
LOG3(("SpdyStream3::TransmitFrame for regular session=%p "
|
LOG3(("SpdyStream3::TransmitFrame for regular session=%p "
|
||||||
"stream=%p result %x len=%d",
|
"stream=%p result %x len=%d",
|
||||||
mSession, this, rv, transmittedCount));
|
mSession, this, rv, transmittedCount));
|
||||||
|
|
||||||
MOZ_ASSERT(rv != NS_BASE_STREAM_WOULD_BLOCK,
|
MOZ_ASSERT(rv != NS_BASE_STREAM_WOULD_BLOCK,
|
||||||
"inconsistent stream commitment result");
|
"inconsistent stream commitment result");
|
||||||
|
|
||||||
|
@ -599,13 +599,13 @@ SpdyStream3::TransmitFrame(const char *buf,
|
||||||
|
|
||||||
MOZ_ASSERT(transmittedCount == mTxStreamFrameSize,
|
MOZ_ASSERT(transmittedCount == mTxStreamFrameSize,
|
||||||
"inconsistent stream commitment count");
|
"inconsistent stream commitment count");
|
||||||
|
|
||||||
SpdySession3::LogIO(mSession, this, "Writing from Transaction Buffer",
|
SpdySession3::LogIO(mSession, this, "Writing from Transaction Buffer",
|
||||||
buf, transmittedCount);
|
buf, transmittedCount);
|
||||||
|
|
||||||
*countUsed += mTxStreamFrameSize;
|
*countUsed += mTxStreamFrameSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// calling this will trigger waiting_for if mRequestBodyLenRemaining is 0
|
// calling this will trigger waiting_for if mRequestBodyLenRemaining is 0
|
||||||
UpdateTransportSendEvents(mTxInlineFrameUsed + mTxStreamFrameSize);
|
UpdateTransportSendEvents(mTxInlineFrameUsed + mTxStreamFrameSize);
|
||||||
|
|
||||||
|
@ -634,14 +634,14 @@ SpdyStream3::GenerateDataFrameHeader(uint32_t dataLength, bool lastFrame)
|
||||||
MOZ_ASSERT(!mTxInlineFrameUsed, "inline frame not empty");
|
MOZ_ASSERT(!mTxInlineFrameUsed, "inline frame not empty");
|
||||||
MOZ_ASSERT(!mTxStreamFrameSize, "stream frame not empty");
|
MOZ_ASSERT(!mTxStreamFrameSize, "stream frame not empty");
|
||||||
MOZ_ASSERT(!(dataLength & 0xff000000), "datalength > 24 bits");
|
MOZ_ASSERT(!(dataLength & 0xff000000), "datalength > 24 bits");
|
||||||
|
|
||||||
(reinterpret_cast<uint32_t *>(mTxInlineFrame.get()))[0] = PR_htonl(mStreamID);
|
(reinterpret_cast<uint32_t *>(mTxInlineFrame.get()))[0] = PR_htonl(mStreamID);
|
||||||
(reinterpret_cast<uint32_t *>(mTxInlineFrame.get()))[1] =
|
(reinterpret_cast<uint32_t *>(mTxInlineFrame.get()))[1] =
|
||||||
PR_htonl(dataLength);
|
PR_htonl(dataLength);
|
||||||
|
|
||||||
MOZ_ASSERT(!(mTxInlineFrame[0] & 0x80), "control bit set unexpectedly");
|
MOZ_ASSERT(!(mTxInlineFrame[0] & 0x80), "control bit set unexpectedly");
|
||||||
MOZ_ASSERT(!mTxInlineFrame[4], "flag bits set unexpectedly");
|
MOZ_ASSERT(!mTxInlineFrame[4], "flag bits set unexpectedly");
|
||||||
|
|
||||||
mTxInlineFrameUsed = 8;
|
mTxInlineFrameUsed = 8;
|
||||||
mTxStreamFrameSize = dataLength;
|
mTxStreamFrameSize = dataLength;
|
||||||
|
|
||||||
|
@ -885,11 +885,11 @@ SpdyStream3::Uncompress(z_stream *context,
|
||||||
LOG3(("SpdySession3::Uncompress %p Dictionary Error\n", this));
|
LOG3(("SpdySession3::Uncompress %p Dictionary Error\n", this));
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
triedDictionary = true;
|
triedDictionary = true;
|
||||||
inflateSetDictionary(context, kDictionary, sizeof(kDictionary));
|
inflateSetDictionary(context, kDictionary, sizeof(kDictionary));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zlib_rv == Z_DATA_ERROR || zlib_rv == Z_MEM_ERROR)
|
if (zlib_rv == Z_DATA_ERROR || zlib_rv == Z_MEM_ERROR)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
@ -898,7 +898,7 @@ SpdyStream3::Uncompress(z_stream *context,
|
||||||
|
|
||||||
mDecompressBufferUsed += mDecompressBufferSize - mDecompressBufferUsed -
|
mDecompressBufferUsed += mDecompressBufferSize - mDecompressBufferUsed -
|
||||||
context->avail_out;
|
context->avail_out;
|
||||||
|
|
||||||
// When there is no more output room, but input still available then
|
// When there is no more output room, but input still available then
|
||||||
// increase the output space
|
// increase the output space
|
||||||
if (zlib_rv == Z_OK &&
|
if (zlib_rv == Z_OK &&
|
||||||
|
@ -985,7 +985,7 @@ SpdyStream3::ConvertHeaders(nsACString &aHeadersOut)
|
||||||
|
|
||||||
// Content-Length is 'advisory'.. we will not strip it because it can
|
// Content-Length is 'advisory'.. we will not strip it because it can
|
||||||
// create UI feedback.
|
// create UI feedback.
|
||||||
|
|
||||||
aHeadersOut.Append(version);
|
aHeadersOut.Append(version);
|
||||||
aHeadersOut.Append(NS_LITERAL_CSTRING(" "));
|
aHeadersOut.Append(NS_LITERAL_CSTRING(" "));
|
||||||
aHeadersOut.Append(status);
|
aHeadersOut.Append(status);
|
||||||
|
@ -1147,12 +1147,12 @@ SpdyStream3::CompressToFrame(const char *data, uint32_t len)
|
||||||
// followed by the utf8 string
|
// followed by the utf8 string
|
||||||
|
|
||||||
uint32_t networkLen = PR_htonl(len);
|
uint32_t networkLen = PR_htonl(len);
|
||||||
|
|
||||||
// write out the length
|
// write out the length
|
||||||
mZlib->next_in = reinterpret_cast<unsigned char *> (&networkLen);
|
mZlib->next_in = reinterpret_cast<unsigned char *> (&networkLen);
|
||||||
mZlib->avail_in = 4;
|
mZlib->avail_in = 4;
|
||||||
ExecuteCompress(Z_NO_FLUSH);
|
ExecuteCompress(Z_NO_FLUSH);
|
||||||
|
|
||||||
// write out the data
|
// write out the data
|
||||||
mZlib->next_in = (unsigned char *)data;
|
mZlib->next_in = (unsigned char *)data;
|
||||||
mZlib->avail_in = len;
|
mZlib->avail_in = len;
|
||||||
|
@ -1187,7 +1187,7 @@ SpdyStream3::OnReadSegment(const char *buf,
|
||||||
|
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
MOZ_ASSERT(mSegmentReader, "OnReadSegment with null mSegmentReader");
|
MOZ_ASSERT(mSegmentReader, "OnReadSegment with null mSegmentReader");
|
||||||
|
|
||||||
nsresult rv = NS_ERROR_UNEXPECTED;
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
||||||
uint32_t dataLength;
|
uint32_t dataLength;
|
||||||
|
|
||||||
|
@ -1235,7 +1235,7 @@ SpdyStream3::OnReadSegment(const char *buf,
|
||||||
if (dataLength > mRemoteWindow)
|
if (dataLength > mRemoteWindow)
|
||||||
dataLength = static_cast<uint32_t>(mRemoteWindow);
|
dataLength = static_cast<uint32_t>(mRemoteWindow);
|
||||||
|
|
||||||
LOG3(("SpdyStream3 this=%p id 0x%X remote window is %d. Chunk is %d\n",
|
LOG3(("SpdyStream3 this=%p id 0x%X remote window is %d. Chunk is %d\n",
|
||||||
this, mStreamID, mRemoteWindow, dataLength));
|
this, mStreamID, mRemoteWindow, dataLength));
|
||||||
mRemoteWindow -= dataLength;
|
mRemoteWindow -= dataLength;
|
||||||
|
|
||||||
|
@ -1273,12 +1273,12 @@ SpdyStream3::OnReadSegment(const char *buf,
|
||||||
case SENDING_FIN_STREAM:
|
case SENDING_FIN_STREAM:
|
||||||
MOZ_ASSERT(false, "resuming partial fin stream out of OnReadSegment");
|
MOZ_ASSERT(false, "resuming partial fin stream out of OnReadSegment");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
MOZ_ASSERT(false, "SpdyStream3::OnReadSegment non-write state");
|
MOZ_ASSERT(false, "SpdyStream3::OnReadSegment non-write state");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ public:
|
||||||
|
|
||||||
// returns false if called more than once
|
// returns false if called more than once
|
||||||
bool GetFullyOpen() {return mFullyOpen;}
|
bool GetFullyOpen() {return mFullyOpen;}
|
||||||
void SetFullyOpen()
|
void SetFullyOpen()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!mFullyOpen);
|
MOZ_ASSERT(!mFullyOpen);
|
||||||
mFullyOpen = 1;
|
mFullyOpen = 1;
|
||||||
|
@ -115,7 +115,7 @@ private:
|
||||||
void CompressFlushFrame();
|
void CompressFlushFrame();
|
||||||
void ExecuteCompress(uint32_t);
|
void ExecuteCompress(uint32_t);
|
||||||
nsresult FindHeader(nsCString, nsDependentCSubstring &);
|
nsresult FindHeader(nsCString, nsDependentCSubstring &);
|
||||||
|
|
||||||
// Each stream goes from syn_stream to upstream_complete, perhaps
|
// Each stream goes from syn_stream to upstream_complete, perhaps
|
||||||
// looping on multiple instances of generating_request_body and
|
// looping on multiple instances of generating_request_body and
|
||||||
// sending_request_body for each SPDY chunk in the upload.
|
// sending_request_body for each SPDY chunk in the upload.
|
||||||
|
|
|
@ -64,7 +64,7 @@ public:
|
||||||
|
|
||||||
// called to indicate a failure with proxy CONNECT
|
// called to indicate a failure with proxy CONNECT
|
||||||
virtual void SetProxyConnectFailed() = 0;
|
virtual void SetProxyConnectFailed() = 0;
|
||||||
|
|
||||||
// called to retrieve the request headers of the transaction
|
// called to retrieve the request headers of the transaction
|
||||||
virtual nsHttpRequestHead *RequestHead() = 0;
|
virtual nsHttpRequestHead *RequestHead() = 0;
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ public:
|
||||||
// classes that do not implement sub transactions
|
// classes that do not implement sub transactions
|
||||||
// return NS_ERROR_NOT_IMPLEMENTED
|
// return NS_ERROR_NOT_IMPLEMENTED
|
||||||
virtual nsresult AddTransaction(nsAHttpTransaction *transaction) = 0;
|
virtual nsresult AddTransaction(nsAHttpTransaction *transaction) = 0;
|
||||||
|
|
||||||
// The total length of the outstanding pipeline comprised of transacations
|
// The total length of the outstanding pipeline comprised of transacations
|
||||||
// and sub-transactions.
|
// and sub-transactions.
|
||||||
virtual uint32_t PipelineDepth() = 0;
|
virtual uint32_t PipelineDepth() = 0;
|
||||||
|
@ -109,7 +109,7 @@ public:
|
||||||
// A null transaction is expected to return BASE_STREAM_CLOSED on all of
|
// A null transaction is expected to return BASE_STREAM_CLOSED on all of
|
||||||
// its IO functions all the time.
|
// its IO functions all the time.
|
||||||
virtual bool IsNullTransaction() { return false; }
|
virtual bool IsNullTransaction() { return false; }
|
||||||
|
|
||||||
// Every transaction is classified into one of the types below. When using
|
// Every transaction is classified into one of the types below. When using
|
||||||
// HTTP pipelines, only transactions with the same type appear on the same
|
// HTTP pipelines, only transactions with the same type appear on the same
|
||||||
// pipeline.
|
// pipeline.
|
||||||
|
@ -123,7 +123,7 @@ public:
|
||||||
// Transactions for content expected to be an image
|
// Transactions for content expected to be an image
|
||||||
CLASS_IMAGE,
|
CLASS_IMAGE,
|
||||||
|
|
||||||
// Transactions that cannot involve a pipeline
|
// Transactions that cannot involve a pipeline
|
||||||
CLASS_SOLO,
|
CLASS_SOLO,
|
||||||
|
|
||||||
// Transactions that do not fit any of the other categories. HTML
|
// Transactions that do not fit any of the other categories. HTML
|
||||||
|
|
|
@ -126,7 +126,7 @@ nsHttp::CreateAtomTable()
|
||||||
(PL_DHashTableOperate(&sAtomTable, atoms[i], PL_DHASH_ADD));
|
(PL_DHashTableOperate(&sAtomTable, atoms[i], PL_DHASH_ADD));
|
||||||
if (!stub)
|
if (!stub)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
MOZ_ASSERT(!stub->key, "duplicate static atom");
|
MOZ_ASSERT(!stub->key, "duplicate static atom");
|
||||||
stub->key = atoms[i];
|
stub->key = atoms[i];
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
/******
|
/******
|
||||||
This file contains the list of all HTTP atoms
|
This file contains the list of all HTTP atoms
|
||||||
See nsHttp.h for access to the atoms.
|
See nsHttp.h for access to the atoms.
|
||||||
|
|
||||||
It is designed to be used as inline input to nsHttp.cpp *only*
|
It is designed to be used as inline input to nsHttp.cpp *only*
|
||||||
|
|
|
@ -331,7 +331,7 @@ nsHttpAuthIdentity::Set(const PRUnichar *domain,
|
||||||
|
|
||||||
int domainLen = domain ? NS_strlen(domain) : 0;
|
int domainLen = domain ? NS_strlen(domain) : 0;
|
||||||
int userLen = user ? NS_strlen(user) : 0;
|
int userLen = user ? NS_strlen(user) : 0;
|
||||||
int passLen = pass ? NS_strlen(pass) : 0;
|
int passLen = pass ? NS_strlen(pass) : 0;
|
||||||
|
|
||||||
int len = userLen + 1 + passLen + 1 + domainLen + 1;
|
int len = userLen + 1 + passLen + 1 + domainLen + 1;
|
||||||
newUser = (PRUnichar *) malloc(len * sizeof(PRUnichar));
|
newUser = (PRUnichar *) malloc(len * sizeof(PRUnichar));
|
||||||
|
@ -414,7 +414,7 @@ nsHttpAuthEntry::AddPath(const char *aPath)
|
||||||
tempPtr = tempPtr->mNext;
|
tempPtr = tempPtr->mNext;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Append the aPath
|
//Append the aPath
|
||||||
nsHttpAuthPath *newAuthPath;
|
nsHttpAuthPath *newAuthPath;
|
||||||
int newpathLen = strlen(aPath);
|
int newpathLen = strlen(aPath);
|
||||||
|
@ -471,7 +471,7 @@ nsHttpAuthEntry::Set(const char *path,
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
if (ident) {
|
if (ident) {
|
||||||
rv = mIdent.Set(*ident);
|
rv = mIdent.Set(*ident);
|
||||||
}
|
}
|
||||||
else if (mIdent.IsEmpty()) {
|
else if (mIdent.IsEmpty()) {
|
||||||
// If we are not given an identity and our cached identity has not been
|
// If we are not given an identity and our cached identity has not been
|
||||||
// initialized yet (so is currently empty), initialize it now by
|
// initialized yet (so is currently empty), initialize it now by
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
#include "nsCRT.h"
|
#include "nsCRT.h"
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct nsHttpAuthPath {
|
struct nsHttpAuthPath {
|
||||||
struct nsHttpAuthPath *mNext;
|
struct nsHttpAuthPath *mNext;
|
||||||
char mPath[1];
|
char mPath[1];
|
||||||
|
@ -85,9 +83,9 @@ public:
|
||||||
nsHttpAuthPath *RootPath() { return mRoot; }
|
nsHttpAuthPath *RootPath() { return mRoot; }
|
||||||
|
|
||||||
const nsHttpAuthIdentity &Identity() const { return mIdent; }
|
const nsHttpAuthIdentity &Identity() const { return mIdent; }
|
||||||
|
|
||||||
nsresult AddPath(const char *aPath);
|
nsresult AddPath(const char *aPath);
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> mMetaData;
|
nsCOMPtr<nsISupports> mMetaData;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -221,7 +219,7 @@ public:
|
||||||
uint32_t appId,
|
uint32_t appId,
|
||||||
bool inBrowserElement);
|
bool inBrowserElement);
|
||||||
|
|
||||||
// expire all existing auth list entries including proxy auths.
|
// expire all existing auth list entries including proxy auths.
|
||||||
nsresult ClearAll();
|
nsresult ClearAll();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -250,7 +248,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
void ClearAppData(uint32_t appId, bool browserOnly);
|
void ClearAppData(uint32_t appId, bool browserOnly);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PLHashTable *mDB; // "host:port" --> nsHttpAuthNode
|
PLHashTable *mDB; // "host:port" --> nsHttpAuthNode
|
||||||
nsRefPtr<AppDataClearObserver> mObserver;
|
nsRefPtr<AppDataClearObserver> mObserver;
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
#include "mozilla/VisualEventTracer.h"
|
#include "mozilla/VisualEventTracer.h"
|
||||||
|
|
||||||
namespace mozilla { namespace net {
|
namespace mozilla { namespace net {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Device IDs for various cache types
|
// Device IDs for various cache types
|
||||||
|
@ -84,7 +84,7 @@ nsresult
|
||||||
Hash(const char *buf, nsACString &hash)
|
Hash(const char *buf, nsACString &hash)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
nsCOMPtr<nsICryptoHash> hasher
|
nsCOMPtr<nsICryptoHash> hasher
|
||||||
= do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID, &rv);
|
= do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID, &rv);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
@ -132,7 +132,7 @@ MaybeMarkCacheEntryValid(const void * channel,
|
||||||
channel, cacheEntry, int(cacheAccess), int(rv)));
|
channel, cacheEntry, int(cacheAccess), int(rv)));
|
||||||
} else {
|
} else {
|
||||||
LOG(("Not marking read-only cache entry valid "
|
LOG(("Not marking read-only cache entry valid "
|
||||||
"[channel=%p, entry=%p, access=%d]",
|
"[channel=%p, entry=%p, access=%d]",
|
||||||
channel, cacheEntry, int(cacheAccess)));
|
channel, cacheEntry, int(cacheAccess)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,8 +160,8 @@ AutoRedirectVetoNotifier::ReportRedirectResult(bool succeeded)
|
||||||
mChannel->mRedirectChannel = nullptr;
|
mChannel->mRedirectChannel = nullptr;
|
||||||
|
|
||||||
nsCOMPtr<nsIRedirectResultListener> vetoHook;
|
nsCOMPtr<nsIRedirectResultListener> vetoHook;
|
||||||
NS_QueryNotificationCallbacks(mChannel,
|
NS_QueryNotificationCallbacks(mChannel,
|
||||||
NS_GET_IID(nsIRedirectResultListener),
|
NS_GET_IID(nsIRedirectResultListener),
|
||||||
getter_AddRefs(vetoHook));
|
getter_AddRefs(vetoHook));
|
||||||
|
|
||||||
#ifdef MOZ_VISUAL_EVENT_TRACER
|
#ifdef MOZ_VISUAL_EVENT_TRACER
|
||||||
|
@ -257,7 +257,7 @@ private:
|
||||||
const bool mUsingSSL;
|
const bool mUsingSSL;
|
||||||
const bool mLoadedFromApplicationCache;
|
const bool mLoadedFromApplicationCache;
|
||||||
|
|
||||||
// Used only internally
|
// Used only internally
|
||||||
nsCOMPtr<nsIEventTarget> mCacheThread;
|
nsCOMPtr<nsIEventTarget> mCacheThread;
|
||||||
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry;
|
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry;
|
||||||
nsCacheAccessMode mCacheAccess;
|
nsCacheAccessMode mCacheAccess;
|
||||||
|
@ -469,7 +469,7 @@ nsHttpChannel::ContinueConnect()
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
else if (mLoadFlags & LOAD_ONLY_FROM_CACHE) {
|
else if (mLoadFlags & LOAD_ONLY_FROM_CACHE) {
|
||||||
// the cache contains the requested resource, but it must be
|
// the cache contains the requested resource, but it must be
|
||||||
// validated before we can reuse it. since we are not allowed
|
// validated before we can reuse it. since we are not allowed
|
||||||
// to hit the net, there's nothing more to do. the document
|
// to hit the net, there's nothing more to do. the document
|
||||||
// is effectively not in the cache.
|
// is effectively not in the cache.
|
||||||
|
@ -516,7 +516,7 @@ nsHttpChannel::SpeculativeConnect()
|
||||||
// if we are offline, when doing http upgrade (i.e. websockets bootstrap),
|
// if we are offline, when doing http upgrade (i.e. websockets bootstrap),
|
||||||
// or if we can't do keep-alive (because then we couldn't reuse
|
// or if we can't do keep-alive (because then we couldn't reuse
|
||||||
// the speculative connection anyhow).
|
// the speculative connection anyhow).
|
||||||
if (mApplicationCache || gIOService->IsOffline() ||
|
if (mApplicationCache || gIOService->IsOffline() ||
|
||||||
mUpgradeProtocolCallback || !(mCaps & NS_HTTP_ALLOW_KEEPALIVE))
|
mUpgradeProtocolCallback || !(mCaps & NS_HTTP_ALLOW_KEEPALIVE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -526,7 +526,7 @@ nsHttpChannel::SpeculativeConnect()
|
||||||
if (mLoadFlags & (LOAD_ONLY_FROM_CACHE | LOAD_FROM_CACHE |
|
if (mLoadFlags & (LOAD_ONLY_FROM_CACHE | LOAD_FROM_CACHE |
|
||||||
LOAD_NO_NETWORK_IO | LOAD_CHECK_OFFLINE_CACHE))
|
LOAD_NO_NETWORK_IO | LOAD_CHECK_OFFLINE_CACHE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nsCOMPtr<nsIInterfaceRequestor> callbacks;
|
nsCOMPtr<nsIInterfaceRequestor> callbacks;
|
||||||
NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
|
NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
|
||||||
getter_AddRefs(callbacks));
|
getter_AddRefs(callbacks));
|
||||||
|
@ -550,7 +550,7 @@ void
|
||||||
nsHttpChannel::HandleAsyncRedirect()
|
nsHttpChannel::HandleAsyncRedirect()
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(!mCallOnResume, "How did that happen?");
|
NS_PRECONDITION(!mCallOnResume, "How did that happen?");
|
||||||
|
|
||||||
if (mSuspendCount) {
|
if (mSuspendCount) {
|
||||||
LOG(("Waiting until resume to do async redirect [this=%p]\n", this));
|
LOG(("Waiting until resume to do async redirect [this=%p]\n", this));
|
||||||
mCallOnResume = &nsHttpChannel::HandleAsyncRedirect;
|
mCallOnResume = &nsHttpChannel::HandleAsyncRedirect;
|
||||||
|
@ -610,14 +610,14 @@ void
|
||||||
nsHttpChannel::HandleAsyncNotModified()
|
nsHttpChannel::HandleAsyncNotModified()
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(!mCallOnResume, "How did that happen?");
|
NS_PRECONDITION(!mCallOnResume, "How did that happen?");
|
||||||
|
|
||||||
if (mSuspendCount) {
|
if (mSuspendCount) {
|
||||||
LOG(("Waiting until resume to do async not-modified [this=%p]\n",
|
LOG(("Waiting until resume to do async not-modified [this=%p]\n",
|
||||||
this));
|
this));
|
||||||
mCallOnResume = &nsHttpChannel::HandleAsyncNotModified;
|
mCallOnResume = &nsHttpChannel::HandleAsyncNotModified;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(("nsHttpChannel::HandleAsyncNotModified [this=%p]\n", this));
|
LOG(("nsHttpChannel::HandleAsyncNotModified [this=%p]\n", this));
|
||||||
|
|
||||||
DoNotifyListener();
|
DoNotifyListener();
|
||||||
|
@ -875,7 +875,7 @@ nsHttpChannel::SetupTransaction()
|
||||||
}
|
}
|
||||||
|
|
||||||
SetupTransactionLoadGroupInfo();
|
SetupTransactionLoadGroupInfo();
|
||||||
|
|
||||||
rv = nsInputStreamPump::Create(getter_AddRefs(mTransactionPump),
|
rv = nsInputStreamPump::Create(getter_AddRefs(mTransactionPump),
|
||||||
responseStream);
|
responseStream);
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -914,7 +914,7 @@ nsHttpChannel::CallOnStartRequest()
|
||||||
typeSniffersCalled =
|
typeSniffersCalled =
|
||||||
NS_SUCCEEDED(mCachePump->PeekStream(CallTypeSniffers, thisChannel));
|
NS_SUCCEEDED(mCachePump->PeekStream(CallTypeSniffers, thisChannel));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!typeSniffersCalled && mTransactionPump) {
|
if (!typeSniffersCalled && mTransactionPump) {
|
||||||
mTransactionPump->PeekStream(CallTypeSniffers, thisChannel);
|
mTransactionPump->PeekStream(CallTypeSniffers, thisChannel);
|
||||||
}
|
}
|
||||||
|
@ -990,7 +990,7 @@ nsHttpChannel::CallOnStartRequest()
|
||||||
LOG(("writing to the offline cache"));
|
LOG(("writing to the offline cache"));
|
||||||
rv = InitOfflineCacheEntry();
|
rv = InitOfflineCacheEntry();
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
// InitOfflineCacheEntry may have closed mOfflineCacheEntry
|
// InitOfflineCacheEntry may have closed mOfflineCacheEntry
|
||||||
if (mOfflineCacheEntry) {
|
if (mOfflineCacheEntry) {
|
||||||
rv = InstallOfflineCacheListener();
|
rv = InstallOfflineCacheListener();
|
||||||
|
@ -1022,7 +1022,7 @@ nsHttpChannel::ProcessFailedProxyConnect(uint32_t httpStatus)
|
||||||
MOZ_ASSERT(mConnectionInfo->UsingConnect(),
|
MOZ_ASSERT(mConnectionInfo->UsingConnect(),
|
||||||
"proxy connect failed but not using CONNECT?");
|
"proxy connect failed but not using CONNECT?");
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
switch (httpStatus)
|
switch (httpStatus)
|
||||||
{
|
{
|
||||||
case 300: case 301: case 302: case 303: case 307: case 308:
|
case 300: case 301: case 302: case 303: case 307: case 308:
|
||||||
// Bad redirect: not top-level, or it's a POST, bad/missing Location,
|
// Bad redirect: not top-level, or it's a POST, bad/missing Location,
|
||||||
|
@ -1035,7 +1035,7 @@ nsHttpChannel::ProcessFailedProxyConnect(uint32_t httpStatus)
|
||||||
case 407: // ProcessAuthentication() failed
|
case 407: // ProcessAuthentication() failed
|
||||||
case 501: // HTTP/1.1: "Not Implemented"
|
case 501: // HTTP/1.1: "Not Implemented"
|
||||||
// user sees boilerplate Mozilla "Proxy Refused Connection" page.
|
// user sees boilerplate Mozilla "Proxy Refused Connection" page.
|
||||||
rv = NS_ERROR_PROXY_CONNECTION_REFUSED;
|
rv = NS_ERROR_PROXY_CONNECTION_REFUSED;
|
||||||
break;
|
break;
|
||||||
// Squid sends 404 if DNS fails (regular 404 from target is tunneled)
|
// Squid sends 404 if DNS fails (regular 404 from target is tunneled)
|
||||||
case 404: // HTTP/1.1: "Not Found"
|
case 404: // HTTP/1.1: "Not Found"
|
||||||
|
@ -1047,7 +1047,7 @@ nsHttpChannel::ProcessFailedProxyConnect(uint32_t httpStatus)
|
||||||
/* User sees: "Address Not Found: Firefox can't find the server at
|
/* User sees: "Address Not Found: Firefox can't find the server at
|
||||||
* www.foo.com."
|
* www.foo.com."
|
||||||
*/
|
*/
|
||||||
rv = NS_ERROR_UNKNOWN_HOST;
|
rv = NS_ERROR_UNKNOWN_HOST;
|
||||||
break;
|
break;
|
||||||
case 502: // HTTP/1.1: "Bad Gateway" (invalid resp from target server)
|
case 502: // HTTP/1.1: "Bad Gateway" (invalid resp from target server)
|
||||||
// Squid returns 503 if target request fails for anything but DNS.
|
// Squid returns 503 if target request fails for anything but DNS.
|
||||||
|
@ -1061,18 +1061,18 @@ nsHttpChannel::ProcessFailedProxyConnect(uint32_t httpStatus)
|
||||||
break;
|
break;
|
||||||
// RFC 2616 uses 504 for both DNS and target timeout, so not clear what to
|
// RFC 2616 uses 504 for both DNS and target timeout, so not clear what to
|
||||||
// do here: picking target timeout, as DNS covered by 400/404/500
|
// do here: picking target timeout, as DNS covered by 400/404/500
|
||||||
case 504: // HTTP/1.1: "Gateway Timeout"
|
case 504: // HTTP/1.1: "Gateway Timeout"
|
||||||
// user sees: "Network Timeout: The server at www.foo.com
|
// user sees: "Network Timeout: The server at www.foo.com
|
||||||
// is taking too long to respond."
|
// is taking too long to respond."
|
||||||
rv = NS_ERROR_NET_TIMEOUT;
|
rv = NS_ERROR_NET_TIMEOUT;
|
||||||
break;
|
break;
|
||||||
// Confused proxy server or malicious response
|
// Confused proxy server or malicious response
|
||||||
default:
|
default:
|
||||||
rv = NS_ERROR_PROXY_CONNECTION_REFUSED;
|
rv = NS_ERROR_PROXY_CONNECTION_REFUSED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LOG(("Cancelling failed proxy CONNECT [this=%p httpStatus=%u]\n",
|
LOG(("Cancelling failed proxy CONNECT [this=%p httpStatus=%u]\n",
|
||||||
this, httpStatus));
|
this, httpStatus));
|
||||||
Cancel(rv);
|
Cancel(rv);
|
||||||
CallOnStartRequest();
|
CallOnStartRequest();
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -1902,7 +1902,7 @@ nsHttpChannel::EnsureAssocReq()
|
||||||
|
|
||||||
if (!mTransaction || !mURI)
|
if (!mTransaction || !mURI)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
if (!mTransaction->PipelinePosition()) {
|
if (!mTransaction->PipelinePosition()) {
|
||||||
// "Pragma: X-Verify-Assoc-Req" can be used to verify even non pipelined
|
// "Pragma: X-Verify-Assoc-Req" can be used to verify even non pipelined
|
||||||
// transactions. It is used by test harness.
|
// transactions. It is used by test harness.
|
||||||
|
@ -1917,17 +1917,17 @@ nsHttpChannel::EnsureAssocReq()
|
||||||
char *method = net_FindCharNotInSet(assoc_val, HTTP_LWS);
|
char *method = net_FindCharNotInSet(assoc_val, HTTP_LWS);
|
||||||
if (!method)
|
if (!method)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
bool equals;
|
bool equals;
|
||||||
char *endofmethod;
|
char *endofmethod;
|
||||||
|
|
||||||
assoc_val = nullptr;
|
assoc_val = nullptr;
|
||||||
endofmethod = net_FindCharInSet(method, HTTP_LWS);
|
endofmethod = net_FindCharInSet(method, HTTP_LWS);
|
||||||
if (endofmethod)
|
if (endofmethod)
|
||||||
assoc_val = net_FindCharNotInSet(endofmethod, HTTP_LWS);
|
assoc_val = net_FindCharNotInSet(endofmethod, HTTP_LWS);
|
||||||
if (!assoc_val)
|
if (!assoc_val)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
// check the method
|
// check the method
|
||||||
int32_t methodlen = strlen(mRequestHead.Method().get());
|
int32_t methodlen = strlen(mRequestHead.Method().get());
|
||||||
if ((methodlen != (endofmethod - method)) ||
|
if ((methodlen != (endofmethod - method)) ||
|
||||||
|
@ -1958,7 +1958,7 @@ nsHttpChannel::EnsureAssocReq()
|
||||||
return NS_ERROR_CORRUPTED_CONTENT;
|
return NS_ERROR_CORRUPTED_CONTENT;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the URL
|
// check the URL
|
||||||
nsCOMPtr<nsIURI> assoc_url;
|
nsCOMPtr<nsIURI> assoc_url;
|
||||||
if (NS_FAILED(NS_NewURI(getter_AddRefs(assoc_url), assoc_val)) ||
|
if (NS_FAILED(NS_NewURI(getter_AddRefs(assoc_url), assoc_val)) ||
|
||||||
|
@ -2033,14 +2033,14 @@ nsHttpChannel::ProcessPartialContent()
|
||||||
// we need to stream whatever data is in the cache out first, and then
|
// we need to stream whatever data is in the cache out first, and then
|
||||||
// pick up whatever data is on the wire, writing it into the cache.
|
// pick up whatever data is on the wire, writing it into the cache.
|
||||||
|
|
||||||
LOG(("nsHttpChannel::ProcessPartialContent [this=%p]\n", this));
|
LOG(("nsHttpChannel::ProcessPartialContent [this=%p]\n", this));
|
||||||
|
|
||||||
NS_ENSURE_TRUE(mCachedResponseHead, NS_ERROR_NOT_INITIALIZED);
|
NS_ENSURE_TRUE(mCachedResponseHead, NS_ERROR_NOT_INITIALIZED);
|
||||||
NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_NOT_INITIALIZED);
|
NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_NOT_INITIALIZED);
|
||||||
|
|
||||||
// Make sure to clear bogus content-encodings before looking at the header
|
// Make sure to clear bogus content-encodings before looking at the header
|
||||||
ClearBogusContentEncodingIfNeeded();
|
ClearBogusContentEncodingIfNeeded();
|
||||||
|
|
||||||
// Check if the content-encoding we now got is different from the one we
|
// Check if the content-encoding we now got is different from the one we
|
||||||
// got before
|
// got before
|
||||||
if (PL_strcasecmp(mResponseHead->PeekHeader(nsHttp::Content_Encoding),
|
if (PL_strcasecmp(mResponseHead->PeekHeader(nsHttp::Content_Encoding),
|
||||||
|
@ -2128,10 +2128,10 @@ nsHttpChannel::ProcessNotModified()
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
LOG(("nsHttpChannel::ProcessNotModified [this=%p]\n", this));
|
LOG(("nsHttpChannel::ProcessNotModified [this=%p]\n", this));
|
||||||
|
|
||||||
if (mCustomConditionalRequest) {
|
if (mCustomConditionalRequest) {
|
||||||
LOG(("Bypassing ProcessNotModified due to custom conditional headers"));
|
LOG(("Bypassing ProcessNotModified due to custom conditional headers"));
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2158,7 +2158,7 @@ nsHttpChannel::ProcessNotModified()
|
||||||
rv = mCachedResponseHead->GetHeader(nsHttp::Last_Modified,
|
rv = mCachedResponseHead->GetHeader(nsHttp::Last_Modified,
|
||||||
lastModifiedCached);
|
lastModifiedCached);
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
rv = mResponseHead->GetHeader(nsHttp::Last_Modified,
|
rv = mResponseHead->GetHeader(nsHttp::Last_Modified,
|
||||||
lastModified304);
|
lastModified304);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2547,7 +2547,7 @@ nsHttpChannel::OpenNormalCacheEntry(bool usingSSL)
|
||||||
rv = DetermineCacheAccess(&accessRequested);
|
rv = DetermineCacheAccess(&accessRequested);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
mCacheQuery = new HttpCacheQuery(
|
mCacheQuery = new HttpCacheQuery(
|
||||||
this, clientID, storagePolicy,
|
this, clientID, storagePolicy,
|
||||||
mPrivateBrowsing, cacheKey, accessRequested,
|
mPrivateBrowsing, cacheKey, accessRequested,
|
||||||
|
@ -2743,13 +2743,13 @@ nsHttpChannel::AssembleCacheKey(const char *spec, uint32_t postID,
|
||||||
|
|
||||||
// UpdateExpirationTime is called when a new response comes in from the server.
|
// UpdateExpirationTime is called when a new response comes in from the server.
|
||||||
// It updates the stored response-time and sets the expiration time on the
|
// It updates the stored response-time and sets the expiration time on the
|
||||||
// cache entry.
|
// cache entry.
|
||||||
//
|
//
|
||||||
// From section 13.2.4 of RFC2616, we compute expiration time as follows:
|
// From section 13.2.4 of RFC2616, we compute expiration time as follows:
|
||||||
//
|
//
|
||||||
// timeRemaining = freshnessLifetime - currentAge
|
// timeRemaining = freshnessLifetime - currentAge
|
||||||
// expirationTime = now + timeRemaining
|
// expirationTime = now + timeRemaining
|
||||||
//
|
//
|
||||||
nsresult
|
nsresult
|
||||||
nsHttpChannel::UpdateExpirationTime()
|
nsHttpChannel::UpdateExpirationTime()
|
||||||
{
|
{
|
||||||
|
@ -2767,7 +2767,7 @@ nsHttpChannel::UpdateExpirationTime()
|
||||||
if (freshnessLifetime > 0) {
|
if (freshnessLifetime > 0) {
|
||||||
uint32_t now = NowInSeconds(), currentAge = 0;
|
uint32_t now = NowInSeconds(), currentAge = 0;
|
||||||
|
|
||||||
rv = mResponseHead->ComputeCurrentAge(now, mRequestTime, ¤tAge);
|
rv = mResponseHead->ComputeCurrentAge(now, mRequestTime, ¤tAge);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
LOG(("freshnessLifetime = %u, currentAge = %u\n",
|
LOG(("freshnessLifetime = %u, currentAge = %u\n",
|
||||||
|
@ -2812,7 +2812,7 @@ HttpCacheQuery::Dispatch()
|
||||||
|
|
||||||
// XXX: Start the cache service; otherwise DispatchToCacheIOThread will
|
// XXX: Start the cache service; otherwise DispatchToCacheIOThread will
|
||||||
// fail.
|
// fail.
|
||||||
nsCOMPtr<nsICacheService> service =
|
nsCOMPtr<nsICacheService> service =
|
||||||
do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
|
do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
|
||||||
|
|
||||||
// Ensure the stream transport service gets initialized on the main thread
|
// Ensure the stream transport service gets initialized on the main thread
|
||||||
|
@ -2872,7 +2872,7 @@ HttpCacheQuery::Run()
|
||||||
|
|
||||||
rv = channel->OnCacheEntryAvailable(entry, mCacheAccess, mStatus);
|
rv = channel->OnCacheEntryAvailable(entry, mCacheAccess, mStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3148,7 +3148,7 @@ HttpCacheQuery::CheckCache()
|
||||||
requestedETag = mRequestHead.PeekHeader(nsHttp::If_Match);
|
requestedETag = mRequestHead.PeekHeader(nsHttp::If_Match);
|
||||||
if (cachedETag && (!strncmp(cachedETag, "W/", 2) ||
|
if (cachedETag && (!strncmp(cachedETag, "W/", 2) ||
|
||||||
strcmp(requestedETag, cachedETag))) {
|
strcmp(requestedETag, cachedETag))) {
|
||||||
// User has defined If-Match header, if the cached entry is not
|
// User has defined If-Match header, if the cached entry is not
|
||||||
// matching the provided header value or the cached ETag is weak,
|
// matching the provided header value or the cached ETag is weak,
|
||||||
// force validation.
|
// force validation.
|
||||||
doValidation = true;
|
doValidation = true;
|
||||||
|
@ -3369,7 +3369,7 @@ HttpCacheQuery::OpenCacheInputStream(bool startBuffering)
|
||||||
if ((mLoadFlags & nsICachingChannel::LOAD_ONLY_IF_MODIFIED) &&
|
if ((mLoadFlags & nsICachingChannel::LOAD_ONLY_IF_MODIFIED) &&
|
||||||
!mCachedContentIsPartial) {
|
!mCachedContentIsPartial) {
|
||||||
// For LOAD_ONLY_IF_MODIFIED, we usually don't have to deal with the
|
// For LOAD_ONLY_IF_MODIFIED, we usually don't have to deal with the
|
||||||
// cached entity.
|
// cached entity.
|
||||||
if (!mCacheForOfflineUse) {
|
if (!mCacheForOfflineUse) {
|
||||||
LOG(("Will skip read from cache based on LOAD_ONLY_IF_MODIFIED "
|
LOG(("Will skip read from cache based on LOAD_ONLY_IF_MODIFIED "
|
||||||
"load flag\n"));
|
"load flag\n"));
|
||||||
|
@ -3413,7 +3413,7 @@ HttpCacheQuery::OpenCacheInputStream(bool startBuffering)
|
||||||
|
|
||||||
// Have the stream transport service start reading the entity on one of its
|
// Have the stream transport service start reading the entity on one of its
|
||||||
// background threads.
|
// background threads.
|
||||||
|
|
||||||
nsCOMPtr<nsITransport> transport;
|
nsCOMPtr<nsITransport> transport;
|
||||||
nsCOMPtr<nsIInputStream> wrapper;
|
nsCOMPtr<nsIInputStream> wrapper;
|
||||||
|
|
||||||
|
@ -3434,7 +3434,7 @@ HttpCacheQuery::OpenCacheInputStream(bool startBuffering)
|
||||||
LOG(("Failed to open cache input stream [channel=%p, "
|
LOG(("Failed to open cache input stream [channel=%p, "
|
||||||
"wrapper=%p, transport=%p, stream=%p]", this,
|
"wrapper=%p, transport=%p, stream=%p]", this,
|
||||||
wrapper.get(), transport.get(), stream.get()));
|
wrapper.get(), transport.get(), stream.get()));
|
||||||
|
|
||||||
stream->Close();
|
stream->Close();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -3460,7 +3460,7 @@ nsHttpChannel::ReadFromCache(bool alreadyMarkedValid)
|
||||||
|
|
||||||
UpdateInhibitPersistentCachingFlag();
|
UpdateInhibitPersistentCachingFlag();
|
||||||
|
|
||||||
// if we don't already have security info, try to get it from the cache
|
// if we don't already have security info, try to get it from the cache
|
||||||
// entry. there are two cases to consider here: 1) we are just reading
|
// entry. there are two cases to consider here: 1) we are just reading
|
||||||
// from the cache, or 2) this may be due to a 304 not modified response,
|
// from the cache, or 2) this may be due to a 304 not modified response,
|
||||||
// in which case we could have security info from a socket transport.
|
// in which case we could have security info from a socket transport.
|
||||||
|
@ -3489,7 +3489,7 @@ nsHttpChannel::ReadFromCache(bool alreadyMarkedValid)
|
||||||
LOG(("Skipping skip read of cached redirect entity\n"));
|
LOG(("Skipping skip read of cached redirect entity\n"));
|
||||||
return AsyncCall(&nsHttpChannel::HandleAsyncRedirect);
|
return AsyncCall(&nsHttpChannel::HandleAsyncRedirect);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mLoadFlags & LOAD_ONLY_IF_MODIFIED) && !mCachedContentIsPartial) {
|
if ((mLoadFlags & LOAD_ONLY_IF_MODIFIED) && !mCachedContentIsPartial) {
|
||||||
if (!mApplicationCacheForWrite) {
|
if (!mApplicationCacheForWrite) {
|
||||||
LOG(("Skipping read from cache based on LOAD_ONLY_IF_MODIFIED "
|
LOG(("Skipping read from cache based on LOAD_ONLY_IF_MODIFIED "
|
||||||
|
@ -3499,7 +3499,7 @@ nsHttpChannel::ReadFromCache(bool alreadyMarkedValid)
|
||||||
// here, to avoid event dispatching latency.
|
// here, to avoid event dispatching latency.
|
||||||
return AsyncCall(&nsHttpChannel::HandleAsyncNotModified);
|
return AsyncCall(&nsHttpChannel::HandleAsyncNotModified);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ShouldUpdateOfflineCacheEntry()) {
|
if (!ShouldUpdateOfflineCacheEntry()) {
|
||||||
LOG(("Skipping read from cache based on LOAD_ONLY_IF_MODIFIED "
|
LOG(("Skipping read from cache based on LOAD_ONLY_IF_MODIFIED "
|
||||||
"load flag (mApplicationCacheForWrite not null case)\n"));
|
"load flag (mApplicationCacheForWrite not null case)\n"));
|
||||||
|
@ -3519,7 +3519,7 @@ nsHttpChannel::ReadFromCache(bool alreadyMarkedValid)
|
||||||
|
|
||||||
|
|
||||||
nsCOMPtr<nsIInputStream> inputStream = mCacheInputStream.forget();
|
nsCOMPtr<nsIInputStream> inputStream = mCacheInputStream.forget();
|
||||||
|
|
||||||
rv = nsInputStreamPump::Create(getter_AddRefs(mCachePump), inputStream,
|
rv = nsInputStreamPump::Create(getter_AddRefs(mCachePump), inputStream,
|
||||||
int64_t(-1), int64_t(-1), 0, 0, true);
|
int64_t(-1), int64_t(-1), 0, 0, true);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
@ -3730,7 +3730,7 @@ nsHttpChannel::AddCacheEntryHeaders(nsICacheEntryDescriptor *entry)
|
||||||
mResponseHead->GetHeader(nsHttp::Vary, buf);
|
mResponseHead->GetHeader(nsHttp::Vary, buf);
|
||||||
if (!buf.IsEmpty()) {
|
if (!buf.IsEmpty()) {
|
||||||
NS_NAMED_LITERAL_CSTRING(prefix, "request-");
|
NS_NAMED_LITERAL_CSTRING(prefix, "request-");
|
||||||
|
|
||||||
char *val = buf.BeginWriting(); // going to munge buf
|
char *val = buf.BeginWriting(); // going to munge buf
|
||||||
char *token = nsCRT::strtok(val, NS_HTTP_HEADER_SEPS, &val);
|
char *token = nsCRT::strtok(val, NS_HTTP_HEADER_SEPS, &val);
|
||||||
while (token) {
|
while (token) {
|
||||||
|
@ -3849,11 +3849,11 @@ nsHttpChannel::InstallCacheListener(uint32_t offset)
|
||||||
mResponseHead->ContentType().EqualsLiteral(APPLICATION_ECMASCRIPT) ||
|
mResponseHead->ContentType().EqualsLiteral(APPLICATION_ECMASCRIPT) ||
|
||||||
mResponseHead->ContentType().EqualsLiteral(APPLICATION_XJAVASCRIPT) ||
|
mResponseHead->ContentType().EqualsLiteral(APPLICATION_XJAVASCRIPT) ||
|
||||||
mResponseHead->ContentType().EqualsLiteral(APPLICATION_XHTML_XML))) {
|
mResponseHead->ContentType().EqualsLiteral(APPLICATION_XHTML_XML))) {
|
||||||
rv = mCacheEntry->SetMetaDataElement("uncompressed-len", "0");
|
rv = mCacheEntry->SetMetaDataElement("uncompressed-len", "0");
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
LOG(("unable to mark cache entry for compression"));
|
LOG(("unable to mark cache entry for compression"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(("Trading cache input stream for output stream [channel=%p]", this));
|
LOG(("Trading cache input stream for output stream [channel=%p]", this));
|
||||||
|
|
||||||
|
@ -3954,7 +3954,7 @@ nsHttpChannel::ClearBogusContentEncodingIfNeeded()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHttpChannel::SetupReplacementChannel(nsIURI *newURI,
|
nsHttpChannel::SetupReplacementChannel(nsIURI *newURI,
|
||||||
nsIChannel *newChannel,
|
nsIChannel *newChannel,
|
||||||
bool preserveMethod)
|
bool preserveMethod)
|
||||||
{
|
{
|
||||||
|
@ -4030,7 +4030,7 @@ nsHttpChannel::AsyncProcessRedirection(uint32_t redirectType)
|
||||||
|
|
||||||
if (mApplicationCache) {
|
if (mApplicationCache) {
|
||||||
// if we are redirected to a different origin check if there is a fallback
|
// if we are redirected to a different origin check if there is a fallback
|
||||||
// cache entry to fall back to. we don't care about file strict
|
// cache entry to fall back to. we don't care about file strict
|
||||||
// checking, at least mURI is not a file URI.
|
// checking, at least mURI is not a file URI.
|
||||||
if (!NS_SecurityCompareURIs(mURI, mRedirectURI, false)) {
|
if (!NS_SecurityCompareURIs(mURI, mRedirectURI, false)) {
|
||||||
PushRedirectAsyncFunc(&nsHttpChannel::ContinueProcessRedirectionAfterFallback);
|
PushRedirectAsyncFunc(&nsHttpChannel::ContinueProcessRedirectionAfterFallback);
|
||||||
|
@ -4097,7 +4097,7 @@ nsHttpChannel::ContinueProcessRedirectionAfterFallback(nsresult rv)
|
||||||
|
|
||||||
bool rewriteToGET = nsHttp::ShouldRewriteRedirectToGET(
|
bool rewriteToGET = nsHttp::ShouldRewriteRedirectToGET(
|
||||||
mRedirectType, mRequestHead.Method());
|
mRedirectType, mRequestHead.Method());
|
||||||
|
|
||||||
// prompt if the method is not safe (such as POST, PUT, DELETE, ...)
|
// prompt if the method is not safe (such as POST, PUT, DELETE, ...)
|
||||||
if (!rewriteToGET &&
|
if (!rewriteToGET &&
|
||||||
!nsHttp::IsSafeMethod(mRequestHead.Method())) {
|
!nsHttp::IsSafeMethod(mRequestHead.Method())) {
|
||||||
|
@ -4174,7 +4174,7 @@ nsHttpChannel::ContinueProcessRedirection(nsresult rv)
|
||||||
|
|
||||||
// close down this channel
|
// close down this channel
|
||||||
Cancel(NS_BINDING_REDIRECTED);
|
Cancel(NS_BINDING_REDIRECTED);
|
||||||
|
|
||||||
notifier.RedirectSucceeded();
|
notifier.RedirectSucceeded();
|
||||||
|
|
||||||
ReleaseListeners();
|
ReleaseListeners();
|
||||||
|
@ -4197,7 +4197,7 @@ NS_IMETHODIMP nsHttpChannel::OnAuthAvailable()
|
||||||
mProxyAuthPending = false;
|
mProxyAuthPending = false;
|
||||||
LOG(("Resuming the transaction, we got credentials from user"));
|
LOG(("Resuming the transaction, we got credentials from user"));
|
||||||
mTransactionPump->Resume();
|
mTransactionPump->Resume();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4302,7 +4302,7 @@ NS_IMETHODIMP
|
||||||
nsHttpChannel::Suspend()
|
nsHttpChannel::Suspend()
|
||||||
{
|
{
|
||||||
NS_ENSURE_TRUE(mIsPending, NS_ERROR_NOT_AVAILABLE);
|
NS_ENSURE_TRUE(mIsPending, NS_ERROR_NOT_AVAILABLE);
|
||||||
|
|
||||||
LOG(("nsHttpChannel::Suspend [this=%p]\n", this));
|
LOG(("nsHttpChannel::Suspend [this=%p]\n", this));
|
||||||
|
|
||||||
++mSuspendCount;
|
++mSuspendCount;
|
||||||
|
@ -4319,9 +4319,9 @@ NS_IMETHODIMP
|
||||||
nsHttpChannel::Resume()
|
nsHttpChannel::Resume()
|
||||||
{
|
{
|
||||||
NS_ENSURE_TRUE(mSuspendCount > 0, NS_ERROR_UNEXPECTED);
|
NS_ENSURE_TRUE(mSuspendCount > 0, NS_ERROR_UNEXPECTED);
|
||||||
|
|
||||||
LOG(("nsHttpChannel::Resume [this=%p]\n", this));
|
LOG(("nsHttpChannel::Resume [this=%p]\n", this));
|
||||||
|
|
||||||
if (--mSuspendCount == 0 && mCallOnResume) {
|
if (--mSuspendCount == 0 && mCallOnResume) {
|
||||||
nsresult rv = AsyncCall(mCallOnResume);
|
nsresult rv = AsyncCall(mCallOnResume);
|
||||||
mCallOnResume = nullptr;
|
mCallOnResume = nullptr;
|
||||||
|
@ -4479,8 +4479,8 @@ nsHttpChannel::BeginConnect()
|
||||||
gHttpHandler->AddConnectionHeader(&mRequestHead.Headers(), mCaps);
|
gHttpHandler->AddConnectionHeader(&mRequestHead.Headers(), mCaps);
|
||||||
|
|
||||||
if (!mConnectionInfo->UsingHttpProxy()) {
|
if (!mConnectionInfo->UsingHttpProxy()) {
|
||||||
// Start a DNS lookup very early in case the real open is queued the DNS can
|
// Start a DNS lookup very early in case the real open is queued the DNS can
|
||||||
// happen in parallel. Do not do so in the presence of an HTTP proxy as
|
// happen in parallel. Do not do so in the presence of an HTTP proxy as
|
||||||
// all lookups other than for the proxy itself are done by the proxy.
|
// all lookups other than for the proxy itself are done by the proxy.
|
||||||
//
|
//
|
||||||
// We keep the DNS prefetch object around so that we can retrieve
|
// We keep the DNS prefetch object around so that we can retrieve
|
||||||
|
@ -4493,14 +4493,14 @@ nsHttpChannel::BeginConnect()
|
||||||
mDNSPrefetch = new nsDNSPrefetch(mURI, mTimingEnabled);
|
mDNSPrefetch = new nsDNSPrefetch(mURI, mTimingEnabled);
|
||||||
mDNSPrefetch->PrefetchHigh();
|
mDNSPrefetch->PrefetchHigh();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust mCaps according to our request headers:
|
// Adjust mCaps according to our request headers:
|
||||||
// - If "Connection: close" is set as a request header, then do not bother
|
// - If "Connection: close" is set as a request header, then do not bother
|
||||||
// trying to establish a keep-alive connection.
|
// trying to establish a keep-alive connection.
|
||||||
if (mRequestHead.HasHeaderValue(nsHttp::Connection, "close"))
|
if (mRequestHead.HasHeaderValue(nsHttp::Connection, "close"))
|
||||||
mCaps &= ~(NS_HTTP_ALLOW_KEEPALIVE | NS_HTTP_ALLOW_PIPELINING);
|
mCaps &= ~(NS_HTTP_ALLOW_KEEPALIVE | NS_HTTP_ALLOW_PIPELINING);
|
||||||
|
|
||||||
if ((mLoadFlags & VALIDATE_ALWAYS) ||
|
if ((mLoadFlags & VALIDATE_ALWAYS) ||
|
||||||
(BYPASS_LOCAL_CACHE(mLoadFlags)))
|
(BYPASS_LOCAL_CACHE(mLoadFlags)))
|
||||||
mCaps |= NS_HTTP_REFRESH_DNS;
|
mCaps |= NS_HTTP_REFRESH_DNS;
|
||||||
|
|
||||||
|
@ -4595,7 +4595,7 @@ nsHttpChannel::OnProxyAvailable(nsICancelable *request, nsIURI *uri,
|
||||||
// proxy info. That is a non-fatal error assuming it wasn't because the
|
// proxy info. That is a non-fatal error assuming it wasn't because the
|
||||||
// request was canceled. We just failover to DIRECT when proxy resolution
|
// request was canceled. We just failover to DIRECT when proxy resolution
|
||||||
// fails (failure can mean that the PAC URL could not be loaded).
|
// fails (failure can mean that the PAC URL could not be loaded).
|
||||||
|
|
||||||
if (NS_SUCCEEDED(status))
|
if (NS_SUCCEEDED(status))
|
||||||
mProxyInfo = pi;
|
mProxyInfo = pi;
|
||||||
|
|
||||||
|
@ -5001,7 +5001,7 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
|
||||||
}
|
}
|
||||||
// Do not to leave the transaction in a suspended state in error cases.
|
// Do not to leave the transaction in a suspended state in error cases.
|
||||||
if (NS_FAILED(status) && mTransaction)
|
if (NS_FAILED(status) && mTransaction)
|
||||||
gHttpHandler->CancelTransaction(mTransaction, status);
|
gHttpHandler->CancelTransaction(mTransaction, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTransaction) {
|
if (mTransaction) {
|
||||||
|
@ -5030,7 +5030,7 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
|
||||||
nsRefPtr<nsAHttpConnection> stickyConn;
|
nsRefPtr<nsAHttpConnection> stickyConn;
|
||||||
if (mCaps & NS_HTTP_STICKY_CONNECTION)
|
if (mCaps & NS_HTTP_STICKY_CONNECTION)
|
||||||
stickyConn = mTransaction->Connection();
|
stickyConn = mTransaction->Connection();
|
||||||
|
|
||||||
// at this point, we're done with the transaction
|
// at this point, we're done with the transaction
|
||||||
mTransactionTimings = mTransaction->Timings();
|
mTransactionTimings = mTransaction->Timings();
|
||||||
mTransaction = nullptr;
|
mTransaction = nullptr;
|
||||||
|
@ -5065,7 +5065,7 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
|
||||||
// if this transaction has been replaced, then bail.
|
// if this transaction has been replaced, then bail.
|
||||||
if (mTransactionReplaced)
|
if (mTransactionReplaced)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
if (mUpgradeProtocolCallback && stickyConn &&
|
if (mUpgradeProtocolCallback && stickyConn &&
|
||||||
mResponseHead && mResponseHead->Status() == 101) {
|
mResponseHead && mResponseHead->Status() == 101) {
|
||||||
gHttpHandler->ConnMgr()->CompleteUpgrade(stickyConn,
|
gHttpHandler->ConnMgr()->CompleteUpgrade(stickyConn,
|
||||||
|
@ -5081,7 +5081,7 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
|
||||||
mRequestTimeInitialized){
|
mRequestTimeInitialized){
|
||||||
FinalizeCacheEntry();
|
FinalizeCacheEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mListener) {
|
if (mListener) {
|
||||||
LOG((" calling OnStopRequest\n"));
|
LOG((" calling OnStopRequest\n"));
|
||||||
mListener->OnStopRequest(this, mListenerContext, status);
|
mListener->OnStopRequest(this, mListenerContext, status);
|
||||||
|
@ -5101,7 +5101,7 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
|
||||||
CleanRedirectCacheChainIfNecessary();
|
CleanRedirectCacheChainIfNecessary();
|
||||||
|
|
||||||
ReleaseListeners();
|
ReleaseListeners();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5157,7 +5157,7 @@ nsHttpChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
|
||||||
|
|
||||||
//
|
//
|
||||||
// we have to manually keep the logical offset of the stream up-to-date.
|
// we have to manually keep the logical offset of the stream up-to-date.
|
||||||
// we cannot depend solely on the offset provided, since we may have
|
// we cannot depend solely on the offset provided, since we may have
|
||||||
// already streamed some data from another source (see, for example,
|
// already streamed some data from another source (see, for example,
|
||||||
// OnDoneReadingPartialCacheEntry).
|
// OnDoneReadingPartialCacheEntry).
|
||||||
//
|
//
|
||||||
|
@ -5221,7 +5221,7 @@ nsHttpChannel::OnTransportStatus(nsITransport *trans, nsresult status,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// nsHttpChannel::nsICacheInfoChannel
|
// nsHttpChannel::nsICacheInfoChannel
|
||||||
|
@ -5320,18 +5320,18 @@ class nsHttpChannelCacheKey MOZ_FINAL : public nsISupportsPRUint32,
|
||||||
|
|
||||||
NS_DECL_NSISUPPORTSPRIMITIVE
|
NS_DECL_NSISUPPORTSPRIMITIVE
|
||||||
NS_FORWARD_NSISUPPORTSPRUINT32(mSupportsPRUint32->)
|
NS_FORWARD_NSISUPPORTSPRUINT32(mSupportsPRUint32->)
|
||||||
|
|
||||||
// Both interfaces declares toString method with the same signature.
|
// Both interfaces declares toString method with the same signature.
|
||||||
// Thus we have to delegate only to nsISupportsPRUint32 implementation.
|
// Thus we have to delegate only to nsISupportsPRUint32 implementation.
|
||||||
NS_IMETHOD GetData(nsACString & aData)
|
NS_IMETHOD GetData(nsACString & aData)
|
||||||
{
|
{
|
||||||
return mSupportsCString->GetData(aData);
|
return mSupportsCString->GetData(aData);
|
||||||
}
|
}
|
||||||
NS_IMETHOD SetData(const nsACString & aData)
|
NS_IMETHOD SetData(const nsACString & aData)
|
||||||
{
|
{
|
||||||
return mSupportsCString->SetData(aData);
|
return mSupportsCString->SetData(aData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
nsresult SetData(uint32_t aPostID, const nsACString& aKey);
|
nsresult SetData(uint32_t aPostID, const nsACString& aKey);
|
||||||
|
|
||||||
|
@ -5368,14 +5368,14 @@ nsresult nsHttpChannelCacheKey::SetData(uint32_t aPostID,
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
mSupportsCString =
|
mSupportsCString =
|
||||||
do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
|
do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
mSupportsCString->SetData(aKey);
|
mSupportsCString->SetData(aKey);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
mSupportsPRUint32 =
|
mSupportsPRUint32 =
|
||||||
do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID, &rv);
|
do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID, &rv);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
@ -5583,7 +5583,7 @@ nsHttpChannel::DoAuthRetry(nsAHttpConnection *conn)
|
||||||
// this authentication attempt (bug 84794).
|
// this authentication attempt (bug 84794).
|
||||||
// TODO: save cookies from auth response and send them here (bug 572151).
|
// TODO: save cookies from auth response and send them here (bug 572151).
|
||||||
AddCookiesToRequest();
|
AddCookiesToRequest();
|
||||||
|
|
||||||
// notify "http-on-modify-request" observers
|
// notify "http-on-modify-request" observers
|
||||||
CallOnModifyRequestObservers();
|
CallOnModifyRequestObservers();
|
||||||
|
|
||||||
|
@ -5595,7 +5595,7 @@ nsHttpChannel::DoAuthRetry(nsAHttpConnection *conn)
|
||||||
// set sticky connection flag and disable pipelining.
|
// set sticky connection flag and disable pipelining.
|
||||||
mCaps |= NS_HTTP_STICKY_CONNECTION;
|
mCaps |= NS_HTTP_STICKY_CONNECTION;
|
||||||
mCaps &= ~NS_HTTP_ALLOW_PIPELINING;
|
mCaps &= ~NS_HTTP_ALLOW_PIPELINING;
|
||||||
|
|
||||||
// and create a new one...
|
// and create a new one...
|
||||||
rv = SetupTransaction();
|
rv = SetupTransaction();
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
@ -5756,7 +5756,7 @@ nsHttpChannel::WaitForRedirectCallback()
|
||||||
rv = mCachePump->Suspend();
|
rv = mCachePump->Suspend();
|
||||||
if (NS_FAILED(rv) && mTransactionPump) {
|
if (NS_FAILED(rv) && mTransactionPump) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
nsresult resume =
|
nsresult resume =
|
||||||
#endif
|
#endif
|
||||||
mTransactionPump->Resume();
|
mTransactionPump->Resume();
|
||||||
MOZ_ASSERT(NS_SUCCEEDED(resume),
|
MOZ_ASSERT(NS_SUCCEEDED(resume),
|
||||||
|
@ -5864,7 +5864,7 @@ nsHttpChannel::MaybeInvalidateCacheEntryForSubsequentGet()
|
||||||
// Pass 0 in first param to get the cache-key for a GET-request.
|
// Pass 0 in first param to get the cache-key for a GET-request.
|
||||||
nsAutoCString tmpCacheKey;
|
nsAutoCString tmpCacheKey;
|
||||||
GenerateCacheKey(0, tmpCacheKey);
|
GenerateCacheKey(0, tmpCacheKey);
|
||||||
LOG(("MaybeInvalidateCacheEntryForSubsequentGet [this=%p uri=%s]\n",
|
LOG(("MaybeInvalidateCacheEntryForSubsequentGet [this=%p uri=%s]\n",
|
||||||
this, tmpCacheKey.get()));
|
this, tmpCacheKey.get()));
|
||||||
DoInvalidateCacheEntry(tmpCacheKey);
|
DoInvalidateCacheEntry(tmpCacheKey);
|
||||||
|
|
||||||
|
|
|
@ -117,11 +117,11 @@ public:
|
||||||
NS_IMETHOD SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks);
|
NS_IMETHOD SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks);
|
||||||
NS_IMETHOD SetLoadGroup(nsILoadGroup *aLoadGroup);
|
NS_IMETHOD SetLoadGroup(nsILoadGroup *aLoadGroup);
|
||||||
|
|
||||||
public: /* internal necko use only */
|
public: /* internal necko use only */
|
||||||
|
|
||||||
void InternalSetUploadStream(nsIInputStream *uploadStream)
|
void InternalSetUploadStream(nsIInputStream *uploadStream)
|
||||||
{ mUploadStream = uploadStream; }
|
{ mUploadStream = uploadStream; }
|
||||||
void SetUploadStreamHasHeaders(bool hasHeaders)
|
void SetUploadStreamHasHeaders(bool hasHeaders)
|
||||||
{ mUploadStreamHasHeaders = hasHeaders; }
|
{ mUploadStreamHasHeaders = hasHeaders; }
|
||||||
|
|
||||||
nsresult SetReferrerInternal(nsIURI *referrer) {
|
nsresult SetReferrerInternal(nsIURI *referrer) {
|
||||||
|
@ -248,7 +248,7 @@ private:
|
||||||
nsresult OpenRedirectChannel(nsresult rv);
|
nsresult OpenRedirectChannel(nsresult rv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A function that takes care of reading STS headers and enforcing STS
|
* A function that takes care of reading STS headers and enforcing STS
|
||||||
* load rules. After a secure channel is erected, STS requires the channel
|
* load rules. After a secure channel is erected, STS requires the channel
|
||||||
* to be trusted or any STS header data on the channel is ignored.
|
* to be trusted or any STS header data on the channel is ignored.
|
||||||
* This is called from ProcessResponse.
|
* This is called from ProcessResponse.
|
||||||
|
|
|
@ -100,7 +100,7 @@ private:
|
||||||
nsresult DoRedirectChannelToHttps();
|
nsresult DoRedirectChannelToHttps();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A function that takes care of reading STS headers and enforcing STS
|
* A function that takes care of reading STS headers and enforcing STS
|
||||||
* load rules. After a secure channel is erected, STS requires the channel
|
* load rules. After a secure channel is erected, STS requires the channel
|
||||||
* to be trusted or any STS header data on the channel is ignored.
|
* to be trusted or any STS header data on the channel is ignored.
|
||||||
* This is called from ProcessResponse.
|
* This is called from ProcessResponse.
|
||||||
|
|
|
@ -20,7 +20,7 @@ nsHttpChunkedDecoder::HandleChunkedContent(char *buf,
|
||||||
LOG(("nsHttpChunkedDecoder::HandleChunkedContent [count=%u]\n", count));
|
LOG(("nsHttpChunkedDecoder::HandleChunkedContent [count=%u]\n", count));
|
||||||
|
|
||||||
*contentRead = 0;
|
*contentRead = 0;
|
||||||
|
|
||||||
// from RFC2617 section 3.6.1, the chunked transfer coding is defined as:
|
// from RFC2617 section 3.6.1, the chunked transfer coding is defined as:
|
||||||
//
|
//
|
||||||
// Chunked-Body = *chunk
|
// Chunked-Body = *chunk
|
||||||
|
@ -31,7 +31,7 @@ nsHttpChunkedDecoder::HandleChunkedContent(char *buf,
|
||||||
// chunk-data CRLF
|
// chunk-data CRLF
|
||||||
// chunk-size = 1*HEX
|
// chunk-size = 1*HEX
|
||||||
// last-chunk = 1*("0") [ chunk-extension ] CRLF
|
// last-chunk = 1*("0") [ chunk-extension ] CRLF
|
||||||
//
|
//
|
||||||
// chunk-extension = *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
|
// chunk-extension = *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
|
||||||
// chunk-ext-name = token
|
// chunk-ext-name = token
|
||||||
// chunk-ext-val = token | quoted-string
|
// chunk-ext-val = token | quoted-string
|
||||||
|
@ -39,7 +39,7 @@ nsHttpChunkedDecoder::HandleChunkedContent(char *buf,
|
||||||
// trailer = *(entity-header CRLF)
|
// trailer = *(entity-header CRLF)
|
||||||
//
|
//
|
||||||
// the chunk-size field is a string of hex digits indicating the size of the
|
// the chunk-size field is a string of hex digits indicating the size of the
|
||||||
// chunk. the chunked encoding is ended by any chunk whose size is zero,
|
// chunk. the chunked encoding is ended by any chunk whose size is zero,
|
||||||
// followed by the trailer, which is terminated by an empty line.
|
// followed by the trailer, which is terminated by an empty line.
|
||||||
|
|
||||||
while (count) {
|
while (count) {
|
||||||
|
@ -68,7 +68,7 @@ nsHttpChunkedDecoder::HandleChunkedContent(char *buf,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*contentRemaining = count;
|
*contentRemaining = count;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ nsHttpChunkedDecoder::ParseChunkRemaining(char *buf,
|
||||||
NS_PRECONDITION(count, "unexpected");
|
NS_PRECONDITION(count, "unexpected");
|
||||||
|
|
||||||
*bytesConsumed = 0;
|
*bytesConsumed = 0;
|
||||||
|
|
||||||
char *p = static_cast<char *>(memchr(buf, '\n', count));
|
char *p = static_cast<char *>(memchr(buf, '\n', count));
|
||||||
if (p) {
|
if (p) {
|
||||||
*p = 0;
|
*p = 0;
|
||||||
|
|
|
@ -210,7 +210,7 @@ nsHttpConnection::StartSpdy(uint8_t spdyVersion)
|
||||||
for (int32_t index = 0; index < count; ++index) {
|
for (int32_t index = 0; index < count; ++index) {
|
||||||
if (!mSpdySession) {
|
if (!mSpdySession) {
|
||||||
mSpdySession = ASpdySession::NewSpdySession(spdyVersion,
|
mSpdySession = ASpdySession::NewSpdySession(spdyVersion,
|
||||||
list[index], mSocketTransport,
|
list[index], mSocketTransport,
|
||||||
mPriority);
|
mPriority);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -247,13 +247,13 @@ nsHttpConnection::EnsureNPNComplete()
|
||||||
|
|
||||||
if (mNPNComplete)
|
if (mNPNComplete)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> securityInfo;
|
nsCOMPtr<nsISupports> securityInfo;
|
||||||
nsCOMPtr<nsISSLSocketControl> ssl;
|
nsCOMPtr<nsISSLSocketControl> ssl;
|
||||||
nsAutoCString negotiatedNPN;
|
nsAutoCString negotiatedNPN;
|
||||||
|
|
||||||
rv = mSocketTransport->GetSecurityInfo(getter_AddRefs(securityInfo));
|
rv = mSocketTransport->GetSecurityInfo(getter_AddRefs(securityInfo));
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
goto npnComplete;
|
goto npnComplete;
|
||||||
|
@ -264,7 +264,7 @@ nsHttpConnection::EnsureNPNComplete()
|
||||||
|
|
||||||
rv = ssl->GetNegotiatedNPN(negotiatedNPN);
|
rv = ssl->GetNegotiatedNPN(negotiatedNPN);
|
||||||
if (rv == NS_ERROR_NOT_CONNECTED) {
|
if (rv == NS_ERROR_NOT_CONNECTED) {
|
||||||
|
|
||||||
// By writing 0 bytes to the socket the SSL handshake machine is
|
// By writing 0 bytes to the socket the SSL handshake machine is
|
||||||
// pushed forward.
|
// pushed forward.
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
|
@ -347,7 +347,7 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, uint32_t caps, int32_t pri
|
||||||
mInputOverflow = nullptr;
|
mInputOverflow = nullptr;
|
||||||
|
|
||||||
rv = OnOutputStreamReady(mSocketOut);
|
rv = OnOutputStreamReady(mSocketOut);
|
||||||
|
|
||||||
failed_activation:
|
failed_activation:
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
mTransaction = nullptr;
|
mTransaction = nullptr;
|
||||||
|
@ -444,7 +444,7 @@ nsHttpConnection::AddTransaction(nsAHttpTransaction *httpTransaction,
|
||||||
"AddTransaction to live http connection without spdy");
|
"AddTransaction to live http connection without spdy");
|
||||||
MOZ_ASSERT(mTransaction,
|
MOZ_ASSERT(mTransaction,
|
||||||
"AddTransaction to idle http connection");
|
"AddTransaction to idle http connection");
|
||||||
|
|
||||||
if (!mSpdySession->AddStream(httpTransaction, priority)) {
|
if (!mSpdySession->AddStream(httpTransaction, priority)) {
|
||||||
MOZ_ASSERT(false, "AddStream should never fail due to"
|
MOZ_ASSERT(false, "AddStream should never fail due to"
|
||||||
"RoomForMore() admission check");
|
"RoomForMore() admission check");
|
||||||
|
@ -487,7 +487,7 @@ nsHttpConnection::Close(nsresult reason)
|
||||||
while (NS_SUCCEEDED(rv) && count > 0 && total < 64000);
|
while (NS_SUCCEEDED(rv) && count > 0 && total < 64000);
|
||||||
LOG(("nsHttpConnection::Close drained %d bytes\n", total));
|
LOG(("nsHttpConnection::Close drained %d bytes\n", total));
|
||||||
}
|
}
|
||||||
|
|
||||||
mSocketTransport->SetSecurityCallbacks(nullptr);
|
mSocketTransport->SetSecurityCallbacks(nullptr);
|
||||||
mSocketTransport->Close(reason);
|
mSocketTransport->Close(reason);
|
||||||
if (mSocketOut)
|
if (mSocketOut)
|
||||||
|
@ -551,7 +551,7 @@ nsHttpConnection::CanReuse()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool canReuse;
|
bool canReuse;
|
||||||
|
|
||||||
if (mSpdySession)
|
if (mSpdySession)
|
||||||
canReuse = mSpdySession->CanReuse();
|
canReuse = mSpdySession->CanReuse();
|
||||||
else
|
else
|
||||||
|
@ -581,7 +581,7 @@ nsHttpConnection::CanDirectlyActivate()
|
||||||
// return true if a new transaction can be addded to ths connection at any
|
// return true if a new transaction can be addded to ths connection at any
|
||||||
// time through Activate(). In practice this means this is a healthy SPDY
|
// time through Activate(). In practice this means this is a healthy SPDY
|
||||||
// connection with room for more concurrent streams.
|
// connection with room for more concurrent streams.
|
||||||
|
|
||||||
return UsingSpdy() && CanReuse() &&
|
return UsingSpdy() && CanReuse() &&
|
||||||
mSpdySession && mSpdySession->RoomForMoreStreams();
|
mSpdySession && mSpdySession->RoomForMoreStreams();
|
||||||
}
|
}
|
||||||
|
@ -658,22 +658,22 @@ nsHttpConnection::SupportsPipelining(nsHttpResponseHead *responseHead)
|
||||||
|
|
||||||
// The blacklist is indexed by the first character. All of these servers are
|
// The blacklist is indexed by the first character. All of these servers are
|
||||||
// known to return their identifier as the first thing in the server string,
|
// known to return their identifier as the first thing in the server string,
|
||||||
// so we can do a leading match.
|
// so we can do a leading match.
|
||||||
|
|
||||||
static const char *bad_servers[26][6] = {
|
static const char *bad_servers[26][6] = {
|
||||||
{ nullptr }, { nullptr }, { nullptr }, { nullptr }, // a - d
|
{ nullptr }, { nullptr }, { nullptr }, { nullptr }, // a - d
|
||||||
{ "EFAServer/", nullptr }, // e
|
{ "EFAServer/", nullptr }, // e
|
||||||
{ nullptr }, { nullptr }, { nullptr }, { nullptr }, // f - i
|
{ nullptr }, { nullptr }, { nullptr }, { nullptr }, // f - i
|
||||||
{ nullptr }, { nullptr }, { nullptr }, // j - l
|
{ nullptr }, { nullptr }, { nullptr }, // j - l
|
||||||
{ "Microsoft-IIS/4.", "Microsoft-IIS/5.", nullptr }, // m
|
{ "Microsoft-IIS/4.", "Microsoft-IIS/5.", nullptr }, // m
|
||||||
{ "Netscape-Enterprise/3.", "Netscape-Enterprise/4.",
|
{ "Netscape-Enterprise/3.", "Netscape-Enterprise/4.",
|
||||||
"Netscape-Enterprise/5.", "Netscape-Enterprise/6.", nullptr }, // n
|
"Netscape-Enterprise/5.", "Netscape-Enterprise/6.", nullptr }, // n
|
||||||
{ nullptr }, { nullptr }, { nullptr }, { nullptr }, // o - r
|
{ nullptr }, { nullptr }, { nullptr }, { nullptr }, // o - r
|
||||||
{ nullptr }, { nullptr }, { nullptr }, { nullptr }, // s - v
|
{ nullptr }, { nullptr }, { nullptr }, { nullptr }, // s - v
|
||||||
{ "WebLogic 3.", "WebLogic 4.","WebLogic 5.", "WebLogic 6.",
|
{ "WebLogic 3.", "WebLogic 4.","WebLogic 5.", "WebLogic 6.",
|
||||||
"Winstone Servlet Engine v0.", nullptr }, // w
|
"Winstone Servlet Engine v0.", nullptr }, // w
|
||||||
{ nullptr }, { nullptr }, { nullptr } // x - z
|
{ nullptr }, { nullptr }, { nullptr } // x - z
|
||||||
};
|
};
|
||||||
|
|
||||||
int index = val[0] - 'A'; // the whole table begins with capital letters
|
int index = val[0] - 'A'; // the whole table begins with capital letters
|
||||||
if ((index >= 0) && (index <= 25))
|
if ((index >= 0) && (index <= 25))
|
||||||
|
@ -744,7 +744,7 @@ nsHttpConnection::OnHeadersAvailable(nsAHttpTransaction *trans,
|
||||||
mKeepAlive = true;
|
mKeepAlive = true;
|
||||||
else
|
else
|
||||||
mKeepAlive = false;
|
mKeepAlive = false;
|
||||||
|
|
||||||
// We need at least version 1.1 to use pipelines
|
// We need at least version 1.1 to use pipelines
|
||||||
gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
|
gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
|
||||||
mConnInfo, nsHttpConnectionMgr::RedVersionTooLow, this, 0);
|
mConnInfo, nsHttpConnectionMgr::RedVersionTooLow, this, 0);
|
||||||
|
@ -799,13 +799,13 @@ nsHttpConnection::OnHeadersAvailable(nsAHttpTransaction *trans,
|
||||||
responseStatus != 304) {
|
responseStatus != 304) {
|
||||||
mClassification = nsAHttpTransaction::CLASS_GENERAL;
|
mClassification = nsAHttpTransaction::CLASS_GENERAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if this connection is persistent, then the server may send a "Keep-Alive"
|
// if this connection is persistent, then the server may send a "Keep-Alive"
|
||||||
// header specifying the maximum number of times the connection can be
|
// header specifying the maximum number of times the connection can be
|
||||||
// reused as well as the maximum amount of time the connection can be idle
|
// reused as well as the maximum amount of time the connection can be idle
|
||||||
// before the server will close it. we ignore the max reuse count, because
|
// before the server will close it. we ignore the max reuse count, because
|
||||||
// a "keep-alive" connection is by definition capable of being reused, and
|
// a "keep-alive" connection is by definition capable of being reused, and
|
||||||
// we only care about being able to reuse it once. if a timeout is not
|
// we only care about being able to reuse it once. if a timeout is not
|
||||||
// specified then we use our advertized timeout value.
|
// specified then we use our advertized timeout value.
|
||||||
bool foundKeepAliveMax = false;
|
bool foundKeepAliveMax = false;
|
||||||
if (mKeepAlive) {
|
if (mKeepAlive) {
|
||||||
|
@ -830,7 +830,7 @@ nsHttpConnection::OnHeadersAvailable(nsAHttpTransaction *trans,
|
||||||
else {
|
else {
|
||||||
mIdleTimeout = gHttpHandler->SpdyTimeout();
|
mIdleTimeout = gHttpHandler->SpdyTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(("Connection can be reused [this=%p idle-timeout=%usec]\n",
|
LOG(("Connection can be reused [this=%p idle-timeout=%usec]\n",
|
||||||
this, PR_IntervalToSeconds(mIdleTimeout)));
|
this, PR_IntervalToSeconds(mIdleTimeout)));
|
||||||
}
|
}
|
||||||
|
@ -871,7 +871,7 @@ nsHttpConnection::OnHeadersAvailable(nsAHttpTransaction *trans,
|
||||||
mTransaction->SetProxyConnectFailed();
|
mTransaction->SetProxyConnectFailed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *upgradeReq = requestHead->PeekHeader(nsHttp::Upgrade);
|
const char *upgradeReq = requestHead->PeekHeader(nsHttp::Upgrade);
|
||||||
// Don't use persistent connection for Upgrade unless there's an auth failure:
|
// Don't use persistent connection for Upgrade unless there's an auth failure:
|
||||||
// some proxies expect to see auth response on persistent connection.
|
// some proxies expect to see auth response on persistent connection.
|
||||||
|
@ -879,7 +879,7 @@ nsHttpConnection::OnHeadersAvailable(nsAHttpTransaction *trans,
|
||||||
LOG(("HTTP Upgrade in play - disable keepalive\n"));
|
LOG(("HTTP Upgrade in play - disable keepalive\n"));
|
||||||
DontReuse();
|
DontReuse();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (responseStatus == 101) {
|
if (responseStatus == 101) {
|
||||||
const char *upgradeResp = responseHead->PeekHeader(nsHttp::Upgrade);
|
const char *upgradeResp = responseHead->PeekHeader(nsHttp::Upgrade);
|
||||||
if (!upgradeReq || !upgradeResp ||
|
if (!upgradeReq || !upgradeResp ||
|
||||||
|
@ -904,7 +904,7 @@ nsHttpConnection::IsReused()
|
||||||
return true;
|
return true;
|
||||||
if (!mConsiderReusedAfterInterval)
|
if (!mConsiderReusedAfterInterval)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// ReusedAfter allows a socket to be consider reused only after a certain
|
// ReusedAfter allows a socket to be consider reused only after a certain
|
||||||
// interval of time has passed
|
// interval of time has passed
|
||||||
return (PR_IntervalNow() - mConsiderReusedAfterEpoch) >=
|
return (PR_IntervalNow() - mConsiderReusedAfterEpoch) >=
|
||||||
|
@ -942,7 +942,7 @@ nsHttpConnection::TakeTransport(nsISocketTransport **aTransport,
|
||||||
mSocketTransport = nullptr;
|
mSocketTransport = nullptr;
|
||||||
mSocketIn = nullptr;
|
mSocketIn = nullptr;
|
||||||
mSocketOut = nullptr;
|
mSocketOut = nullptr;
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -960,7 +960,7 @@ nsHttpConnection::ReadTimeoutTick(PRIntervalTime now)
|
||||||
mSpdySession->ReadTimeoutTick(now);
|
mSpdySession->ReadTimeoutTick(now);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gHttpHandler->GetPipelineRescheduleOnTimeout())
|
if (!gHttpHandler->GetPipelineRescheduleOnTimeout())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1002,7 +1002,7 @@ nsHttpConnection::ReadTimeoutTick(PRIntervalTime now)
|
||||||
|
|
||||||
if (pipelineDepth <= 1 && !mTransaction->PipelinePosition())
|
if (pipelineDepth <= 1 && !mTransaction->PipelinePosition())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// nothing has transpired on this pipelined socket for many
|
// nothing has transpired on this pipelined socket for many
|
||||||
// seconds. Call that a total stall and close the transaction.
|
// seconds. Call that a total stall and close the transaction.
|
||||||
// There is a chance the transaction will be restarted again
|
// There is a chance the transaction will be restarted again
|
||||||
|
@ -1049,7 +1049,7 @@ nsHttpConnection::PushBack(const char *data, uint32_t length)
|
||||||
NS_ERROR("nsHttpConnection::PushBack only one buffer supported");
|
NS_ERROR("nsHttpConnection::PushBack only one buffer supported");
|
||||||
return NS_ERROR_UNEXPECTED;
|
return NS_ERROR_UNEXPECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
mInputOverflow = new nsPreloadedStream(mSocketIn, data, length);
|
mInputOverflow = new nsPreloadedStream(mSocketIn, data, length);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -1283,7 +1283,7 @@ nsHttpConnection::OnSocketWritable()
|
||||||
rv = NS_OK;
|
rv = NS_OK;
|
||||||
|
|
||||||
if (mTransaction) { // in case the ReadSegments stack called CloseTransaction()
|
if (mTransaction) { // in case the ReadSegments stack called CloseTransaction()
|
||||||
//
|
//
|
||||||
// at this point we've written out the entire transaction, and now we
|
// at this point we've written out the entire transaction, and now we
|
||||||
// must wait for the server's response. we manufacture a status message
|
// must wait for the server's response. we manufacture a status message
|
||||||
// here to reflect the fact that we are waiting. this message will be
|
// here to reflect the fact that we are waiting. this message will be
|
||||||
|
@ -1347,7 +1347,7 @@ nsHttpConnection::OnSocketReadable()
|
||||||
// are caused by server bottlenecks such as think-time, disk i/o, or
|
// are caused by server bottlenecks such as think-time, disk i/o, or
|
||||||
// cpu exhaustion (as opposed to network latency) then we generate negative
|
// cpu exhaustion (as opposed to network latency) then we generate negative
|
||||||
// pipelining feedback to prevent head of line problems
|
// pipelining feedback to prevent head of line problems
|
||||||
|
|
||||||
// Reduce the estimate of the time since last read by up to 1 RTT to
|
// Reduce the estimate of the time since last read by up to 1 RTT to
|
||||||
// accommodate exhausted sender TCP congestion windows or minor I/O delays.
|
// accommodate exhausted sender TCP congestion windows or minor I/O delays.
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ public:
|
||||||
// Initialize the connection:
|
// Initialize the connection:
|
||||||
// info - specifies the connection parameters.
|
// info - specifies the connection parameters.
|
||||||
// maxHangTime - limits the amount of time this connection can spend on a
|
// maxHangTime - limits the amount of time this connection can spend on a
|
||||||
// single transaction before it should no longer be kept
|
// single transaction before it should no longer be kept
|
||||||
// alive. a value of 0xffff indicates no limit.
|
// alive. a value of 0xffff indicates no limit.
|
||||||
nsresult Init(nsHttpConnectionInfo *info, uint16_t maxHangTime,
|
nsresult Init(nsHttpConnectionInfo *info, uint16_t maxHangTime,
|
||||||
nsISocketTransport *, nsIAsyncInputStream *,
|
nsISocketTransport *, nsIAsyncInputStream *,
|
||||||
|
@ -123,7 +123,7 @@ public:
|
||||||
static NS_METHOD ReadFromStream(nsIInputStream *, void *, const char *,
|
static NS_METHOD ReadFromStream(nsIInputStream *, void *, const char *,
|
||||||
uint32_t, uint32_t, uint32_t *);
|
uint32_t, uint32_t, uint32_t *);
|
||||||
|
|
||||||
// When a persistent connection is in the connection manager idle
|
// When a persistent connection is in the connection manager idle
|
||||||
// connection pool, the nsHttpConnection still reads errors and hangups
|
// connection pool, the nsHttpConnection still reads errors and hangups
|
||||||
// on the socket so that it can be proactively released if the server
|
// on the socket so that it can be proactively released if the server
|
||||||
// initiates a termination. Only call on socket thread.
|
// initiates a termination. Only call on socket thread.
|
||||||
|
@ -168,7 +168,7 @@ private:
|
||||||
PRIntervalTime IdleTime();
|
PRIntervalTime IdleTime();
|
||||||
bool IsAlive();
|
bool IsAlive();
|
||||||
bool SupportsPipelining(nsHttpResponseHead *);
|
bool SupportsPipelining(nsHttpResponseHead *);
|
||||||
|
|
||||||
// Makes certain the SSL handshake is complete and NPN negotiation
|
// Makes certain the SSL handshake is complete and NPN negotiation
|
||||||
// has had a chance to happen
|
// has had a chance to happen
|
||||||
bool EnsureNPNComplete();
|
bool EnsureNPNComplete();
|
||||||
|
|
|
@ -45,7 +45,7 @@ public:
|
||||||
|
|
||||||
SetOriginServer(host, port);
|
SetOriginServer(host, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
~nsHttpConnectionInfo()
|
~nsHttpConnectionInfo()
|
||||||
{
|
{
|
||||||
LOG(("Destroying nsHttpConnectionInfo @%x\n", this));
|
LOG(("Destroying nsHttpConnectionInfo @%x\n", this));
|
||||||
|
@ -75,7 +75,7 @@ public:
|
||||||
{
|
{
|
||||||
SetOriginServer(nsDependentCString(host), port);
|
SetOriginServer(nsDependentCString(host), port);
|
||||||
}
|
}
|
||||||
|
|
||||||
// OK to treat this as an infalible allocation
|
// OK to treat this as an infalible allocation
|
||||||
nsHttpConnectionInfo* Clone() const;
|
nsHttpConnectionInfo* Clone() const;
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ public:
|
||||||
// Two connections are 'equal' if they end up talking the same
|
// Two connections are 'equal' if they end up talking the same
|
||||||
// protocol to the same server. This is needed to properly manage
|
// protocol to the same server. This is needed to properly manage
|
||||||
// persistent connections to proxies
|
// persistent connections to proxies
|
||||||
// Note that we don't care about transparent proxies -
|
// Note that we don't care about transparent proxies -
|
||||||
// it doesn't matter if we're talking via socks or not, since
|
// it doesn't matter if we're talking via socks or not, since
|
||||||
// a request will end up at the same host.
|
// a request will end up at the same host.
|
||||||
bool Equals(const nsHttpConnectionInfo *info)
|
bool Equals(const nsHttpConnectionInfo *info)
|
||||||
|
@ -102,7 +102,7 @@ public:
|
||||||
bool UsingSSL() const { return mUsingSSL; }
|
bool UsingSSL() const { return mUsingSSL; }
|
||||||
bool UsingConnect() const { return mUsingConnect; }
|
bool UsingConnect() const { return mUsingConnect; }
|
||||||
int32_t DefaultPort() const { return mUsingSSL ? NS_HTTPS_DEFAULT_PORT : NS_HTTP_DEFAULT_PORT; }
|
int32_t DefaultPort() const { return mUsingSSL ? NS_HTTPS_DEFAULT_PORT : NS_HTTP_DEFAULT_PORT; }
|
||||||
void SetAnonymous(bool anon)
|
void SetAnonymous(bool anon)
|
||||||
{ mHashKey.SetCharAt(anon ? 'A' : '.', 2); }
|
{ mHashKey.SetCharAt(anon ? 'A' : '.', 2); }
|
||||||
bool GetAnonymous() const { return mHashKey.CharAt(2) == 'A'; }
|
bool GetAnonymous() const { return mHashKey.CharAt(2) == 'A'; }
|
||||||
void SetPrivate(bool priv) { mHashKey.SetCharAt(priv ? 'P' : '.', 3); }
|
void SetPrivate(bool priv) { mHashKey.SetCharAt(priv ? 'P' : '.', 3); }
|
||||||
|
|
|
@ -368,14 +368,14 @@ nsHttpConnectionMgr::ReclaimConnection(nsHttpConnection *conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// A structure used to marshall 2 pointers across the various necessary
|
// A structure used to marshall 2 pointers across the various necessary
|
||||||
// threads to complete an HTTP upgrade.
|
// threads to complete an HTTP upgrade.
|
||||||
class nsCompleteUpgradeData
|
class nsCompleteUpgradeData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsCompleteUpgradeData(nsAHttpConnection *aConn,
|
nsCompleteUpgradeData(nsAHttpConnection *aConn,
|
||||||
nsIHttpUpgradeListener *aListener)
|
nsIHttpUpgradeListener *aListener)
|
||||||
: mConn(aConn), mUpgradeListener(aListener) {}
|
: mConn(aConn), mUpgradeListener(aListener) {}
|
||||||
|
|
||||||
nsRefPtr<nsAHttpConnection> mConn;
|
nsRefPtr<nsAHttpConnection> mConn;
|
||||||
nsCOMPtr<nsIHttpUpgradeListener> mUpgradeListener;
|
nsCOMPtr<nsIHttpUpgradeListener> mUpgradeListener;
|
||||||
};
|
};
|
||||||
|
@ -392,7 +392,7 @@ nsHttpConnectionMgr::CompleteUpgrade(nsAHttpConnection *aConn,
|
||||||
delete data;
|
delete data;
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHttpConnectionMgr::UpdateParam(nsParamName name, uint16_t value)
|
nsHttpConnectionMgr::UpdateParam(nsParamName name, uint16_t value)
|
||||||
{
|
{
|
||||||
|
@ -432,7 +432,7 @@ nsresult
|
||||||
nsHttpConnectionMgr::UpdateRequestTokenBucket(EventTokenBucket *aBucket)
|
nsHttpConnectionMgr::UpdateRequestTokenBucket(EventTokenBucket *aBucket)
|
||||||
{
|
{
|
||||||
nsRefPtr<EventTokenBucket> bucket(aBucket);
|
nsRefPtr<EventTokenBucket> bucket(aBucket);
|
||||||
|
|
||||||
// Call From main thread when a new EventTokenBucket has been made in order
|
// Call From main thread when a new EventTokenBucket has been made in order
|
||||||
// to post the new value to the socket thread.
|
// to post the new value to the socket thread.
|
||||||
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgUpdateRequestTokenBucket,
|
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgUpdateRequestTokenBucket,
|
||||||
|
@ -457,7 +457,7 @@ nsHttpConnectionMgr::LookupConnectionEntry(nsHttpConnectionInfo *ci,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
nsConnectionEntry *ent = mCT.Get(ci->HashKey());
|
nsConnectionEntry *ent = mCT.Get(ci->HashKey());
|
||||||
|
|
||||||
// If there is no sign of coalescing (or it is disabled) then just
|
// If there is no sign of coalescing (or it is disabled) then just
|
||||||
// return the primary hash lookup
|
// return the primary hash lookup
|
||||||
if (!ent || !ent->mUsingSpdy || ent->mCoalescingKey.IsEmpty())
|
if (!ent || !ent->mUsingSpdy || ent->mCoalescingKey.IsEmpty())
|
||||||
|
@ -478,10 +478,10 @@ nsHttpConnectionMgr::LookupConnectionEntry(nsHttpConnectionInfo *ci,
|
||||||
if (preferred->mIdleConns.Contains(conn))
|
if (preferred->mIdleConns.Contains(conn))
|
||||||
return preferred;
|
return preferred;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trans && preferred->mPendingQ.Contains(trans))
|
if (trans && preferred->mPendingQ.Contains(trans))
|
||||||
return preferred;
|
return preferred;
|
||||||
|
|
||||||
// Neither conn nor trans found in preferred, use the default entry
|
// Neither conn nor trans found in preferred, use the default entry
|
||||||
return ent;
|
return ent;
|
||||||
}
|
}
|
||||||
|
@ -521,7 +521,7 @@ nsHttpConnectionMgr::ReportSpdyConnection(nsHttpConnection *conn,
|
||||||
bool usingSpdy)
|
bool usingSpdy)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
|
|
||||||
nsConnectionEntry *ent = LookupConnectionEntry(conn->ConnectionInfo(),
|
nsConnectionEntry *ent = LookupConnectionEntry(conn->ConnectionInfo(),
|
||||||
conn, nullptr);
|
conn, nullptr);
|
||||||
|
|
||||||
|
@ -552,7 +552,7 @@ nsHttpConnectionMgr::ReportSpdyConnection(nsHttpConnection *conn,
|
||||||
LOG(("ReportSpdyConnection %s %s ent=%p preferred=%p\n",
|
LOG(("ReportSpdyConnection %s %s ent=%p preferred=%p\n",
|
||||||
ent->mConnInfo->Host(), ent->mCoalescingKey.get(),
|
ent->mConnInfo->Host(), ent->mCoalescingKey.get(),
|
||||||
ent, preferred));
|
ent, preferred));
|
||||||
|
|
||||||
if (!preferred) {
|
if (!preferred) {
|
||||||
if (!ent->mCoalescingKey.IsEmpty()) {
|
if (!ent->mCoalescingKey.IsEmpty()) {
|
||||||
mSpdyPreferredHash.Put(ent->mCoalescingKey, ent);
|
mSpdyPreferredHash.Put(ent->mCoalescingKey, ent);
|
||||||
|
@ -675,11 +675,11 @@ nsHttpConnectionMgr::ReportSpdyAlternateProtocol(nsHttpConnection *conn)
|
||||||
// Check to see if this is already present
|
// Check to see if this is already present
|
||||||
if (mAlternateProtocolHash.Contains(hostPortKey))
|
if (mAlternateProtocolHash.Contains(hostPortKey))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (mAlternateProtocolHash.Count() > 2000)
|
if (mAlternateProtocolHash.Count() > 2000)
|
||||||
mAlternateProtocolHash.EnumerateEntries(&TrimAlternateProtocolHash,
|
mAlternateProtocolHash.EnumerateEntries(&TrimAlternateProtocolHash,
|
||||||
this);
|
this);
|
||||||
|
|
||||||
mAlternateProtocolHash.PutEntry(hostPortKey);
|
mAlternateProtocolHash.PutEntry(hostPortKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,7 +698,7 @@ nsHttpConnectionMgr::TrimAlternateProtocolHash(nsCStringHashKey *entry,
|
||||||
void *closure)
|
void *closure)
|
||||||
{
|
{
|
||||||
nsHttpConnectionMgr *self = (nsHttpConnectionMgr *) closure;
|
nsHttpConnectionMgr *self = (nsHttpConnectionMgr *) closure;
|
||||||
|
|
||||||
if (self->mAlternateProtocolHash.Count() > 2000)
|
if (self->mAlternateProtocolHash.Count() > 2000)
|
||||||
return PL_DHASH_REMOVE;
|
return PL_DHASH_REMOVE;
|
||||||
return PL_DHASH_STOP;
|
return PL_DHASH_STOP;
|
||||||
|
@ -722,7 +722,7 @@ nsHttpConnectionMgr::GetSpdyPreferredEnt(nsConnectionEntry *aOriginalEntry)
|
||||||
// if there is no preferred host or it is no longer using spdy
|
// if there is no preferred host or it is no longer using spdy
|
||||||
// then skip pooling
|
// then skip pooling
|
||||||
if (!preferred || !preferred->mUsingSpdy)
|
if (!preferred || !preferred->mUsingSpdy)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// if there is not an active spdy session in this entry then
|
// if there is not an active spdy session in this entry then
|
||||||
// we cannot pool because the cert upon activation may not
|
// we cannot pool because the cert upon activation may not
|
||||||
|
@ -758,7 +758,7 @@ nsHttpConnectionMgr::GetSpdyPreferredEnt(nsConnectionEntry *aOriginalEntry)
|
||||||
nsCOMPtr<nsISupports> securityInfo;
|
nsCOMPtr<nsISupports> securityInfo;
|
||||||
nsCOMPtr<nsISSLSocketControl> sslSocketControl;
|
nsCOMPtr<nsISSLSocketControl> sslSocketControl;
|
||||||
nsAutoCString negotiatedNPN;
|
nsAutoCString negotiatedNPN;
|
||||||
|
|
||||||
activeSpdy->GetSecurityInfo(getter_AddRefs(securityInfo));
|
activeSpdy->GetSecurityInfo(getter_AddRefs(securityInfo));
|
||||||
if (!securityInfo) {
|
if (!securityInfo) {
|
||||||
NS_WARNING("cannot obtain spdy security info");
|
NS_WARNING("cannot obtain spdy security info");
|
||||||
|
@ -813,7 +813,7 @@ nsHttpConnectionMgr::RemoveSpdyPreferredEnt(nsACString &aHashKey)
|
||||||
{
|
{
|
||||||
if (aHashKey.IsEmpty())
|
if (aHashKey.IsEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mSpdyPreferredHash.Remove(aHashKey);
|
mSpdyPreferredHash.Remove(aHashKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -936,7 +936,7 @@ nsHttpConnectionMgr::PruneDeadConnectionsCB(const nsACString &key,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If time to next expire found is shorter than time to next wake-up, we need to
|
// If time to next expire found is shorter than time to next wake-up, we need to
|
||||||
// change the time for next wake-up.
|
// change the time for next wake-up.
|
||||||
if (timeToNextExpire != UINT32_MAX) {
|
if (timeToNextExpire != UINT32_MAX) {
|
||||||
|
@ -1126,11 +1126,11 @@ public:
|
||||||
, mData(data)
|
, mData(data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~nsHttpPipelineFeedback()
|
~nsHttpPipelineFeedback()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<nsHttpConnectionInfo> mConnInfo;
|
nsRefPtr<nsHttpConnectionInfo> mConnInfo;
|
||||||
nsRefPtr<nsHttpConnection> mConn;
|
nsRefPtr<nsHttpConnection> mConn;
|
||||||
nsHttpConnectionMgr::PipelineFeedbackInfoType mInfo;
|
nsHttpConnectionMgr::PipelineFeedbackInfoType mInfo;
|
||||||
|
@ -1242,7 +1242,7 @@ nsHttpConnectionMgr::AtActiveConnectionLimit(nsConnectionEntry *ent, uint32_t ca
|
||||||
// Add in the in-progress tcp connections, we will assume they are
|
// Add in the in-progress tcp connections, we will assume they are
|
||||||
// keepalive enabled.
|
// keepalive enabled.
|
||||||
// Exclude half-open's that has already created a usable connection.
|
// Exclude half-open's that has already created a usable connection.
|
||||||
// This prevents the limit being stuck on ipv6 connections that
|
// This prevents the limit being stuck on ipv6 connections that
|
||||||
// eventually time out after typical 21 seconds of no ACK+SYN reply.
|
// eventually time out after typical 21 seconds of no ACK+SYN reply.
|
||||||
uint32_t totalCount =
|
uint32_t totalCount =
|
||||||
ent->mActiveConns.Length() + ent->UnconnectedHalfOpens();
|
ent->mActiveConns.Length() + ent->UnconnectedHalfOpens();
|
||||||
|
@ -1274,7 +1274,7 @@ nsHttpConnectionMgr::ClosePersistentConnections(nsConnectionEntry *ent)
|
||||||
conn->Close(NS_ERROR_ABORT);
|
conn->Close(NS_ERROR_ABORT);
|
||||||
NS_RELEASE(conn);
|
NS_RELEASE(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t activeCount = ent->mActiveConns.Length();
|
int32_t activeCount = ent->mActiveConns.Length();
|
||||||
for (int32_t i=0; i < activeCount; i++)
|
for (int32_t i=0; i < activeCount; i++)
|
||||||
ent->mActiveConns[i]->DontReuse();
|
ent->mActiveConns[i]->DontReuse();
|
||||||
|
@ -1298,7 +1298,7 @@ nsHttpConnectionMgr::RestrictConnections(nsConnectionEntry *ent)
|
||||||
// If this host is trying to negotiate a SPDY session right now,
|
// If this host is trying to negotiate a SPDY session right now,
|
||||||
// don't create any new ssl connections until the result of the
|
// don't create any new ssl connections until the result of the
|
||||||
// negotiation is known.
|
// negotiation is known.
|
||||||
|
|
||||||
bool doRestrict = ent->mConnInfo->UsingSSL() &&
|
bool doRestrict = ent->mConnInfo->UsingSSL() &&
|
||||||
gHttpHandler->IsSpdyEnabled() &&
|
gHttpHandler->IsSpdyEnabled() &&
|
||||||
(!ent->mTestedSpdy || ent->mUsingSpdy) &&
|
(!ent->mTestedSpdy || ent->mUsingSpdy) &&
|
||||||
|
@ -1307,7 +1307,7 @@ nsHttpConnectionMgr::RestrictConnections(nsConnectionEntry *ent)
|
||||||
// If there are no restrictions, we are done
|
// If there are no restrictions, we are done
|
||||||
if (!doRestrict)
|
if (!doRestrict)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// If the restriction is based on a tcp handshake in progress
|
// If the restriction is based on a tcp handshake in progress
|
||||||
// let that connect and then see if it was SPDY or not
|
// let that connect and then see if it was SPDY or not
|
||||||
if (ent->UnconnectedHalfOpens())
|
if (ent->UnconnectedHalfOpens())
|
||||||
|
@ -1345,7 +1345,7 @@ nsHttpConnectionMgr::MakeNewConnection(nsConnectionEntry *ent,
|
||||||
LOG(("nsHttpConnectionMgr::MakeNewConnection %p ent=%p trans=%p",
|
LOG(("nsHttpConnectionMgr::MakeNewConnection %p ent=%p trans=%p",
|
||||||
this, ent, trans));
|
this, ent, trans));
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
|
|
||||||
uint32_t halfOpenLength = ent->mHalfOpens.Length();
|
uint32_t halfOpenLength = ent->mHalfOpens.Length();
|
||||||
for (uint32_t i = 0; i < halfOpenLength; i++) {
|
for (uint32_t i = 0; i < halfOpenLength; i++) {
|
||||||
if (ent->mHalfOpens[i]->IsSpeculative()) {
|
if (ent->mHalfOpens[i]->IsSpeculative()) {
|
||||||
|
@ -1416,7 +1416,7 @@ nsHttpConnectionMgr::AddToShortestPipeline(nsConnectionEntry *ent,
|
||||||
ent->CreditPenalty();
|
ent->CreditPenalty();
|
||||||
maxdepth = ent->MaxPipelineDepth(classification);
|
maxdepth = ent->MaxPipelineDepth(classification);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ent->PipelineState() == PS_RED)
|
if (ent->PipelineState() == PS_RED)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1504,7 +1504,7 @@ bool
|
||||||
nsHttpConnectionMgr::IsUnderPressure(nsConnectionEntry *ent,
|
nsHttpConnectionMgr::IsUnderPressure(nsConnectionEntry *ent,
|
||||||
nsHttpTransaction::Classifier classification)
|
nsHttpTransaction::Classifier classification)
|
||||||
{
|
{
|
||||||
// A connection entry is declared to be "under pressure" if most of the
|
// A connection entry is declared to be "under pressure" if most of the
|
||||||
// allowed parallel connections are already used up. In that case we want to
|
// allowed parallel connections are already used up. In that case we want to
|
||||||
// favor existing pipelines over more parallelism so as to reserve any
|
// favor existing pipelines over more parallelism so as to reserve any
|
||||||
// unused parallel connections for types that don't have existing pipelines.
|
// unused parallel connections for types that don't have existing pipelines.
|
||||||
|
@ -1516,7 +1516,7 @@ nsHttpConnectionMgr::IsUnderPressure(nsConnectionEntry *ent,
|
||||||
// using 3 or more of the connections. Failure to do this could result in
|
// using 3 or more of the connections. Failure to do this could result in
|
||||||
// one class (e.g. images) establishing self replenishing queues on all the
|
// one class (e.g. images) establishing self replenishing queues on all the
|
||||||
// connections that would starve the other transaction types.
|
// connections that would starve the other transaction types.
|
||||||
|
|
||||||
int32_t currentConns = ent->mActiveConns.Length();
|
int32_t currentConns = ent->mActiveConns.Length();
|
||||||
int32_t maxConns =
|
int32_t maxConns =
|
||||||
(ent->mConnInfo->UsingHttpProxy() && !ent->mConnInfo->UsingConnect()) ?
|
(ent->mConnInfo->UsingHttpProxy() && !ent->mConnInfo->UsingConnect()) ?
|
||||||
|
@ -1532,7 +1532,7 @@ nsHttpConnectionMgr::IsUnderPressure(nsConnectionEntry *ent,
|
||||||
if (classification == ent->mActiveConns[i]->Classification())
|
if (classification == ent->mActiveConns[i]->Classification())
|
||||||
if (++sameClass == 3)
|
if (++sameClass == 3)
|
||||||
return true; /* prefer pipeline */
|
return true; /* prefer pipeline */
|
||||||
|
|
||||||
return false; /* normal behavior */
|
return false; /* normal behavior */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1651,7 +1651,7 @@ nsHttpConnectionMgr::TryDispatchTransaction(nsConnectionEntry *ent,
|
||||||
mNumIdleConns--;
|
mNumIdleConns--;
|
||||||
nsHttpConnection *temp = conn;
|
nsHttpConnection *temp = conn;
|
||||||
NS_RELEASE(temp);
|
NS_RELEASE(temp);
|
||||||
|
|
||||||
// we check if the connection can be reused before even checking if
|
// we check if the connection can be reused before even checking if
|
||||||
// it is a "matching" connection.
|
// it is a "matching" connection.
|
||||||
if (!conn->CanReuse()) {
|
if (!conn->CanReuse()) {
|
||||||
|
@ -1697,14 +1697,14 @@ nsHttpConnectionMgr::TryDispatchTransaction(nsConnectionEntry *ent,
|
||||||
// this function returns NOT_AVAILABLE for asynchronous connects
|
// this function returns NOT_AVAILABLE for asynchronous connects
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rv != NS_ERROR_NOT_AVAILABLE) {
|
if (rv != NS_ERROR_NOT_AVAILABLE) {
|
||||||
// not available return codes should try next step as they are
|
// not available return codes should try next step as they are
|
||||||
// not hard errors. Other codes should stop now
|
// not hard errors. Other codes should stop now
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// step 5
|
// step 5
|
||||||
if (caps & NS_HTTP_ALLOW_PIPELINING) {
|
if (caps & NS_HTTP_ALLOW_PIPELINING) {
|
||||||
if (AddToShortestPipeline(ent, trans,
|
if (AddToShortestPipeline(ent, trans,
|
||||||
|
@ -1713,7 +1713,7 @@ nsHttpConnectionMgr::TryDispatchTransaction(nsConnectionEntry *ent,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// step 6
|
// step 6
|
||||||
return NS_ERROR_NOT_AVAILABLE; /* queue it */
|
return NS_ERROR_NOT_AVAILABLE; /* queue it */
|
||||||
}
|
}
|
||||||
|
@ -1836,7 +1836,7 @@ nsHttpConnectionMgr::DispatchAbstractTransaction(nsConnectionEntry *ent,
|
||||||
|
|
||||||
// As transaction goes out of scope it will drop the last refernece to the
|
// As transaction goes out of scope it will drop the last refernece to the
|
||||||
// pipeline if activation failed, in which case this will destroy
|
// pipeline if activation failed, in which case this will destroy
|
||||||
// the pipeline, which will cause each the transactions owned by the
|
// the pipeline, which will cause each the transactions owned by the
|
||||||
// pipeline to be restarted.
|
// pipeline to be restarted.
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -1854,7 +1854,7 @@ nsHttpConnectionMgr::BuildPipeline(nsConnectionEntry *ent,
|
||||||
|
|
||||||
/* the first transaction can go in unconditionally - 1 transaction
|
/* the first transaction can go in unconditionally - 1 transaction
|
||||||
on a nsHttpPipeline object is not a real HTTP pipeline */
|
on a nsHttpPipeline object is not a real HTTP pipeline */
|
||||||
|
|
||||||
nsRefPtr<nsHttpPipeline> pipeline = new nsHttpPipeline();
|
nsRefPtr<nsHttpPipeline> pipeline = new nsHttpPipeline();
|
||||||
pipeline->AddTransaction(firstTrans);
|
pipeline->AddTransaction(firstTrans);
|
||||||
NS_ADDREF(*result = pipeline);
|
NS_ADDREF(*result = pipeline);
|
||||||
|
@ -1932,7 +1932,7 @@ nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans)
|
||||||
LOG((" ProcessNewTransaction Dispatch Immediately trans=%p\n", trans));
|
LOG((" ProcessNewTransaction Dispatch Immediately trans=%p\n", trans));
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rv == NS_ERROR_NOT_AVAILABLE) {
|
if (rv == NS_ERROR_NOT_AVAILABLE) {
|
||||||
LOG((" adding transaction to pending queue "
|
LOG((" adding transaction to pending queue "
|
||||||
"[trans=%p pending-count=%u]\n",
|
"[trans=%p pending-count=%u]\n",
|
||||||
|
@ -1987,7 +1987,7 @@ nsHttpConnectionMgr::CreateTransport(nsConnectionEntry *ent,
|
||||||
bool speculative)
|
bool speculative)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
|
|
||||||
nsRefPtr<nsHalfOpenSocket> sock = new nsHalfOpenSocket(ent, trans, caps);
|
nsRefPtr<nsHalfOpenSocket> sock = new nsHalfOpenSocket(ent, trans, caps);
|
||||||
nsresult rv = sock->SetupPrimaryStreams();
|
nsresult rv = sock->SetupPrimaryStreams();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
@ -2020,7 +2020,7 @@ nsHttpConnectionMgr::ProcessSpdyPendingQ(nsConnectionEntry *ent)
|
||||||
if (!(trans->Caps() & NS_HTTP_ALLOW_KEEPALIVE) ||
|
if (!(trans->Caps() & NS_HTTP_ALLOW_KEEPALIVE) ||
|
||||||
trans->Caps() & NS_HTTP_DISALLOW_SPDY)
|
trans->Caps() & NS_HTTP_DISALLOW_SPDY)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ent->mPendingQ.RemoveElementAt(index);
|
ent->mPendingQ.RemoveElementAt(index);
|
||||||
|
|
||||||
nsresult rv = DispatchTransaction(ent, trans, conn);
|
nsresult rv = DispatchTransaction(ent, trans, conn);
|
||||||
|
@ -2068,9 +2068,9 @@ nsHttpConnectionMgr::GetSpdyPreferredConn(nsConnectionEntry *ent)
|
||||||
ent->mUsingSpdy = true;
|
ent->mUsingSpdy = true;
|
||||||
else
|
else
|
||||||
preferred = ent;
|
preferred = ent;
|
||||||
|
|
||||||
nsHttpConnection *conn = nullptr;
|
nsHttpConnection *conn = nullptr;
|
||||||
|
|
||||||
if (preferred->mUsingSpdy) {
|
if (preferred->mUsingSpdy) {
|
||||||
for (uint32_t index = 0;
|
for (uint32_t index = 0;
|
||||||
index < preferred->mActiveConns.Length();
|
index < preferred->mActiveConns.Length();
|
||||||
|
@ -2081,7 +2081,7 @@ nsHttpConnectionMgr::GetSpdyPreferredConn(nsConnectionEntry *ent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2100,9 +2100,9 @@ nsHttpConnectionMgr::OnMsgShutdown(int32_t, void *param)
|
||||||
mTimeoutTick = nullptr;
|
mTimeoutTick = nullptr;
|
||||||
mTimeoutTickArmed = false;
|
mTimeoutTickArmed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// signal shutdown complete
|
// signal shutdown complete
|
||||||
nsRefPtr<nsIRunnable> runnable =
|
nsRefPtr<nsIRunnable> runnable =
|
||||||
new nsConnEvent(this, &nsHttpConnectionMgr::OnMsgShutdownConfirm,
|
new nsConnEvent(this, &nsHttpConnectionMgr::OnMsgShutdownConfirm,
|
||||||
0, param);
|
0, param);
|
||||||
NS_DispatchToMainThread(runnable);
|
NS_DispatchToMainThread(runnable);
|
||||||
|
@ -2251,7 +2251,7 @@ nsHttpConnectionMgr::OnMsgReclaimConnection(int32_t, void *param)
|
||||||
|
|
||||||
nsHttpConnection *conn = (nsHttpConnection *) param;
|
nsHttpConnection *conn = (nsHttpConnection *) param;
|
||||||
|
|
||||||
//
|
//
|
||||||
// 1) remove the connection from the active list
|
// 1) remove the connection from the active list
|
||||||
// 2) if keep-alive, add connection to idle list
|
// 2) if keep-alive, add connection to idle list
|
||||||
// 3) post event to process the pending transaction queue
|
// 3) post event to process the pending transaction queue
|
||||||
|
@ -2327,7 +2327,7 @@ nsHttpConnectionMgr::OnMsgReclaimConnection(int32_t, void *param)
|
||||||
conn->Close(NS_ERROR_ABORT);
|
conn->Close(NS_ERROR_ABORT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OnMsgProcessPendingQ(0, ci); // releases |ci|
|
OnMsgProcessPendingQ(0, ci); // releases |ci|
|
||||||
NS_RELEASE(conn);
|
NS_RELEASE(conn);
|
||||||
}
|
}
|
||||||
|
@ -2401,7 +2401,7 @@ nsHttpConnectionMgr::OnMsgProcessFeedback(int32_t, void *param)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
nsHttpPipelineFeedback *fb = (nsHttpPipelineFeedback *)param;
|
nsHttpPipelineFeedback *fb = (nsHttpPipelineFeedback *)param;
|
||||||
|
|
||||||
PipelineFeedbackInfo(fb->mConnInfo, fb->mInfo, fb->mConn, fb->mData);
|
PipelineFeedbackInfo(fb->mConnInfo, fb->mInfo, fb->mConn, fb->mData);
|
||||||
delete fb;
|
delete fb;
|
||||||
}
|
}
|
||||||
|
@ -2633,7 +2633,7 @@ nsHttpConnectionMgr::nsHalfOpenSocket::~nsHalfOpenSocket()
|
||||||
MOZ_ASSERT(!mBackupStreamOut);
|
MOZ_ASSERT(!mBackupStreamOut);
|
||||||
MOZ_ASSERT(!mSynTimer);
|
MOZ_ASSERT(!mSynTimer);
|
||||||
LOG(("Destroying nsHalfOpenSocket [this=%p]\n", this));
|
LOG(("Destroying nsHalfOpenSocket [this=%p]\n", this));
|
||||||
|
|
||||||
if (mEnt)
|
if (mEnt)
|
||||||
mEnt->RemoveHalfOpen(this);
|
mEnt->RemoveHalfOpen(this);
|
||||||
}
|
}
|
||||||
|
@ -2664,7 +2664,7 @@ nsHalfOpenSocket::SetupStreams(nsISocketTransport **transport,
|
||||||
mEnt->mConnInfo->ProxyInfo(),
|
mEnt->mConnInfo->ProxyInfo(),
|
||||||
getter_AddRefs(socketTransport));
|
getter_AddRefs(socketTransport));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
uint32_t tmpFlags = 0;
|
uint32_t tmpFlags = 0;
|
||||||
if (mCaps & NS_HTTP_REFRESH_DNS)
|
if (mCaps & NS_HTTP_REFRESH_DNS)
|
||||||
tmpFlags = nsISocketTransport::BYPASS_CACHE;
|
tmpFlags = nsISocketTransport::BYPASS_CACHE;
|
||||||
|
@ -2770,7 +2770,7 @@ nsHttpConnectionMgr::nsHalfOpenSocket::SetupBackupTimer()
|
||||||
{
|
{
|
||||||
uint16_t timeout = gHttpHandler->GetIdleSynTimeout();
|
uint16_t timeout = gHttpHandler->GetIdleSynTimeout();
|
||||||
MOZ_ASSERT(!mSynTimer, "timer already initd");
|
MOZ_ASSERT(!mSynTimer, "timer already initd");
|
||||||
|
|
||||||
if (timeout && !mTransaction->IsDone()) {
|
if (timeout && !mTransaction->IsDone()) {
|
||||||
// Setup the timer that will establish a backup socket
|
// Setup the timer that will establish a backup socket
|
||||||
// if we do not get a writable event on the main one.
|
// if we do not get a writable event on the main one.
|
||||||
|
@ -2863,12 +2863,12 @@ nsHalfOpenSocket::OnOutputStreamReady(nsIAsyncOutputStream *out)
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
MOZ_ASSERT(out == mStreamOut || out == mBackupStreamOut,
|
MOZ_ASSERT(out == mStreamOut || out == mBackupStreamOut,
|
||||||
"stream mismatch");
|
"stream mismatch");
|
||||||
LOG(("nsHalfOpenSocket::OnOutputStreamReady [this=%p ent=%s %s]\n",
|
LOG(("nsHalfOpenSocket::OnOutputStreamReady [this=%p ent=%s %s]\n",
|
||||||
this, mEnt->mConnInfo->Host(),
|
this, mEnt->mConnInfo->Host(),
|
||||||
out == mStreamOut ? "primary" : "backup"));
|
out == mStreamOut ? "primary" : "backup"));
|
||||||
int32_t index;
|
int32_t index;
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
gHttpHandler->ConnMgr()->RecvdConnect();
|
gHttpHandler->ConnMgr()->RecvdConnect();
|
||||||
|
|
||||||
CancelBackupTimer();
|
CancelBackupTimer();
|
||||||
|
@ -3146,7 +3146,7 @@ nsHttpConnectionMgr::nsConnectionEntry::PipelineState()
|
||||||
{
|
{
|
||||||
return mPipelineState;
|
return mPipelineState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsHttpConnectionMgr::
|
nsHttpConnectionMgr::
|
||||||
nsConnectionEntry::OnPipelineFeedbackInfo(
|
nsConnectionEntry::OnPipelineFeedbackInfo(
|
||||||
|
@ -3155,14 +3155,14 @@ nsConnectionEntry::OnPipelineFeedbackInfo(
|
||||||
uint32_t data)
|
uint32_t data)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
|
|
||||||
if (mPipelineState == PS_YELLOW) {
|
if (mPipelineState == PS_YELLOW) {
|
||||||
if (info & kPipelineInfoTypeBad)
|
if (info & kPipelineInfoTypeBad)
|
||||||
mYellowBadEvents++;
|
mYellowBadEvents++;
|
||||||
else if (info & (kPipelineInfoTypeNeutral | kPipelineInfoTypeGood))
|
else if (info & (kPipelineInfoTypeNeutral | kPipelineInfoTypeGood))
|
||||||
mYellowGoodEvents++;
|
mYellowGoodEvents++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mPipelineState == PS_GREEN && info == GoodCompletedOK) {
|
if (mPipelineState == PS_GREEN && info == GoodCompletedOK) {
|
||||||
int32_t depth = data;
|
int32_t depth = data;
|
||||||
LOG(("Transaction completed at pipeline depth of %d. Host = %s\n",
|
LOG(("Transaction completed at pipeline depth of %d. Host = %s\n",
|
||||||
|
@ -3204,7 +3204,7 @@ nsConnectionEntry::OnPipelineFeedbackInfo(
|
||||||
|
|
||||||
// Red* events impact the host globally via mPipeliningPenalty, while
|
// Red* events impact the host globally via mPipeliningPenalty, while
|
||||||
// Bad* events impact the per class penalty.
|
// Bad* events impact the per class penalty.
|
||||||
|
|
||||||
// The individual penalties should be < 16bit-signed-maxint - 25000
|
// The individual penalties should be < 16bit-signed-maxint - 25000
|
||||||
// (approx 7500). Penalties are paid-off either when something promising
|
// (approx 7500). Penalties are paid-off either when something promising
|
||||||
// happens (a successful transaction, or promising headers) or when
|
// happens (a successful transaction, or promising headers) or when
|
||||||
|
@ -3242,12 +3242,12 @@ nsConnectionEntry::OnPipelineFeedbackInfo(
|
||||||
default:
|
default:
|
||||||
MOZ_ASSERT(false, "Unknown Bad/Red Pipeline Feedback Event");
|
MOZ_ASSERT(false, "Unknown Bad/Red Pipeline Feedback Event");
|
||||||
}
|
}
|
||||||
|
|
||||||
const int16_t kPenalty = 25000;
|
const int16_t kPenalty = 25000;
|
||||||
mPipeliningPenalty = std::min(mPipeliningPenalty, kPenalty);
|
mPipeliningPenalty = std::min(mPipeliningPenalty, kPenalty);
|
||||||
mPipeliningClassPenalty[classification] =
|
mPipeliningClassPenalty[classification] =
|
||||||
std::min(mPipeliningClassPenalty[classification], kPenalty);
|
std::min(mPipeliningClassPenalty[classification], kPenalty);
|
||||||
|
|
||||||
LOG(("Assessing red penalty to %s class %d for event %d. "
|
LOG(("Assessing red penalty to %s class %d for event %d. "
|
||||||
"Penalty now %d, throttle[%d] = %d\n", mConnInfo->Host(),
|
"Penalty now %d, throttle[%d] = %d\n", mConnInfo->Host(),
|
||||||
classification, info, mPipeliningPenalty, classification,
|
classification, info, mPipeliningPenalty, classification,
|
||||||
|
@ -3309,7 +3309,7 @@ nsConnectionEntry::CreditPenalty()
|
||||||
{
|
{
|
||||||
if (mLastCreditTime.IsNull())
|
if (mLastCreditTime.IsNull())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Decrease penalty values by 1 for every 16 seconds
|
// Decrease penalty values by 1 for every 16 seconds
|
||||||
// (i.e 3.7 per minute, or 1000 every 4h20m)
|
// (i.e 3.7 per minute, or 1000 every 4h20m)
|
||||||
|
|
||||||
|
@ -3317,14 +3317,14 @@ nsConnectionEntry::CreditPenalty()
|
||||||
TimeDuration elapsedTime = now - mLastCreditTime;
|
TimeDuration elapsedTime = now - mLastCreditTime;
|
||||||
uint32_t creditsEarned =
|
uint32_t creditsEarned =
|
||||||
static_cast<uint32_t>(elapsedTime.ToSeconds()) >> 4;
|
static_cast<uint32_t>(elapsedTime.ToSeconds()) >> 4;
|
||||||
|
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
if (creditsEarned > 0) {
|
if (creditsEarned > 0) {
|
||||||
mPipeliningPenalty =
|
mPipeliningPenalty =
|
||||||
std::max(int32_t(mPipeliningPenalty - creditsEarned), 0);
|
std::max(int32_t(mPipeliningPenalty - creditsEarned), 0);
|
||||||
if (mPipeliningPenalty > 0)
|
if (mPipeliningPenalty > 0)
|
||||||
failed = true;
|
failed = true;
|
||||||
|
|
||||||
for (int32_t i = 0; i < nsAHttpTransaction::CLASS_MAX; ++i) {
|
for (int32_t i = 0; i < nsAHttpTransaction::CLASS_MAX; ++i) {
|
||||||
mPipeliningClassPenalty[i] =
|
mPipeliningClassPenalty[i] =
|
||||||
std::max(int32_t(mPipeliningClassPenalty[i] - creditsEarned), 0);
|
std::max(int32_t(mPipeliningClassPenalty[i] - creditsEarned), 0);
|
||||||
|
@ -3349,7 +3349,7 @@ nsConnectionEntry::CreditPenalty()
|
||||||
mConnInfo->Host()));
|
mConnInfo->Host()));
|
||||||
mPipelineState = PS_YELLOW;
|
mPipelineState = PS_YELLOW;
|
||||||
mYellowConnection = nullptr;
|
mYellowConnection = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
|
@ -3357,7 +3357,7 @@ nsHttpConnectionMgr::
|
||||||
nsConnectionEntry::MaxPipelineDepth(nsAHttpTransaction::Classifier aClass)
|
nsConnectionEntry::MaxPipelineDepth(nsAHttpTransaction::Classifier aClass)
|
||||||
{
|
{
|
||||||
// Still subject to configuration limit no matter return value
|
// Still subject to configuration limit no matter return value
|
||||||
|
|
||||||
if ((mPipelineState == PS_RED) || (mPipeliningClassPenalty[aClass] > 0))
|
if ((mPipelineState == PS_RED) || (mPipeliningClassPenalty[aClass] > 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ public:
|
||||||
nsresult SpeculativeConnect(nsHttpConnectionInfo *,
|
nsresult SpeculativeConnect(nsHttpConnectionInfo *,
|
||||||
nsIInterfaceRequestor *);
|
nsIInterfaceRequestor *);
|
||||||
|
|
||||||
// called when a connection is done processing a transaction. if the
|
// called when a connection is done processing a transaction. if the
|
||||||
// connection can be reused then it will be added to the idle list, else
|
// connection can be reused then it will be added to the idle list, else
|
||||||
// it will be closed.
|
// it will be closed.
|
||||||
nsresult ReclaimConnection(nsHttpConnection *conn);
|
nsresult ReclaimConnection(nsHttpConnection *conn);
|
||||||
|
@ -158,7 +158,7 @@ public:
|
||||||
// Used when a HTTP Server response header that is on the banned from
|
// Used when a HTTP Server response header that is on the banned from
|
||||||
// pipelining list is received
|
// pipelining list is received
|
||||||
RedBannedServer = kPipelineInfoTypeRed | kPipelineInfoTypeBad | 0x0002,
|
RedBannedServer = kPipelineInfoTypeRed | kPipelineInfoTypeBad | 0x0002,
|
||||||
|
|
||||||
// Used when a response is terminated early, when it fails an
|
// Used when a response is terminated early, when it fails an
|
||||||
// integrity check such as assoc-req or when a 304 contained a Last-Modified
|
// integrity check such as assoc-req or when a 304 contained a Last-Modified
|
||||||
// differnet than the entry being validated.
|
// differnet than the entry being validated.
|
||||||
|
@ -184,7 +184,7 @@ public:
|
||||||
// Used when a response is received that is not framed with either chunked
|
// Used when a response is received that is not framed with either chunked
|
||||||
// encoding or a complete content length.
|
// encoding or a complete content length.
|
||||||
BadInsufficientFraming = kPipelineInfoTypeBad | 0x0008,
|
BadInsufficientFraming = kPipelineInfoTypeBad | 0x0008,
|
||||||
|
|
||||||
// Used when a very large response is recevied in a potential pipelining
|
// Used when a very large response is recevied in a potential pipelining
|
||||||
// context. Large responses cause head of line blocking.
|
// context. Large responses cause head of line blocking.
|
||||||
BadUnexpectedLarge = kPipelineInfoTypeBad | 0x000B,
|
BadUnexpectedLarge = kPipelineInfoTypeBad | 0x000B,
|
||||||
|
@ -196,7 +196,7 @@ public:
|
||||||
// Used when a response is received successfully to a pipelined request.
|
// Used when a response is received successfully to a pipelined request.
|
||||||
GoodCompletedOK = kPipelineInfoTypeGood | 0x000A
|
GoodCompletedOK = kPipelineInfoTypeGood | 0x000A
|
||||||
};
|
};
|
||||||
|
|
||||||
// called to provide information relevant to the pipelining manager
|
// called to provide information relevant to the pipelining manager
|
||||||
// may be called from any thread
|
// may be called from any thread
|
||||||
void PipelineFeedbackInfo(nsHttpConnectionInfo *,
|
void PipelineFeedbackInfo(nsHttpConnectionInfo *,
|
||||||
|
@ -236,7 +236,7 @@ public:
|
||||||
// in future sessions to speed up the opening portions of the connection.
|
// in future sessions to speed up the opening portions of the connection.
|
||||||
void ReportSpdyCWNDSetting(nsHttpConnectionInfo *host, uint32_t cwndValue);
|
void ReportSpdyCWNDSetting(nsHttpConnectionInfo *host, uint32_t cwndValue);
|
||||||
uint32_t GetSpdyCWNDSetting(nsHttpConnectionInfo *host);
|
uint32_t GetSpdyCWNDSetting(nsHttpConnectionInfo *host);
|
||||||
|
|
||||||
bool SupportsPipelining(nsHttpConnectionInfo *);
|
bool SupportsPipelining(nsHttpConnectionInfo *);
|
||||||
|
|
||||||
bool GetConnectionData(nsTArray<mozilla::net::HttpRetParams> *);
|
bool GetConnectionData(nsTArray<mozilla::net::HttpRetParams> *);
|
||||||
|
@ -262,7 +262,7 @@ private:
|
||||||
// other positive experiences will eventually allow it to try again.
|
// other positive experiences will eventually allow it to try again.
|
||||||
PS_RED
|
PS_RED
|
||||||
};
|
};
|
||||||
|
|
||||||
class nsHalfOpenSocket;
|
class nsHalfOpenSocket;
|
||||||
|
|
||||||
// nsConnectionEntry
|
// nsConnectionEntry
|
||||||
|
@ -294,7 +294,7 @@ private:
|
||||||
const static uint32_t kPipelineUnlimited = 1024; // fully open - extended green
|
const static uint32_t kPipelineUnlimited = 1024; // fully open - extended green
|
||||||
const static uint32_t kPipelineOpen = 6; // 6 on each conn - normal green
|
const static uint32_t kPipelineOpen = 6; // 6 on each conn - normal green
|
||||||
const static uint32_t kPipelineRestricted = 2; // 2 on just 1 conn in yellow
|
const static uint32_t kPipelineRestricted = 2; // 2 on just 1 conn in yellow
|
||||||
|
|
||||||
nsHttpConnectionMgr::PipeliningState PipelineState();
|
nsHttpConnectionMgr::PipeliningState PipelineState();
|
||||||
void OnPipelineFeedbackInfo(
|
void OnPipelineFeedbackInfo(
|
||||||
nsHttpConnectionMgr::PipelineFeedbackInfoType info,
|
nsHttpConnectionMgr::PipelineFeedbackInfoType info,
|
||||||
|
@ -422,7 +422,7 @@ private:
|
||||||
nsAHttpTransaction *trans,
|
nsAHttpTransaction *trans,
|
||||||
uint32_t caps);
|
uint32_t caps);
|
||||||
~nsHalfOpenSocket();
|
~nsHalfOpenSocket();
|
||||||
|
|
||||||
nsresult SetupStreams(nsISocketTransport **,
|
nsresult SetupStreams(nsISocketTransport **,
|
||||||
nsIAsyncInputStream **,
|
nsIAsyncInputStream **,
|
||||||
nsIAsyncOutputStream **,
|
nsIAsyncOutputStream **,
|
||||||
|
@ -631,7 +631,7 @@ private:
|
||||||
// that are accessed from mCT connection table
|
// that are accessed from mCT connection table
|
||||||
uint32_t mNumHalfOpenConns;
|
uint32_t mNumHalfOpenConns;
|
||||||
|
|
||||||
// Holds time in seconds for next wake-up to prune dead connections.
|
// Holds time in seconds for next wake-up to prune dead connections.
|
||||||
uint64_t mTimeOfNextWakeUp;
|
uint64_t mTimeOfNextWakeUp;
|
||||||
// Timer for next pruning of dead connections.
|
// Timer for next pruning of dead connections.
|
||||||
nsCOMPtr<nsITimer> mTimer;
|
nsCOMPtr<nsITimer> mTimer;
|
||||||
|
|
|
@ -100,7 +100,7 @@ nsHttpDigestAuth::GetMethodAndPath(nsIHttpAuthenticableChannel *authChannel,
|
||||||
path.AppendInt(port < 0 ? NS_HTTPS_DEFAULT_PORT : port);
|
path.AppendInt(port < 0 ? NS_HTTPS_DEFAULT_PORT : port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rv = authChannel->GetRequestMethod(httpMethod);
|
rv = authChannel->GetRequestMethod(httpMethod);
|
||||||
rv2 = uri->GetPath(path);
|
rv2 = uri->GetPath(path);
|
||||||
if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(rv2)) {
|
if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(rv2)) {
|
||||||
|
@ -219,7 +219,7 @@ nsHttpDigestAuth::GenerateCredentials(nsIHttpAuthenticableChannel *authChannel,
|
||||||
/* TODO: to support auth-int, we need to get an MD5 digest of
|
/* TODO: to support auth-int, we need to get an MD5 digest of
|
||||||
* TODO: the data uploaded with this request.
|
* TODO: the data uploaded with this request.
|
||||||
* TODO: however, i am not sure how to read in the file in without
|
* TODO: however, i am not sure how to read in the file in without
|
||||||
* TODO: disturbing the channel''s use of it. do i need to copy it
|
* TODO: disturbing the channel''s use of it. do i need to copy it
|
||||||
* TODO: somehow?
|
* TODO: somehow?
|
||||||
*/
|
*/
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -251,7 +251,7 @@ nsHttpDigestAuth::GenerateCredentials(nsIHttpAuthenticableChannel *authChannel,
|
||||||
//
|
//
|
||||||
// the following are for increasing security. see RFC 2617 for more
|
// the following are for increasing security. see RFC 2617 for more
|
||||||
// information.
|
// information.
|
||||||
//
|
//
|
||||||
// nonce_count allows the server to keep track of auth challenges (to help
|
// nonce_count allows the server to keep track of auth challenges (to help
|
||||||
// prevent spoofing). we increase this count every time.
|
// prevent spoofing). we increase this count every time.
|
||||||
//
|
//
|
||||||
|
@ -268,7 +268,7 @@ nsHttpDigestAuth::GenerateCredentials(nsIHttpAuthenticableChannel *authChannel,
|
||||||
else {
|
else {
|
||||||
nsCOMPtr<nsISupportsPRUint32> v(
|
nsCOMPtr<nsISupportsPRUint32> v(
|
||||||
do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID));
|
do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID));
|
||||||
if (v) {
|
if (v) {
|
||||||
v->SetData(1);
|
v->SetData(1);
|
||||||
NS_ADDREF(*sessionState = v);
|
NS_ADDREF(*sessionState = v);
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,7 @@ nsHttpDigestAuth::GenerateCredentials(nsIHttpAuthenticableChannel *authChannel,
|
||||||
// returned Authentication-Info header). also used for session info.
|
// returned Authentication-Info header). also used for session info.
|
||||||
//
|
//
|
||||||
nsAutoCString cnonce;
|
nsAutoCString cnonce;
|
||||||
static const char hexChar[] = "0123456789abcdef";
|
static const char hexChar[] = "0123456789abcdef";
|
||||||
for (int i=0; i<16; ++i) {
|
for (int i=0; i<16; ++i) {
|
||||||
cnonce.Append(hexChar[(int)(15.0 * rand()/(RAND_MAX + 1.0))]);
|
cnonce.Append(hexChar[(int)(15.0 * rand()/(RAND_MAX + 1.0))]);
|
||||||
}
|
}
|
||||||
|
@ -553,15 +553,15 @@ nsHttpDigestAuth::ParseChallenge(const char * challenge,
|
||||||
|
|
||||||
// name
|
// name
|
||||||
int16_t nameStart = (p - challenge);
|
int16_t nameStart = (p - challenge);
|
||||||
while (*p && !nsCRT::IsAsciiSpace(*p) && *p != '=')
|
while (*p && !nsCRT::IsAsciiSpace(*p) && *p != '=')
|
||||||
++p;
|
++p;
|
||||||
if (!*p)
|
if (!*p)
|
||||||
return NS_ERROR_INVALID_ARG;
|
return NS_ERROR_INVALID_ARG;
|
||||||
int16_t nameLength = (p - challenge) - nameStart;
|
int16_t nameLength = (p - challenge) - nameStart;
|
||||||
|
|
||||||
while (*p && (nsCRT::IsAsciiSpace(*p) || *p == '='))
|
while (*p && (nsCRT::IsAsciiSpace(*p) || *p == '='))
|
||||||
++p;
|
++p;
|
||||||
if (!*p)
|
if (!*p)
|
||||||
return NS_ERROR_INVALID_ARG;
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
|
||||||
bool quoted = false;
|
bool quoted = false;
|
||||||
|
@ -574,15 +574,15 @@ nsHttpDigestAuth::ParseChallenge(const char * challenge,
|
||||||
int16_t valueStart = (p - challenge);
|
int16_t valueStart = (p - challenge);
|
||||||
int16_t valueLength = 0;
|
int16_t valueLength = 0;
|
||||||
if (quoted) {
|
if (quoted) {
|
||||||
while (*p && *p != '"')
|
while (*p && *p != '"')
|
||||||
++p;
|
++p;
|
||||||
if (*p != '"')
|
if (*p != '"')
|
||||||
return NS_ERROR_INVALID_ARG;
|
return NS_ERROR_INVALID_ARG;
|
||||||
valueLength = (p - challenge) - valueStart;
|
valueLength = (p - challenge) - valueStart;
|
||||||
++p;
|
++p;
|
||||||
} else {
|
} else {
|
||||||
while (*p && !nsCRT::IsAsciiSpace(*p) && *p != ',')
|
while (*p && !nsCRT::IsAsciiSpace(*p) && *p != ',')
|
||||||
++p;
|
++p;
|
||||||
valueLength = (p - challenge) - valueStart;
|
valueLength = (p - challenge) - valueStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,12 +634,12 @@ nsHttpDigestAuth::ParseChallenge(const char * challenge,
|
||||||
while (ipos < valueStart+valueLength) {
|
while (ipos < valueStart+valueLength) {
|
||||||
while (ipos < valueStart+valueLength &&
|
while (ipos < valueStart+valueLength &&
|
||||||
(nsCRT::IsAsciiSpace(challenge[ipos]) ||
|
(nsCRT::IsAsciiSpace(challenge[ipos]) ||
|
||||||
challenge[ipos] == ','))
|
challenge[ipos] == ','))
|
||||||
ipos++;
|
ipos++;
|
||||||
int16_t algostart = ipos;
|
int16_t algostart = ipos;
|
||||||
while (ipos < valueStart+valueLength &&
|
while (ipos < valueStart+valueLength &&
|
||||||
!nsCRT::IsAsciiSpace(challenge[ipos]) &&
|
!nsCRT::IsAsciiSpace(challenge[ipos]) &&
|
||||||
challenge[ipos] != ',')
|
challenge[ipos] != ',')
|
||||||
ipos++;
|
ipos++;
|
||||||
if ((ipos - algostart) == 4 &&
|
if ((ipos - algostart) == 4 &&
|
||||||
nsCRT::strncasecmp(challenge+algostart, "auth", 4) == 0)
|
nsCRT::strncasecmp(challenge+algostart, "auth", 4) == 0)
|
||||||
|
|
|
@ -133,10 +133,10 @@ public:
|
||||||
//
|
//
|
||||||
// - the handler keeps a count of active connections to enforce the
|
// - the handler keeps a count of active connections to enforce the
|
||||||
// steady-state max-connections pref.
|
// steady-state max-connections pref.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Called to kick-off a new transaction, by default the transaction
|
// Called to kick-off a new transaction, by default the transaction
|
||||||
// will be put on the pending transaction queue if it cannot be
|
// will be put on the pending transaction queue if it cannot be
|
||||||
// initiated at this time. Callable from any thread.
|
// initiated at this time. Callable from any thread.
|
||||||
nsresult InitiateTransaction(nsHttpTransaction *trans, int32_t priority)
|
nsresult InitiateTransaction(nsHttpTransaction *trans, int32_t priority)
|
||||||
{
|
{
|
||||||
|
@ -258,7 +258,7 @@ public:
|
||||||
{
|
{
|
||||||
return mPipelineRescheduleTimeout;
|
return mPipelineRescheduleTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIntervalTime GetPipelineTimeout() { return mPipelineReadTimeout; }
|
PRIntervalTime GetPipelineTimeout() { return mPipelineReadTimeout; }
|
||||||
|
|
||||||
mozilla::net::SpdyInformation *SpdyInfo() { return &mSpdyInfo; }
|
mozilla::net::SpdyInformation *SpdyInfo() { return &mSpdyInfo; }
|
||||||
|
@ -388,7 +388,7 @@ private:
|
||||||
bool mUseCache;
|
bool mUseCache;
|
||||||
|
|
||||||
bool mPromptTempRedirect;
|
bool mPromptTempRedirect;
|
||||||
// mSendSecureXSiteReferrer: default is false,
|
// mSendSecureXSiteReferrer: default is false,
|
||||||
// if true allow referrer headers between secure non-matching hosts
|
// if true allow referrer headers between secure non-matching hosts
|
||||||
bool mSendSecureXSiteReferrer;
|
bool mSendSecureXSiteReferrer;
|
||||||
|
|
||||||
|
@ -485,7 +485,7 @@ class nsHttpsHandler : public nsIHttpProtocolHandler
|
||||||
public:
|
public:
|
||||||
// we basically just want to override GetScheme and GetDefaultPort...
|
// we basically just want to override GetScheme and GetDefaultPort...
|
||||||
// all other methods should be forwarded to the nsHttpHandler instance.
|
// all other methods should be forwarded to the nsHttpHandler instance.
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIPROTOCOLHANDLER
|
NS_DECL_NSIPROTOCOLHANDLER
|
||||||
NS_FORWARD_NSIPROXIEDPROTOCOLHANDLER (gHttpHandler->)
|
NS_FORWARD_NSIPROXIEDPROTOCOLHANDLER (gHttpHandler->)
|
||||||
|
|
|
@ -135,7 +135,7 @@ nsHttpHeaderArray::ParseHeaderLine(const char *line,
|
||||||
// and consisting of either *TEXT or combinations
|
// and consisting of either *TEXT or combinations
|
||||||
// of token, separators, and quoted-string>
|
// of token, separators, and quoted-string>
|
||||||
//
|
//
|
||||||
|
|
||||||
// We skip over mal-formed headers in the hope that we'll still be able to
|
// We skip over mal-formed headers in the hope that we'll still be able to
|
||||||
// do something useful with the response.
|
// do something useful with the response.
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ nsHttpHeaderArray::ParseHeaderLine(const char *line,
|
||||||
LOG(("malformed header [%s]: field-name not a token\n", line));
|
LOG(("malformed header [%s]: field-name not a token\n", line));
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
*p = 0; // null terminate field-name
|
*p = 0; // null terminate field-name
|
||||||
|
|
||||||
nsHttpAtom atom = nsHttp::ResolveAtom(line);
|
nsHttpAtom atom = nsHttp::ResolveAtom(line);
|
||||||
|
@ -184,7 +184,7 @@ nsHttpHeaderArray::Flatten(nsACString &buf, bool pruneProxyHeaders)
|
||||||
for (i = 0; i < count; ++i) {
|
for (i = 0; i < count; ++i) {
|
||||||
const nsEntry &entry = mHeaders[i];
|
const nsEntry &entry = mHeaders[i];
|
||||||
// prune proxy headers if requested
|
// prune proxy headers if requested
|
||||||
if (pruneProxyHeaders && ((entry.header == nsHttp::Proxy_Authorization) ||
|
if (pruneProxyHeaders && ((entry.header == nsHttp::Proxy_Authorization) ||
|
||||||
(entry.header == nsHttp::Proxy_Connection)))
|
(entry.header == nsHttp::Proxy_Connection)))
|
||||||
continue;
|
continue;
|
||||||
buf.Append(entry.header);
|
buf.Append(entry.header);
|
||||||
|
|
|
@ -61,7 +61,7 @@ public:
|
||||||
void ClearHeader(nsHttpAtom h);
|
void ClearHeader(nsHttpAtom h);
|
||||||
|
|
||||||
// Find the location of the given header value, or null if none exists.
|
// Find the location of the given header value, or null if none exists.
|
||||||
const char *FindHeaderValue(nsHttpAtom header, const char *value) const
|
const char *FindHeaderValue(nsHttpAtom header, const char *value) const
|
||||||
{
|
{
|
||||||
return nsHttp::FindToken(PeekHeader(header), value,
|
return nsHttp::FindToken(PeekHeader(header), value,
|
||||||
HTTP_HEADER_VALUE_SEPS);
|
HTTP_HEADER_VALUE_SEPS);
|
||||||
|
@ -75,7 +75,7 @@ public:
|
||||||
|
|
||||||
nsresult VisitHeaders(nsIHttpHeaderVisitor *visitor);
|
nsresult VisitHeaders(nsIHttpHeaderVisitor *visitor);
|
||||||
|
|
||||||
// parse a header line, return the header atom and a pointer to the
|
// parse a header line, return the header atom and a pointer to the
|
||||||
// header value (the substring of the header line -- do not free).
|
// header value (the substring of the header line -- do not free).
|
||||||
nsresult ParseHeaderLine(const char *line,
|
nsresult ParseHeaderLine(const char *line,
|
||||||
nsHttpAtom *header=nullptr,
|
nsHttpAtom *header=nullptr,
|
||||||
|
|
|
@ -152,7 +152,7 @@ TestPref(nsIURI *uri, const char *pref)
|
||||||
break;
|
break;
|
||||||
start = end + 1;
|
start = end + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsMemory::Free(hostList);
|
nsMemory::Free(hostList);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -249,7 +249,7 @@ nsHttpNTLMAuth::ChallengeReceived(nsIHttpAuthenticableChannel *channel,
|
||||||
// instantiate a native NTLM module the last time, so skip trying again.
|
// instantiate a native NTLM module the last time, so skip trying again.
|
||||||
bool forceGeneric = ForceGenericNTLM();
|
bool forceGeneric = ForceGenericNTLM();
|
||||||
if (!forceGeneric && !*sessionState) {
|
if (!forceGeneric && !*sessionState) {
|
||||||
// Check for approved default credentials hosts and proxies. If
|
// Check for approved default credentials hosts and proxies. If
|
||||||
// *continuationState is non-null, the last authentication attempt
|
// *continuationState is non-null, the last authentication attempt
|
||||||
// failed so skip default credential use.
|
// failed so skip default credential use.
|
||||||
if (!*continuationState && CanUseDefaultCredentials(channel, isProxyAuth)) {
|
if (!*continuationState && CanUseDefaultCredentials(channel, isProxyAuth)) {
|
||||||
|
@ -296,7 +296,7 @@ nsHttpNTLMAuth::ChallengeReceived(nsIHttpAuthenticableChannel *channel,
|
||||||
// see bug 520607 for details.
|
// see bug 520607 for details.
|
||||||
LOG(("Trying to fall back on internal ntlm auth.\n"));
|
LOG(("Trying to fall back on internal ntlm auth.\n"));
|
||||||
module = do_CreateInstance(NS_AUTH_MODULE_CONTRACTID_PREFIX "ntlm");
|
module = do_CreateInstance(NS_AUTH_MODULE_CONTRACTID_PREFIX "ntlm");
|
||||||
|
|
||||||
mUseNative = false;
|
mUseNative = false;
|
||||||
|
|
||||||
// Prompt user for domain, username, and password.
|
// Prompt user for domain, username, and password.
|
||||||
|
@ -336,7 +336,7 @@ nsHttpNTLMAuth::GenerateCredentials(nsIHttpAuthenticableChannel *authChannel,
|
||||||
|
|
||||||
// if user or password is empty, ChallengeReceived returned
|
// if user or password is empty, ChallengeReceived returned
|
||||||
// identityInvalid = false, that means we are using default user
|
// identityInvalid = false, that means we are using default user
|
||||||
// credentials; see nsAuthSSPI::Init method for explanation of this
|
// credentials; see nsAuthSSPI::Init method for explanation of this
|
||||||
// condition
|
// condition
|
||||||
if (!user || !pass)
|
if (!user || !pass)
|
||||||
*aFlags = USING_INTERNAL_IDENTITY;
|
*aFlags = USING_INTERNAL_IDENTITY;
|
||||||
|
@ -367,15 +367,15 @@ nsHttpNTLMAuth::GenerateCredentials(nsIHttpAuthenticableChannel *authChannel,
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
// This update enables updated Windows machines (Win7 or patched previous
|
// This update enables updated Windows machines (Win7 or patched previous
|
||||||
// versions) and Linux machines running Samba (updated for Channel
|
// versions) and Linux machines running Samba (updated for Channel
|
||||||
// Binding), to perform Channel Binding when authenticating using NTLMv2
|
// Binding), to perform Channel Binding when authenticating using NTLMv2
|
||||||
// and an outer secure channel.
|
// and an outer secure channel.
|
||||||
//
|
//
|
||||||
// Currently only implemented for Windows, linux support will be landing in
|
// Currently only implemented for Windows, linux support will be landing in
|
||||||
// a separate patch, update this #ifdef accordingly then.
|
// a separate patch, update this #ifdef accordingly then.
|
||||||
#if defined (XP_WIN) /* || defined (LINUX) */
|
#if defined (XP_WIN) /* || defined (LINUX) */
|
||||||
// We should retrieve the server certificate and compute the CBT,
|
// We should retrieve the server certificate and compute the CBT,
|
||||||
// but only when we are using the native NTLM implementation and
|
// but only when we are using the native NTLM implementation and
|
||||||
// not the internal one.
|
// not the internal one.
|
||||||
// It is a valid case not having the security info object. This
|
// It is a valid case not having the security info object. This
|
||||||
// occures when we connect an https site through an ntlm proxy.
|
// occures when we connect an https site through an ntlm proxy.
|
||||||
|
@ -406,13 +406,13 @@ nsHttpNTLMAuth::GenerateCredentials(nsIHttpAuthenticableChannel *authChannel,
|
||||||
|
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
uint8_t* certArray;
|
uint8_t* certArray;
|
||||||
cert->GetRawDER(&length, &certArray);
|
cert->GetRawDER(&length, &certArray);
|
||||||
|
|
||||||
// If there is a server certificate, we pass it along the
|
// If there is a server certificate, we pass it along the
|
||||||
// first time we call GetNextToken().
|
// first time we call GetNextToken().
|
||||||
inBufLen = length;
|
inBufLen = length;
|
||||||
inBuf = certArray;
|
inBuf = certArray;
|
||||||
} else {
|
} else {
|
||||||
// If there is no server certificate, we don't pass anything.
|
// If there is no server certificate, we don't pass anything.
|
||||||
inBufLen = 0;
|
inBufLen = 0;
|
||||||
inBuf = nullptr;
|
inBuf = nullptr;
|
||||||
|
|
|
@ -99,7 +99,7 @@ nsHttpPipeline::AddTransaction(nsAHttpTransaction *trans)
|
||||||
NS_ADDREF(trans);
|
NS_ADDREF(trans);
|
||||||
mRequestQ.AppendElement(trans);
|
mRequestQ.AppendElement(trans);
|
||||||
uint32_t qlen = PipelineDepth();
|
uint32_t qlen = PipelineDepth();
|
||||||
|
|
||||||
if (qlen != 1) {
|
if (qlen != 1) {
|
||||||
trans->SetPipelinePosition(qlen);
|
trans->SetPipelinePosition(qlen);
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ nsHttpPipeline::PipelinePosition()
|
||||||
// The response queue is empty, so return oldest request
|
// The response queue is empty, so return oldest request
|
||||||
if (mRequestQ.Length())
|
if (mRequestQ.Length())
|
||||||
return Request(mRequestQ.Length() - 1)->PipelinePosition();
|
return Request(mRequestQ.Length() - 1)->PipelinePosition();
|
||||||
|
|
||||||
// No transactions in the pipeline
|
// No transactions in the pipeline
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -182,19 +182,19 @@ nsHttpPipeline::OnHeadersAvailable(nsAHttpTransaction *trans,
|
||||||
|
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
MOZ_ASSERT(mConnection, "no connection");
|
MOZ_ASSERT(mConnection, "no connection");
|
||||||
|
|
||||||
nsRefPtr<nsHttpConnectionInfo> ci;
|
nsRefPtr<nsHttpConnectionInfo> ci;
|
||||||
GetConnectionInfo(getter_AddRefs(ci));
|
GetConnectionInfo(getter_AddRefs(ci));
|
||||||
MOZ_ASSERT(ci);
|
MOZ_ASSERT(ci);
|
||||||
|
|
||||||
bool pipeliningBefore = gHttpHandler->ConnMgr()->SupportsPipelining(ci);
|
bool pipeliningBefore = gHttpHandler->ConnMgr()->SupportsPipelining(ci);
|
||||||
|
|
||||||
// trans has now received its response headers; forward to the real connection
|
// trans has now received its response headers; forward to the real connection
|
||||||
nsresult rv = mConnection->OnHeadersAvailable(trans,
|
nsresult rv = mConnection->OnHeadersAvailable(trans,
|
||||||
requestHead,
|
requestHead,
|
||||||
responseHead,
|
responseHead,
|
||||||
reset);
|
reset);
|
||||||
|
|
||||||
if (!pipeliningBefore && gHttpHandler->ConnMgr()->SupportsPipelining(ci))
|
if (!pipeliningBefore && gHttpHandler->ConnMgr()->SupportsPipelining(ci))
|
||||||
// The received headers have expanded the eligible
|
// The received headers have expanded the eligible
|
||||||
// pipeline depth for this connection
|
// pipeline depth for this connection
|
||||||
|
@ -213,7 +213,7 @@ nsHttpPipeline::CloseTransaction(nsAHttpTransaction *trans, nsresult reason)
|
||||||
MOZ_ASSERT(NS_FAILED(reason), "expecting failure code");
|
MOZ_ASSERT(NS_FAILED(reason), "expecting failure code");
|
||||||
|
|
||||||
// the specified transaction is to be closed with the given "reason"
|
// the specified transaction is to be closed with the given "reason"
|
||||||
|
|
||||||
int32_t index;
|
int32_t index;
|
||||||
bool killPipeline = false;
|
bool killPipeline = false;
|
||||||
|
|
||||||
|
@ -288,7 +288,7 @@ nsresult
|
||||||
nsHttpPipeline::PushBack(const char *data, uint32_t length)
|
nsHttpPipeline::PushBack(const char *data, uint32_t length)
|
||||||
{
|
{
|
||||||
LOG(("nsHttpPipeline::PushBack [this=%x len=%u]\n", this, length));
|
LOG(("nsHttpPipeline::PushBack [this=%x len=%u]\n", this, length));
|
||||||
|
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
MOZ_ASSERT(mPushBackLen == 0, "push back buffer already has data!");
|
MOZ_ASSERT(mPushBackLen == 0, "push back buffer already has data!");
|
||||||
|
|
||||||
|
@ -322,7 +322,7 @@ nsHttpPipeline::PushBack(const char *data, uint32_t length)
|
||||||
if (!mPushBackBuf)
|
if (!mPushBackBuf)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(mPushBackBuf, data, length);
|
memcpy(mPushBackBuf, data, length);
|
||||||
mPushBackLen = length;
|
mPushBackLen = length;
|
||||||
|
|
||||||
|
@ -480,7 +480,7 @@ nsHttpPipeline::OnTransportStatus(nsITransport* transport,
|
||||||
|
|
||||||
if (mSuppressSendEvents) {
|
if (mSuppressSendEvents) {
|
||||||
mSuppressSendEvents = false;
|
mSuppressSendEvents = false;
|
||||||
|
|
||||||
// catch up by sending the event to all the transactions that have
|
// catch up by sending the event to all the transactions that have
|
||||||
// moved from request to response and any that have been partially
|
// moved from request to response and any that have been partially
|
||||||
// sent. Also send WAITING_FOR to those that were completely sent
|
// sent. Also send WAITING_FOR to those that were completely sent
|
||||||
|
@ -489,7 +489,7 @@ nsHttpPipeline::OnTransportStatus(nsITransport* transport,
|
||||||
Response(i)->OnTransportStatus(transport,
|
Response(i)->OnTransportStatus(transport,
|
||||||
NS_NET_STATUS_SENDING_TO,
|
NS_NET_STATUS_SENDING_TO,
|
||||||
progress);
|
progress);
|
||||||
Response(i)->OnTransportStatus(transport,
|
Response(i)->OnTransportStatus(transport,
|
||||||
NS_NET_STATUS_WAITING_FOR,
|
NS_NET_STATUS_WAITING_FOR,
|
||||||
progress);
|
progress);
|
||||||
}
|
}
|
||||||
|
@ -501,12 +501,12 @@ nsHttpPipeline::OnTransportStatus(nsITransport* transport,
|
||||||
}
|
}
|
||||||
// otherwise ignore it
|
// otherwise ignore it
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NS_NET_STATUS_WAITING_FOR:
|
case NS_NET_STATUS_WAITING_FOR:
|
||||||
// Created by nsHttpConnection when request pipeline has been totally
|
// Created by nsHttpConnection when request pipeline has been totally
|
||||||
// sent. Ignore it here because it is simulated in FillSendBuf() when
|
// sent. Ignore it here because it is simulated in FillSendBuf() when
|
||||||
// a request is moved from request to response.
|
// a request is moved from request to response.
|
||||||
|
|
||||||
// ignore it
|
// ignore it
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -532,7 +532,7 @@ bool
|
||||||
nsHttpPipeline::IsDone()
|
nsHttpPipeline::IsDone()
|
||||||
{
|
{
|
||||||
bool done = true;
|
bool done = true;
|
||||||
|
|
||||||
uint32_t i, count = mRequestQ.Length();
|
uint32_t i, count = mRequestQ.Length();
|
||||||
for (i = 0; done && (i < count); i++)
|
for (i = 0; done && (i < count); i++)
|
||||||
done = Request(i)->IsDone();
|
done = Request(i)->IsDone();
|
||||||
|
@ -540,7 +540,7 @@ nsHttpPipeline::IsDone()
|
||||||
count = mResponseQ.Length();
|
count = mResponseQ.Length();
|
||||||
for (i = 0; done && (i < count); i++)
|
for (i = 0; done && (i < count); i++)
|
||||||
done = Response(i)->IsDone();
|
done = Response(i)->IsDone();
|
||||||
|
|
||||||
return done;
|
return done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,7 +643,7 @@ nsHttpPipeline::WriteSegments(nsAHttpSegmentWriter *writer,
|
||||||
if (mClosed)
|
if (mClosed)
|
||||||
return NS_SUCCEEDED(mStatus) ? NS_BASE_STREAM_CLOSED : mStatus;
|
return NS_SUCCEEDED(mStatus) ? NS_BASE_STREAM_CLOSED : mStatus;
|
||||||
|
|
||||||
nsAHttpTransaction *trans;
|
nsAHttpTransaction *trans;
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
trans = Response(0);
|
trans = Response(0);
|
||||||
|
@ -665,7 +665,7 @@ nsHttpPipeline::WriteSegments(nsAHttpSegmentWriter *writer,
|
||||||
rv = NS_BASE_STREAM_CLOSED;
|
rv = NS_BASE_STREAM_CLOSED;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//
|
//
|
||||||
// ask the transaction to consume data from the connection.
|
// ask the transaction to consume data from the connection.
|
||||||
// PushBack may be called recursively.
|
// PushBack may be called recursively.
|
||||||
//
|
//
|
||||||
|
@ -826,7 +826,7 @@ nsHttpPipeline::FillSendBuf()
|
||||||
// when they have been completely read.
|
// when they have been completely read.
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
if (!mSendBufIn) {
|
if (!mSendBufIn) {
|
||||||
// allocate a single-segment pipe
|
// allocate a single-segment pipe
|
||||||
rv = NS_NewPipe(getter_AddRefs(mSendBufIn),
|
rv = NS_NewPipe(getter_AddRefs(mSendBufIn),
|
||||||
|
@ -854,7 +854,7 @@ nsHttpPipeline::FillSendBuf()
|
||||||
response->SetPipelinePosition(1);
|
response->SetPipelinePosition(1);
|
||||||
rv = trans->ReadSegments(this, (uint32_t)std::min(avail, (uint64_t)UINT32_MAX), &n);
|
rv = trans->ReadSegments(this, (uint32_t)std::min(avail, (uint64_t)UINT32_MAX), &n);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
LOG(("send pipe is full"));
|
LOG(("send pipe is full"));
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsresult FillSendBuf();
|
nsresult FillSendBuf();
|
||||||
|
|
||||||
static NS_METHOD ReadFromPipe(nsIInputStream *, void *, const char *,
|
static NS_METHOD ReadFromPipe(nsIInputStream *, void *, const char *,
|
||||||
uint32_t, uint32_t, uint32_t *);
|
uint32_t, uint32_t, uint32_t *);
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ private:
|
||||||
nsresult mStatus;
|
nsresult mStatus;
|
||||||
|
|
||||||
// these flags indicate whether or not the first request or response
|
// these flags indicate whether or not the first request or response
|
||||||
// is partial. a partial request means that Request(0) has been
|
// is partial. a partial request means that Request(0) has been
|
||||||
// partially written out to the socket. a partial response means
|
// partially written out to the socket. a partial response means
|
||||||
// that Response(0) has been partially read in from the socket.
|
// that Response(0) has been partially read in from the socket.
|
||||||
bool mRequestIsPartial;
|
bool mRequestIsPartial;
|
||||||
|
|
|
@ -13,7 +13,7 @@ void
|
||||||
nsHttpRequestHead::Flatten(nsACString &buf, bool pruneProxyHeaders)
|
nsHttpRequestHead::Flatten(nsACString &buf, bool pruneProxyHeaders)
|
||||||
{
|
{
|
||||||
// note: the first append is intentional.
|
// note: the first append is intentional.
|
||||||
|
|
||||||
buf.Append(mMethod.get());
|
buf.Append(mMethod.get());
|
||||||
buf.Append(' ');
|
buf.Append(' ');
|
||||||
buf.Append(mRequestURI);
|
buf.Append(mRequestURI);
|
||||||
|
|
|
@ -134,10 +134,10 @@ nsHttpResponseHead::ParseStatusLine(const char *line)
|
||||||
//
|
//
|
||||||
// Parse Status-Line:: HTTP-Version SP Status-Code SP Reason-Phrase CRLF
|
// Parse Status-Line:: HTTP-Version SP Status-Code SP Reason-Phrase CRLF
|
||||||
//
|
//
|
||||||
|
|
||||||
// HTTP-Version
|
// HTTP-Version
|
||||||
ParseVersion(line);
|
ParseVersion(line);
|
||||||
|
|
||||||
if ((mVersion == NS_HTTP_VERSION_0_9) || !(line = PL_strchr(line, ' '))) {
|
if ((mVersion == NS_HTTP_VERSION_0_9) || !(line = PL_strchr(line, ' '))) {
|
||||||
mStatus = 200;
|
mStatus = 200;
|
||||||
mStatusText.AssignLiteral("OK");
|
mStatusText.AssignLiteral("OK");
|
||||||
|
@ -169,11 +169,11 @@ nsHttpResponseHead::ParseHeaderLine(const char *line)
|
||||||
nsHttpAtom hdr = {0};
|
nsHttpAtom hdr = {0};
|
||||||
char *val;
|
char *val;
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
rv = mHeaders.ParseHeaderLine(line, &hdr, &val);
|
rv = mHeaders.ParseHeaderLine(line, &hdr, &val);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
// leading and trailing LWS has been removed from |val|
|
// leading and trailing LWS has been removed from |val|
|
||||||
|
|
||||||
// handle some special case headers...
|
// handle some special case headers...
|
||||||
|
@ -185,7 +185,7 @@ nsHttpResponseHead::ParseHeaderLine(const char *line)
|
||||||
mContentLength = len;
|
mContentLength = len;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// If this is a negative content length then just ignore it
|
// If this is a negative content length then just ignore it
|
||||||
LOG(("invalid content-length! %s\n", val));
|
LOG(("invalid content-length! %s\n", val));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,7 +278,7 @@ nsHttpResponseHead::ComputeFreshnessLifetime(uint32_t *result) const
|
||||||
// the Expires header can specify a date in the past.
|
// the Expires header can specify a date in the past.
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback on heuristic using last modified header...
|
// Fallback on heuristic using last modified header...
|
||||||
if (NS_SUCCEEDED(GetLastModifiedValue(&date2))) {
|
if (NS_SUCCEEDED(GetLastModifiedValue(&date2))) {
|
||||||
LOG(("using last-modified to determine freshness-lifetime\n"));
|
LOG(("using last-modified to determine freshness-lifetime\n"));
|
||||||
|
@ -335,7 +335,7 @@ nsHttpResponseHead::MustValidate() const
|
||||||
LOG(("Must validate since response is an uncacheable error page\n"));
|
LOG(("Must validate since response is an uncacheable error page\n"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The no-cache response header indicates that we must validate this
|
// The no-cache response header indicates that we must validate this
|
||||||
// cached response before reusing.
|
// cached response before reusing.
|
||||||
if (NoCache()) {
|
if (NoCache()) {
|
||||||
|
@ -369,8 +369,8 @@ nsHttpResponseHead::MustValidateIfExpired() const
|
||||||
{
|
{
|
||||||
// according to RFC2616, section 14.9.4:
|
// according to RFC2616, section 14.9.4:
|
||||||
//
|
//
|
||||||
// When the must-revalidate directive is present in a response received by a
|
// When the must-revalidate directive is present in a response received by a
|
||||||
// cache, that cache MUST NOT use the entry after it becomes stale to respond to
|
// cache, that cache MUST NOT use the entry after it becomes stale to respond to
|
||||||
// a subsequent request without first revalidating it with the origin server.
|
// a subsequent request without first revalidating it with the origin server.
|
||||||
//
|
//
|
||||||
return HasHeaderValue(nsHttp::Cache_Control, "must-revalidate");
|
return HasHeaderValue(nsHttp::Cache_Control, "must-revalidate");
|
||||||
|
@ -386,7 +386,7 @@ nsHttpResponseHead::IsResumable() const
|
||||||
// non-2xx responses.
|
// non-2xx responses.
|
||||||
return mStatus == 200 &&
|
return mStatus == 200 &&
|
||||||
mVersion >= NS_HTTP_VERSION_1_1 &&
|
mVersion >= NS_HTTP_VERSION_1_1 &&
|
||||||
PeekHeader(nsHttp::Content_Length) &&
|
PeekHeader(nsHttp::Content_Length) &&
|
||||||
(PeekHeader(nsHttp::ETag) || PeekHeader(nsHttp::Last_Modified)) &&
|
(PeekHeader(nsHttp::ETag) || PeekHeader(nsHttp::Last_Modified)) &&
|
||||||
HasHeaderValue(nsHttp::Accept_Ranges, "bytes");
|
HasHeaderValue(nsHttp::Accept_Ranges, "bytes");
|
||||||
}
|
}
|
||||||
|
@ -395,12 +395,12 @@ bool
|
||||||
nsHttpResponseHead::ExpiresInPast() const
|
nsHttpResponseHead::ExpiresInPast() const
|
||||||
{
|
{
|
||||||
uint32_t maxAgeVal, expiresVal, dateVal;
|
uint32_t maxAgeVal, expiresVal, dateVal;
|
||||||
|
|
||||||
// Bug #203271. Ensure max-age directive takes precedence over Expires
|
// Bug #203271. Ensure max-age directive takes precedence over Expires
|
||||||
if (NS_SUCCEEDED(GetMaxAgeValue(&maxAgeVal))) {
|
if (NS_SUCCEEDED(GetMaxAgeValue(&maxAgeVal))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_SUCCEEDED(GetExpiresValue(&expiresVal)) &&
|
return NS_SUCCEEDED(GetExpiresValue(&expiresVal)) &&
|
||||||
NS_SUCCEEDED(GetDateValue(&dateVal)) &&
|
NS_SUCCEEDED(GetDateValue(&dateVal)) &&
|
||||||
expiresVal < dateVal;
|
expiresVal < dateVal;
|
||||||
|
@ -485,7 +485,7 @@ nsHttpResponseHead::ParseDateHeader(nsHttpAtom header, uint32_t *result) const
|
||||||
if (st != PR_SUCCESS)
|
if (st != PR_SUCCESS)
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
|
||||||
*result = PRTimeToSeconds(time);
|
*result = PRTimeToSeconds(time);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,7 +539,7 @@ nsHttpResponseHead::GetExpiresValue(uint32_t *result) const
|
||||||
if (time < 0)
|
if (time < 0)
|
||||||
*result = 0;
|
*result = 0;
|
||||||
else
|
else
|
||||||
*result = PRTimeToSeconds(time);
|
*result = PRTimeToSeconds(time);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -627,7 +627,7 @@ nsHttpResponseHead::ParseCacheControl(const char *val)
|
||||||
if (nsHttp::FindToken(val, "no-cache", HTTP_HEADER_VALUE_SEPS))
|
if (nsHttp::FindToken(val, "no-cache", HTTP_HEADER_VALUE_SEPS))
|
||||||
mCacheControlNoCache = true;
|
mCacheControlNoCache = true;
|
||||||
|
|
||||||
// search header value for occurrence of "no-store"
|
// search header value for occurrence of "no-store"
|
||||||
if (nsHttp::FindToken(val, "no-store", HTTP_HEADER_VALUE_SEPS))
|
if (nsHttp::FindToken(val, "no-store", HTTP_HEADER_VALUE_SEPS))
|
||||||
mCacheControlNoStore = true;
|
mCacheControlNoStore = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ public:
|
||||||
, mCacheControlNoStore(false)
|
, mCacheControlNoStore(false)
|
||||||
, mCacheControlNoCache(false)
|
, mCacheControlNoCache(false)
|
||||||
, mPragmaNoCache(false) {}
|
, mPragmaNoCache(false) {}
|
||||||
|
|
||||||
const nsHttpHeaderArray & Headers() const { return mHeaders; }
|
const nsHttpHeaderArray & Headers() const { return mHeaders; }
|
||||||
nsHttpHeaderArray &Headers() { return mHeaders; }
|
nsHttpHeaderArray &Headers() { return mHeaders; }
|
||||||
nsHttpVersion Version() const { return mVersion; }
|
nsHttpVersion Version() const { return mVersion; }
|
||||||
|
@ -90,7 +90,7 @@ public:
|
||||||
bool ExpiresInPast() const;
|
bool ExpiresInPast() const;
|
||||||
|
|
||||||
// update headers...
|
// update headers...
|
||||||
nsresult UpdateHeaders(const nsHttpHeaderArray &headers);
|
nsresult UpdateHeaders(const nsHttpHeaderArray &headers);
|
||||||
|
|
||||||
// reset the response head to it's initial state
|
// reset the response head to it's initial state
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
|
@ -221,7 +221,7 @@ nsHttpTransaction::Init(uint32_t caps,
|
||||||
mActivityDistributor = nullptr;
|
mActivityDistributor = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create transport event sink proxy. it coalesces all events if and only
|
// create transport event sink proxy. it coalesces all events if and only
|
||||||
// if the activity observer is not active. when the observer is active
|
// if the activity observer is not active. when the observer is active
|
||||||
// we need not to coalesce any events to get all expected notifications
|
// we need not to coalesce any events to get all expected notifications
|
||||||
// of the transaction state, necessary for correct debugging and logging.
|
// of the transaction state, necessary for correct debugging and logging.
|
||||||
|
@ -258,10 +258,10 @@ nsHttpTransaction::Init(uint32_t caps,
|
||||||
// grab a weak reference to the request head
|
// grab a weak reference to the request head
|
||||||
mRequestHead = requestHead;
|
mRequestHead = requestHead;
|
||||||
|
|
||||||
// make sure we eliminate any proxy specific headers from
|
// make sure we eliminate any proxy specific headers from
|
||||||
// the request if we are using CONNECT
|
// the request if we are using CONNECT
|
||||||
bool pruneProxyHeaders = cinfo->UsingConnect();
|
bool pruneProxyHeaders = cinfo->UsingConnect();
|
||||||
|
|
||||||
mReqHeaderBuf.Truncate();
|
mReqHeaderBuf.Truncate();
|
||||||
requestHead->Flatten(mReqHeaderBuf, pruneProxyHeaders);
|
requestHead->Flatten(mReqHeaderBuf, pruneProxyHeaders);
|
||||||
|
|
||||||
|
@ -361,7 +361,7 @@ nsHttpTransaction::TakeResponseHead()
|
||||||
mForTakeResponseHead = nullptr;
|
mForTakeResponseHead = nullptr;
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Even in OnStartRequest() the headers won't be available if we were
|
// Even in OnStartRequest() the headers won't be available if we were
|
||||||
// canceled
|
// canceled
|
||||||
if (!mHaveAllHeaders) {
|
if (!mHaveAllHeaders) {
|
||||||
|
@ -527,7 +527,7 @@ nsHttpTransaction::Status()
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
nsHttpTransaction::Caps()
|
nsHttpTransaction::Caps()
|
||||||
{
|
{
|
||||||
return mCaps;
|
return mCaps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -645,7 +645,7 @@ nsHttpTransaction::WritePipeSegment(nsIOutputStream *stream,
|
||||||
// - Bytes in HTTP headers don't count towards countWritten, so the input
|
// - Bytes in HTTP headers don't count towards countWritten, so the input
|
||||||
// side of pipe (aka nsHttpChannel's mTransactionPump) won't hit
|
// side of pipe (aka nsHttpChannel's mTransactionPump) won't hit
|
||||||
// OnInputStreamReady until all headers have been parsed.
|
// OnInputStreamReady until all headers have been parsed.
|
||||||
//
|
//
|
||||||
rv = trans->ProcessData(buf, *countWritten, countWritten);
|
rv = trans->ProcessData(buf, *countWritten, countWritten);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
trans->Close(rv);
|
trans->Close(rv);
|
||||||
|
@ -720,7 +720,7 @@ nsHttpTransaction::Close(nsresult reason)
|
||||||
PR_Now(), 0, EmptyCString());
|
PR_Now(), 0, EmptyCString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// we must no longer reference the connection! find out if the
|
// we must no longer reference the connection! find out if the
|
||||||
// connection was being reused before letting it go.
|
// connection was being reused before letting it go.
|
||||||
bool connReused = false;
|
bool connReused = false;
|
||||||
if (mConnection)
|
if (mConnection)
|
||||||
|
@ -751,12 +751,12 @@ nsHttpTransaction::Close(nsresult reason)
|
||||||
// a TLS session (perhaps via a tunnel) is setup.
|
// a TLS session (perhaps via a tunnel) is setup.
|
||||||
bool reallySentData =
|
bool reallySentData =
|
||||||
mSentData && (!mConnection || mConnection->BytesWritten());
|
mSentData && (!mConnection || mConnection->BytesWritten());
|
||||||
|
|
||||||
if (!mReceivedData &&
|
if (!mReceivedData &&
|
||||||
(!reallySentData || connReused || mPipelinePosition)) {
|
(!reallySentData || connReused || mPipelinePosition)) {
|
||||||
// if restarting fails, then we must proceed to close the pipe,
|
// if restarting fails, then we must proceed to close the pipe,
|
||||||
// which will notify the channel that the transaction failed.
|
// which will notify the channel that the transaction failed.
|
||||||
|
|
||||||
if (mPipelinePosition) {
|
if (mPipelinePosition) {
|
||||||
gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
|
gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
|
||||||
mConnInfo, nsHttpConnectionMgr::RedCanceledPipeline,
|
mConnInfo, nsHttpConnectionMgr::RedCanceledPipeline,
|
||||||
|
@ -864,7 +864,7 @@ nsHttpTransaction::SetPipelinePosition(int32_t position)
|
||||||
mPipelinePosition = position;
|
mPipelinePosition = position;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
nsHttpTransaction::PipelinePosition()
|
nsHttpTransaction::PipelinePosition()
|
||||||
{
|
{
|
||||||
|
@ -879,7 +879,7 @@ nsresult
|
||||||
nsHttpTransaction::RestartInProgress()
|
nsHttpTransaction::RestartInProgress()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
|
|
||||||
if ((mRestartCount + 1) >= gHttpHandler->MaxRequestAttempts()) {
|
if ((mRestartCount + 1) >= gHttpHandler->MaxRequestAttempts()) {
|
||||||
LOG(("nsHttpTransaction::RestartInProgress() "
|
LOG(("nsHttpTransaction::RestartInProgress() "
|
||||||
"reached max request attempts, failing transaction %p\n", this));
|
"reached max request attempts, failing transaction %p\n", this));
|
||||||
|
@ -977,7 +977,7 @@ nsHttpTransaction::LocateHttpStart(char *buf, uint32_t len,
|
||||||
static const uint32_t HTTPHeaderLen = sizeof(HTTPHeader) - 1;
|
static const uint32_t HTTPHeaderLen = sizeof(HTTPHeader) - 1;
|
||||||
static const char HTTP2Header[] = "HTTP/2.0";
|
static const char HTTP2Header[] = "HTTP/2.0";
|
||||||
static const uint32_t HTTP2HeaderLen = sizeof(HTTP2Header) - 1;
|
static const uint32_t HTTP2HeaderLen = sizeof(HTTP2Header) - 1;
|
||||||
|
|
||||||
if (aAllowPartialMatch && (len < HTTPHeaderLen))
|
if (aAllowPartialMatch && (len < HTTPHeaderLen))
|
||||||
return (PL_strncasecmp(buf, HTTPHeader, len) == 0) ? buf : nullptr;
|
return (PL_strncasecmp(buf, HTTPHeader, len) == 0) ? buf : nullptr;
|
||||||
|
|
||||||
|
@ -1039,7 +1039,7 @@ nsHttpTransaction::ParseLine(char *line)
|
||||||
{
|
{
|
||||||
LOG(("nsHttpTransaction::ParseLine [%s]\n", line));
|
LOG(("nsHttpTransaction::ParseLine [%s]\n", line));
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
if (!mHaveStatusLine) {
|
if (!mHaveStatusLine) {
|
||||||
mResponseHead->ParseStatusLine(line);
|
mResponseHead->ParseStatusLine(line);
|
||||||
mHaveStatusLine = true;
|
mHaveStatusLine = true;
|
||||||
|
@ -1078,7 +1078,7 @@ nsHttpTransaction::ParseLineSegment(char *segment, uint32_t len)
|
||||||
|
|
||||||
// append segment to mLineBuf...
|
// append segment to mLineBuf...
|
||||||
mLineBuf.Append(segment, len);
|
mLineBuf.Append(segment, len);
|
||||||
|
|
||||||
// a line buf with only a new line char signifies the end of headers.
|
// a line buf with only a new line char signifies the end of headers.
|
||||||
if (mLineBuf.First() == '\n') {
|
if (mLineBuf.First() == '\n') {
|
||||||
mLineBuf.Truncate();
|
mLineBuf.Truncate();
|
||||||
|
@ -1111,7 +1111,7 @@ nsHttpTransaction::ParseHead(char *buf,
|
||||||
*countRead = 0;
|
*countRead = 0;
|
||||||
|
|
||||||
NS_PRECONDITION(!mHaveAllHeaders, "oops");
|
NS_PRECONDITION(!mHaveAllHeaders, "oops");
|
||||||
|
|
||||||
// allocate the response head object if necessary
|
// allocate the response head object if necessary
|
||||||
if (!mResponseHead) {
|
if (!mResponseHead) {
|
||||||
mResponseHead = new nsHttpResponseHead();
|
mResponseHead = new nsHttpResponseHead();
|
||||||
|
@ -1271,7 +1271,7 @@ nsHttpTransaction::HandleContentStart()
|
||||||
LOG(("this response should not contain a body.\n"));
|
LOG(("this response should not contain a body.\n"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mResponseHead->Status() == 200 &&
|
if (mResponseHead->Status() == 200 &&
|
||||||
mConnection->IsProxyConnectInProgress()) {
|
mConnection->IsProxyConnectInProgress()) {
|
||||||
// successful CONNECTs do not have response bodies
|
// successful CONNECTs do not have response bodies
|
||||||
|
@ -1292,7 +1292,7 @@ nsHttpTransaction::HandleContentStart()
|
||||||
if ((mClassification != CLASS_SOLO) &&
|
if ((mClassification != CLASS_SOLO) &&
|
||||||
(mContentLength > mMaxPipelineObjectSize))
|
(mContentLength > mMaxPipelineObjectSize))
|
||||||
CancelPipeline(nsHttpConnectionMgr::BadUnexpectedLarge);
|
CancelPipeline(nsHttpConnectionMgr::BadUnexpectedLarge);
|
||||||
|
|
||||||
// handle chunked encoding here, so we'll know immediately when
|
// handle chunked encoding here, so we'll know immediately when
|
||||||
// we're done with the socket. please note that _all_ other
|
// we're done with the socket. please note that _all_ other
|
||||||
// decoding is done when the channel receives the content data
|
// decoding is done when the channel receives the content data
|
||||||
|
@ -1386,7 +1386,7 @@ nsHttpTransaction::HandleContent(char *buf,
|
||||||
// (no explicit content-length given)
|
// (no explicit content-length given)
|
||||||
*contentRead = count;
|
*contentRead = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t toReadBeforeRestart =
|
int64_t toReadBeforeRestart =
|
||||||
mRestartInProgressVerifier.ToReadBeforeRestart();
|
mRestartInProgressVerifier.ToReadBeforeRestart();
|
||||||
|
|
||||||
|
@ -1465,13 +1465,13 @@ nsHttpTransaction::ProcessData(char *buf, uint32_t count, uint32_t *countRead)
|
||||||
uint32_t localBytesConsumed = 0;
|
uint32_t localBytesConsumed = 0;
|
||||||
char *localBuf = buf + bytesConsumed;
|
char *localBuf = buf + bytesConsumed;
|
||||||
uint32_t localCount = count - bytesConsumed;
|
uint32_t localCount = count - bytesConsumed;
|
||||||
|
|
||||||
rv = ParseHead(localBuf, localCount, &localBytesConsumed);
|
rv = ParseHead(localBuf, localCount, &localBytesConsumed);
|
||||||
if (NS_FAILED(rv) && rv != NS_ERROR_NET_INTERRUPT)
|
if (NS_FAILED(rv) && rv != NS_ERROR_NET_INTERRUPT)
|
||||||
return rv;
|
return rv;
|
||||||
bytesConsumed += localBytesConsumed;
|
bytesConsumed += localBytesConsumed;
|
||||||
} while (rv == NS_ERROR_NET_INTERRUPT);
|
} while (rv == NS_ERROR_NET_INTERRUPT);
|
||||||
|
|
||||||
count -= bytesConsumed;
|
count -= bytesConsumed;
|
||||||
|
|
||||||
// if buf has some content in it, shift bytes to top of buf.
|
// if buf has some content in it, shift bytes to top of buf.
|
||||||
|
@ -1500,7 +1500,7 @@ nsHttpTransaction::ProcessData(char *buf, uint32_t count, uint32_t *countRead)
|
||||||
uint32_t countRemaining = 0;
|
uint32_t countRemaining = 0;
|
||||||
//
|
//
|
||||||
// buf layout:
|
// buf layout:
|
||||||
//
|
//
|
||||||
// +--------------------------------------+----------------+-----+
|
// +--------------------------------------+----------------+-----+
|
||||||
// | countRead | countRemaining | |
|
// | countRead | countRemaining | |
|
||||||
// +--------------------------------------+----------------+-----+
|
// +--------------------------------------+----------------+-----+
|
||||||
|
@ -1553,13 +1553,13 @@ nsHttpTransaction::DispatchedAsBlocking()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LOG(("nsHttpTransaction %p dispatched as blocking\n", this));
|
LOG(("nsHttpTransaction %p dispatched as blocking\n", this));
|
||||||
|
|
||||||
if (!mLoadGroupCI)
|
if (!mLoadGroupCI)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LOG(("nsHttpTransaction adding blocking channel %p from "
|
LOG(("nsHttpTransaction adding blocking channel %p from "
|
||||||
"loadgroup %p\n", this, mLoadGroupCI.get()));
|
"loadgroup %p\n", this, mLoadGroupCI.get()));
|
||||||
|
|
||||||
mLoadGroupCI->AddBlockingTransaction();
|
mLoadGroupCI->AddBlockingTransaction();
|
||||||
mDispatchedAsBlocking = true;
|
mDispatchedAsBlocking = true;
|
||||||
}
|
}
|
||||||
|
@ -1569,7 +1569,7 @@ nsHttpTransaction::RemoveDispatchedAsBlocking()
|
||||||
{
|
{
|
||||||
if (!mLoadGroupCI || !mDispatchedAsBlocking)
|
if (!mLoadGroupCI || !mDispatchedAsBlocking)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint32_t blockers = 0;
|
uint32_t blockers = 0;
|
||||||
nsresult rv = mLoadGroupCI->RemoveBlockingTransaction(&blockers);
|
nsresult rv = mLoadGroupCI->RemoveBlockingTransaction(&blockers);
|
||||||
|
|
||||||
|
@ -1582,7 +1582,7 @@ nsHttpTransaction::RemoveDispatchedAsBlocking()
|
||||||
this));
|
this));
|
||||||
gHttpHandler->ConnMgr()->ProcessPendingQ();
|
gHttpHandler->ConnMgr()->ProcessPendingQ();
|
||||||
}
|
}
|
||||||
|
|
||||||
mDispatchedAsBlocking = false;
|
mDispatchedAsBlocking = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1616,7 +1616,7 @@ void
|
||||||
nsHttpTransaction::DeleteSelfOnConsumerThread()
|
nsHttpTransaction::DeleteSelfOnConsumerThread()
|
||||||
{
|
{
|
||||||
LOG(("nsHttpTransaction::DeleteSelfOnConsumerThread [this=%x]\n", this));
|
LOG(("nsHttpTransaction::DeleteSelfOnConsumerThread [this=%x]\n", this));
|
||||||
|
|
||||||
bool val;
|
bool val;
|
||||||
if (!mConsumerTarget ||
|
if (!mConsumerTarget ||
|
||||||
(NS_SUCCEEDED(mConsumerTarget->IsOnCurrentThread(&val)) && val)) {
|
(NS_SUCCEEDED(mConsumerTarget->IsOnCurrentThread(&val)) && val)) {
|
||||||
|
@ -1676,7 +1676,7 @@ nsHttpTransaction::Release()
|
||||||
NS_LOG_RELEASE(this, count, "nsHttpTransaction");
|
NS_LOG_RELEASE(this, count, "nsHttpTransaction");
|
||||||
if (0 == count) {
|
if (0 == count) {
|
||||||
mRefCnt = 1; /* stablize */
|
mRefCnt = 1; /* stablize */
|
||||||
// it is essential that the transaction be destroyed on the consumer
|
// it is essential that the transaction be destroyed on the consumer
|
||||||
// thread (we could be holding the last reference to our consumer).
|
// thread (we could be holding the last reference to our consumer).
|
||||||
DeleteSelfOnConsumerThread();
|
DeleteSelfOnConsumerThread();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1728,7 +1728,7 @@ matchOld(nsHttpResponseHead *newHead, nsCString &old,
|
||||||
nsHttpAtom headerAtom)
|
nsHttpAtom headerAtom)
|
||||||
{
|
{
|
||||||
const char *val;
|
const char *val;
|
||||||
|
|
||||||
val = newHead->PeekHeader(headerAtom);
|
val = newHead->PeekHeader(headerAtom);
|
||||||
if (val && old.IsEmpty())
|
if (val && old.IsEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
@ -1763,7 +1763,7 @@ nsHttpTransaction::RestartVerifier::Verify(int64_t contentLength,
|
||||||
|
|
||||||
if (!matchOld(newHead, mTransferEncoding, nsHttp::Transfer_Encoding))
|
if (!matchOld(newHead, mTransferEncoding, nsHttp::Transfer_Encoding))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1782,7 +1782,7 @@ nsHttpTransaction::RestartVerifier::Set(int64_t contentLength,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mContentLength = contentLength;
|
mContentLength = contentLength;
|
||||||
|
|
||||||
if (head) {
|
if (head) {
|
||||||
const char *val;
|
const char *val;
|
||||||
val = head->PeekHeader(nsHttp::ETag);
|
val = head->PeekHeader(nsHttp::ETag);
|
||||||
|
|
|
@ -53,7 +53,7 @@ public:
|
||||||
|
|
||||||
//
|
//
|
||||||
// called to initialize the transaction
|
// called to initialize the transaction
|
||||||
//
|
//
|
||||||
// @param caps
|
// @param caps
|
||||||
// the transaction capabilities (see nsHttp.h)
|
// the transaction capabilities (see nsHttp.h)
|
||||||
// @param connInfo
|
// @param connInfo
|
||||||
|
@ -115,7 +115,7 @@ public:
|
||||||
const mozilla::TimeStamp GetPendingTime() { return mPendingTime; }
|
const mozilla::TimeStamp GetPendingTime() { return mPendingTime; }
|
||||||
bool UsesPipelining() const { return mCaps & NS_HTTP_ALLOW_PIPELINING; }
|
bool UsesPipelining() const { return mCaps & NS_HTTP_ALLOW_PIPELINING; }
|
||||||
|
|
||||||
void SetLoadGroupConnectionInfo(nsILoadGroupConnectionInfo *aLoadGroupCI) { mLoadGroupCI = aLoadGroupCI; }
|
void SetLoadGroupConnectionInfo(nsILoadGroupConnectionInfo *aLoadGroupCI) { mLoadGroupCI = aLoadGroupCI; }
|
||||||
nsILoadGroupConnectionInfo *LoadGroupConnectionInfo() { return mLoadGroupCI.get(); }
|
nsILoadGroupConnectionInfo *LoadGroupConnectionInfo() { return mLoadGroupCI.get(); }
|
||||||
void DispatchedAsBlocking();
|
void DispatchedAsBlocking();
|
||||||
void RemoveDispatchedAsBlocking();
|
void RemoveDispatchedAsBlocking();
|
||||||
|
@ -250,7 +250,7 @@ private:
|
||||||
// The time when the transaction was submitted to the Connection Manager
|
// The time when the transaction was submitted to the Connection Manager
|
||||||
mozilla::TimeStamp mPendingTime;
|
mozilla::TimeStamp mPendingTime;
|
||||||
|
|
||||||
class RestartVerifier
|
class RestartVerifier
|
||||||
{
|
{
|
||||||
|
|
||||||
// When a idemptotent transaction has received part of its response body
|
// When a idemptotent transaction has received part of its response body
|
||||||
|
@ -269,7 +269,7 @@ private:
|
||||||
, mSetup(false)
|
, mSetup(false)
|
||||||
{}
|
{}
|
||||||
~RestartVerifier() {}
|
~RestartVerifier() {}
|
||||||
|
|
||||||
void Set(int64_t contentLength, nsHttpResponseHead *head);
|
void Set(int64_t contentLength, nsHttpResponseHead *head);
|
||||||
bool Verify(int64_t contentLength, nsHttpResponseHead *head);
|
bool Verify(int64_t contentLength, nsHttpResponseHead *head);
|
||||||
bool IsDiscardingContent() { return mToReadBeforeRestart != 0; }
|
bool IsDiscardingContent() { return mToReadBeforeRestart != 0; }
|
||||||
|
|
|
@ -72,9 +72,9 @@ interface nsIHttpActivityObserver : nsISupports
|
||||||
/**
|
/**
|
||||||
* When aActivityType is ACTIVITY_TYPE_SOCKET_TRANSPORT
|
* When aActivityType is ACTIVITY_TYPE_SOCKET_TRANSPORT
|
||||||
* and aActivitySubtype is STATUS_SENDING_TO
|
* and aActivitySubtype is STATUS_SENDING_TO
|
||||||
* aExtraSizeData will contain the count of bytes sent
|
* aExtraSizeData will contain the count of bytes sent
|
||||||
* There may be more than one of these activities reported
|
* There may be more than one of these activities reported
|
||||||
* for a single http transaction, each aExtraSizeData
|
* for a single http transaction, each aExtraSizeData
|
||||||
* represents only that portion of the total bytes sent
|
* represents only that portion of the total bytes sent
|
||||||
*
|
*
|
||||||
* When aActivityType is ACTIVITY_TYPE_HTTP_TRANSACTION
|
* When aActivityType is ACTIVITY_TYPE_HTTP_TRANSACTION
|
||||||
|
|
|
@ -10,7 +10,7 @@ interface nsIPrincipal;
|
||||||
/**
|
/**
|
||||||
* nsIHttpAuthManager
|
* nsIHttpAuthManager
|
||||||
*
|
*
|
||||||
* This service provides access to cached HTTP authentication
|
* This service provides access to cached HTTP authentication
|
||||||
* user credentials (domain, username, password) for sites
|
* user credentials (domain, username, password) for sites
|
||||||
* visited during the current browser session.
|
* visited during the current browser session.
|
||||||
*
|
*
|
||||||
|
|
|
@ -17,7 +17,7 @@ interface nsIHttpAuthenticableChannel : nsIProxiedChannel
|
||||||
* If the channel being authenticated is using SSL.
|
* If the channel being authenticated is using SSL.
|
||||||
*/
|
*/
|
||||||
readonly attribute boolean isSSL;
|
readonly attribute boolean isSSL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if the proxy HTTP method used is CONNECT. If no proxy is being
|
* Returns if the proxy HTTP method used is CONNECT. If no proxy is being
|
||||||
* used it must return PR_FALSE.
|
* used it must return PR_FALSE.
|
||||||
|
@ -72,7 +72,7 @@ interface nsIHttpAuthenticableChannel : nsIProxiedChannel
|
||||||
readonly attribute ACString WWWChallenges;
|
readonly attribute ACString WWWChallenges;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the Proxy-Authorization request header. An empty string
|
* Sets the Proxy-Authorization request header. An empty string
|
||||||
* will clear it.
|
* will clear it.
|
||||||
*/
|
*/
|
||||||
void setProxyCredentials(in ACString credentials);
|
void setProxyCredentials(in ACString credentials);
|
||||||
|
|
|
@ -13,7 +13,7 @@ interface nsIHttpAuthenticableChannel;
|
||||||
* Interface designed to allow for pluggable HTTP authentication modules.
|
* Interface designed to allow for pluggable HTTP authentication modules.
|
||||||
* Implementations are registered under the ContractID:
|
* Implementations are registered under the ContractID:
|
||||||
*
|
*
|
||||||
* "@mozilla.org/network/http-authenticator;1?scheme=<auth-scheme>"
|
* "@mozilla.org/network/http-authenticator;1?scheme=<auth-scheme>"
|
||||||
*
|
*
|
||||||
* where <auth-scheme> is the lower-cased value of the authentication scheme
|
* where <auth-scheme> is the lower-cased value of the authentication scheme
|
||||||
* found in the server challenge per the rules of RFC 2617.
|
* found in the server challenge per the rules of RFC 2617.
|
||||||
|
@ -104,7 +104,7 @@ interface nsIHttpAuthenticator : nsISupports
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that the authenticator has used an out-of-band or internal
|
* Indicates that the authenticator has used an out-of-band or internal
|
||||||
* source of identity and tells the consumer that it must not cache
|
* source of identity and tells the consumer that it must not cache
|
||||||
* the returned identity because it might not be valid and would overwrite
|
* the returned identity because it might not be valid and would overwrite
|
||||||
* the cached identity. See bug 542318 comment 32.
|
* the cached identity. See bug 542318 comment 32.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -42,7 +42,7 @@ interface nsIHttpChannel : nsIChannel
|
||||||
* Get/set the HTTP referrer URI. This is the address (URI) of the
|
* Get/set the HTTP referrer URI. This is the address (URI) of the
|
||||||
* resource from which this channel's URI was obtained (see RFC2616 section
|
* resource from which this channel's URI was obtained (see RFC2616 section
|
||||||
* 14.36).
|
* 14.36).
|
||||||
*
|
*
|
||||||
* This attribute may only be set before the channel is opened.
|
* This attribute may only be set before the channel is opened.
|
||||||
*
|
*
|
||||||
* NOTE: The channel may silently refuse to set the Referer header if the
|
* NOTE: The channel may silently refuse to set the Referer header if the
|
||||||
|
@ -215,7 +215,7 @@ interface nsIHttpChannel : nsIChannel
|
||||||
* contents of |aValue|.
|
* contents of |aValue|.
|
||||||
*
|
*
|
||||||
* If aValue is empty and aMerge is false, the header will be cleared.
|
* If aValue is empty and aMerge is false, the header will be cleared.
|
||||||
*
|
*
|
||||||
* @throws NS_ERROR_NOT_AVAILABLE if called before the response
|
* @throws NS_ERROR_NOT_AVAILABLE if called before the response
|
||||||
* has been received (before onStartRequest).
|
* has been received (before onStartRequest).
|
||||||
* @throws NS_ERROR_ILLEGAL_VALUE if changing the value of this response
|
* @throws NS_ERROR_ILLEGAL_VALUE if changing the value of this response
|
||||||
|
|
|
@ -132,7 +132,7 @@ interface nsIHttpChannelInternal : nsISupports
|
||||||
/**
|
/**
|
||||||
* HTTPUpgrade allows for the use of HTTP to bootstrap another protocol
|
* HTTPUpgrade allows for the use of HTTP to bootstrap another protocol
|
||||||
* via the RFC 2616 Upgrade request header in conjunction with a 101 level
|
* via the RFC 2616 Upgrade request header in conjunction with a 101 level
|
||||||
* response. The nsIHttpUpgradeListener will have its
|
* response. The nsIHttpUpgradeListener will have its
|
||||||
* onTransportAvailable() method invoked if a matching 101 is processed.
|
* onTransportAvailable() method invoked if a matching 101 is processed.
|
||||||
* The arguments to onTransportAvailable provide the new protocol the low
|
* The arguments to onTransportAvailable provide the new protocol the low
|
||||||
* level tranport streams that are no longer used by HTTP.
|
* level tranport streams that are no longer used by HTTP.
|
||||||
|
|
|
@ -32,6 +32,6 @@ interface nsIHttpEventSink : nsISupports
|
||||||
*
|
*
|
||||||
* @return failure cancels redirect
|
* @return failure cancels redirect
|
||||||
*/
|
*/
|
||||||
void onRedirect(in nsIHttpChannel httpChannel,
|
void onRedirect(in nsIHttpChannel httpChannel,
|
||||||
in nsIChannel newChannel);
|
in nsIChannel newChannel);
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,14 +50,14 @@ interface nsIHttpProtocolHandler : nsIProxiedProtocolHandler
|
||||||
};
|
};
|
||||||
|
|
||||||
%{C++
|
%{C++
|
||||||
// ----------- Categories -----------
|
// ----------- Categories -----------
|
||||||
/**
|
/**
|
||||||
* At initialization time, the HTTP handler will initialize each service
|
* At initialization time, the HTTP handler will initialize each service
|
||||||
* registered under this category:
|
* registered under this category:
|
||||||
*/
|
*/
|
||||||
#define NS_HTTP_STARTUP_CATEGORY "http-startup-category"
|
#define NS_HTTP_STARTUP_CATEGORY "http-startup-category"
|
||||||
|
|
||||||
// ----------- Observer topics -----------
|
// ----------- Observer topics -----------
|
||||||
/**
|
/**
|
||||||
* nsIObserver notification corresponding to startup category. Services
|
* nsIObserver notification corresponding to startup category. Services
|
||||||
* registered under the startup category will receive this observer topic at
|
* registered under the startup category will receive this observer topic at
|
||||||
|
|
Загрузка…
Ссылка в новой задаче