summaryrefslogtreecommitdiffstats
path: root/netwerk/protocol/http
diff options
context:
space:
mode:
authorwicknix <39230578+wicknix@users.noreply.github.com>2019-04-15 18:58:07 -0500
committerGitHub <noreply@github.com>2019-04-15 18:58:07 -0500
commit5a1843c9f9e323627f9c35529e6a8c853d4dbb0d (patch)
tree62de3cd7cb8a6f75e568863bb73ca2deb80d87a9 /netwerk/protocol/http
parent065f6f9e5ebc1ed6cfaadaf7851b6021fa94a013 (diff)
parent095ea556855b38138e39e713f482eb440f7da9b2 (diff)
downloadUXP-5a1843c9f9e323627f9c35529e6a8c853d4dbb0d.tar
UXP-5a1843c9f9e323627f9c35529e6a8c853d4dbb0d.tar.gz
UXP-5a1843c9f9e323627f9c35529e6a8c853d4dbb0d.tar.lz
UXP-5a1843c9f9e323627f9c35529e6a8c853d4dbb0d.tar.xz
UXP-5a1843c9f9e323627f9c35529e6a8c853d4dbb0d.zip
Merge pull request #1 from MoonchildProductions/master
keep up with mc
Diffstat (limited to 'netwerk/protocol/http')
-rw-r--r--netwerk/protocol/http/ASpdySession.cpp2
-rw-r--r--netwerk/protocol/http/AlternateServices.cpp7
-rw-r--r--netwerk/protocol/http/Http2Compression.cpp42
-rw-r--r--netwerk/protocol/http/Http2Session.cpp11
-rw-r--r--netwerk/protocol/http/Http2Stream.cpp21
-rw-r--r--netwerk/protocol/http/HttpBaseChannel.cpp46
-rw-r--r--netwerk/protocol/http/HttpBaseChannel.h3
-rw-r--r--netwerk/protocol/http/PHttpChannelParams.h15
-rw-r--r--netwerk/protocol/http/TunnelUtils.cpp67
-rw-r--r--netwerk/protocol/http/TunnelUtils.h11
-rw-r--r--netwerk/protocol/http/nsHttpChannel.cpp297
-rw-r--r--netwerk/protocol/http/nsHttpChannel.h10
-rw-r--r--netwerk/protocol/http/nsHttpChannelAuthProvider.cpp34
-rw-r--r--netwerk/protocol/http/nsHttpConnection.cpp45
-rw-r--r--netwerk/protocol/http/nsHttpConnection.h3
-rw-r--r--netwerk/protocol/http/nsHttpConnectionInfo.cpp22
-rw-r--r--netwerk/protocol/http/nsHttpConnectionMgr.cpp62
-rw-r--r--netwerk/protocol/http/nsHttpConnectionMgr.h1
-rw-r--r--netwerk/protocol/http/nsHttpHandler.cpp126
-rw-r--r--netwerk/protocol/http/nsHttpHandler.h32
-rw-r--r--netwerk/protocol/http/nsHttpHeaderArray.cpp99
-rw-r--r--netwerk/protocol/http/nsHttpHeaderArray.h36
-rw-r--r--netwerk/protocol/http/nsHttpPipeline.cpp5
-rw-r--r--netwerk/protocol/http/nsHttpRequestHead.cpp23
-rw-r--r--netwerk/protocol/http/nsHttpRequestHead.h4
-rw-r--r--netwerk/protocol/http/nsHttpResponseHead.cpp50
-rw-r--r--netwerk/protocol/http/nsHttpResponseHead.h6
-rw-r--r--netwerk/protocol/http/nsHttpTransaction.cpp4
28 files changed, 453 insertions, 631 deletions
diff --git a/netwerk/protocol/http/ASpdySession.cpp b/netwerk/protocol/http/ASpdySession.cpp
index f22c326d1..d5d98804d 100644
--- a/netwerk/protocol/http/ASpdySession.cpp
+++ b/netwerk/protocol/http/ASpdySession.cpp
@@ -45,8 +45,6 @@ ASpdySession::NewSpdySession(uint32_t version,
// from a list provided in the SERVER HELLO filtered by our acceptable
// versions, so there is no risk of the server ignoring our prefs.
- Telemetry::Accumulate(Telemetry::SPDY_VERSION2, version);
-
return new Http2Session(aTransport, version, attemptingEarlyData);
}
diff --git a/netwerk/protocol/http/AlternateServices.cpp b/netwerk/protocol/http/AlternateServices.cpp
index b3e6babe3..ee2fa9331 100644
--- a/netwerk/protocol/http/AlternateServices.cpp
+++ b/netwerk/protocol/http/AlternateServices.cpp
@@ -654,8 +654,13 @@ private:
{
nsID channelId;
nsLoadFlags flags;
+
+ nsContentPolicyType contentPolicyType =
+ loadInfo ? loadInfo->GetExternalContentPolicyType()
+ : nsIContentPolicy::TYPE_OTHER;
+
if (NS_FAILED(gHttpHandler->NewChannelId(&channelId)) ||
- NS_FAILED(chan->Init(uri, caps, nullptr, 0, nullptr, channelId)) ||
+ NS_FAILED(chan->Init(uri, caps, nullptr, 0, nullptr, channelId, contentPolicyType)) ||
NS_FAILED(chan->SetAllowAltSvc(false)) ||
NS_FAILED(chan->SetRedirectMode(nsIHttpChannelInternal::REDIRECT_MODE_ERROR)) ||
NS_FAILED(chan->SetLoadInfo(loadInfo)) ||
diff --git a/netwerk/protocol/http/Http2Compression.cpp b/netwerk/protocol/http/Http2Compression.cpp
index 1b4603e1a..9206f8b4c 100644
--- a/netwerk/protocol/http/Http2Compression.cpp
+++ b/netwerk/protocol/http/Http2Compression.cpp
@@ -292,12 +292,6 @@ Http2BaseCompressor::Http2BaseCompressor()
Http2BaseCompressor::~Http2BaseCompressor()
{
- if (mPeakSize) {
- Telemetry::Accumulate(mPeakSizeID, mPeakSize);
- }
- if (mPeakCount) {
- Telemetry::Accumulate(mPeakCountID, mPeakCount);
- }
UnregisterStrongMemoryReporter(mDynamicReporter);
mDynamicReporter->mCompressor = nullptr;
mDynamicReporter = nullptr;
@@ -336,16 +330,6 @@ Http2BaseCompressor::MakeRoom(uint32_t amount, const char *direction)
bytesEvicted += mHeaderTable[index]->Size();
mHeaderTable.RemoveElement();
}
-
- if (!strcmp(direction, "decompressor")) {
- Telemetry::Accumulate(Telemetry::HPACK_ELEMENTS_EVICTED_DECOMPRESSOR, countEvicted);
- Telemetry::Accumulate(Telemetry::HPACK_BYTES_EVICTED_DECOMPRESSOR, bytesEvicted);
- Telemetry::Accumulate(Telemetry::HPACK_BYTES_EVICTED_RATIO_DECOMPRESSOR, (uint32_t)((100.0 * (double)bytesEvicted) / (double)amount));
- } else {
- Telemetry::Accumulate(Telemetry::HPACK_ELEMENTS_EVICTED_COMPRESSOR, countEvicted);
- Telemetry::Accumulate(Telemetry::HPACK_BYTES_EVICTED_COMPRESSOR, bytesEvicted);
- Telemetry::Accumulate(Telemetry::HPACK_BYTES_EVICTED_RATIO_COMPRESSOR, (uint32_t)((100.0 * (double)bytesEvicted) / (double)amount));
- }
}
void
@@ -418,7 +402,7 @@ Http2Decompressor::DecodeHeaderBlock(const uint8_t *data, uint32_t datalen,
nsresult rv = NS_OK;
nsresult softfail_rv = NS_OK;
- while (NS_SUCCEEDED(rv) && (mOffset < datalen)) {
+ while (NS_SUCCEEDED(rv) && (mOffset < mDataLen)) {
bool modifiesTable = true;
if (mData[mOffset] & 0x80) {
rv = DoIndexed();
@@ -700,6 +684,11 @@ nsresult
Http2Decompressor::DecodeFinalHuffmanCharacter(const HuffmanIncomingTable *table,
uint8_t &c, uint8_t &bitsLeft)
{
+ MOZ_ASSERT(mOffset <= mDataLen);
+ if (mOffset > mDataLen) {
+ NS_WARNING("DecodeFinalHuffmanCharacter trying to read beyond end of buffer");
+ return NS_ERROR_FAILURE;
+ }
uint8_t mask = (1 << bitsLeft) - 1;
uint8_t idx = mData[mOffset - 1] & mask;
idx <<= (8 - bitsLeft);
@@ -737,6 +726,7 @@ Http2Decompressor::DecodeFinalHuffmanCharacter(const HuffmanIncomingTable *table
uint8_t
Http2Decompressor::ExtractByte(uint8_t bitsLeft, uint32_t &bytesConsumed)
{
+ MOZ_DIAGNOSTIC_ASSERT(mOffset < mDataLen);
uint8_t rv;
if (bitsLeft) {
@@ -766,8 +756,8 @@ Http2Decompressor::DecodeHuffmanCharacter(const HuffmanIncomingTable *table,
uint8_t idx = ExtractByte(bitsLeft, bytesConsumed);
if (table->IndexHasANextTable(idx)) {
- if (bytesConsumed >= mDataLen) {
- if (!bitsLeft || (bytesConsumed > mDataLen)) {
+ if (mOffset >= mDataLen) {
+ if (!bitsLeft || (mOffset > mDataLen)) {
// TODO - does this get me into trouble in the new world?
// No info left in input to try to consume, we're done
LOG(("DecodeHuffmanCharacter all out of bits to consume, can't chain"));
@@ -908,6 +898,13 @@ Http2Decompressor::DoLiteralInternal(nsACString &name, nsACString &value,
return rv;
}
+ // sanity check
+ if (mOffset >= mDataLen) {
+ NS_WARNING("Http2 Decompressor ran out of data");
+ // This is session-fatal
+ return NS_ERROR_FAILURE;
+ }
+
bool isHuffmanEncoded;
if (!index) {
@@ -935,6 +932,13 @@ Http2Decompressor::DoLiteralInternal(nsACString &name, nsACString &value,
return rv;
}
+ // sanity check
+ if (mOffset >= mDataLen) {
+ NS_WARNING("Http2 Decompressor ran out of data");
+ // This is session-fatal
+ return NS_ERROR_FAILURE;
+ }
+
// now the value
uint32_t valueLen;
isHuffmanEncoded = mData[mOffset] & (1 << 7);
diff --git a/netwerk/protocol/http/Http2Session.cpp b/netwerk/protocol/http/Http2Session.cpp
index 4f350af83..4a178f091 100644
--- a/netwerk/protocol/http/Http2Session.cpp
+++ b/netwerk/protocol/http/Http2Session.cpp
@@ -168,13 +168,6 @@ Http2Session::~Http2Session()
this, mDownstreamState));
Shutdown();
-
- Telemetry::Accumulate(Telemetry::SPDY_PARALLEL_STREAMS, mConcurrentHighWater);
- Telemetry::Accumulate(Telemetry::SPDY_REQUEST_PER_CONN, (mNextStreamID - 1) / 2);
- Telemetry::Accumulate(Telemetry::SPDY_SERVER_INITIATED_STREAMS,
- mServerPushedResources);
- Telemetry::Accumulate(Telemetry::SPDY_GOAWAY_LOCAL, mClientGoAwayReason);
- Telemetry::Accumulate(Telemetry::SPDY_GOAWAY_PEER, mPeerGoAwayReason);
}
void
@@ -1508,13 +1501,11 @@ Http2Session::RecvSettings(Http2Session *self)
case SETTINGS_TYPE_MAX_CONCURRENT:
self->mMaxConcurrent = value;
- Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_MAX_STREAMS, value);
self->ProcessPending();
break;
case SETTINGS_TYPE_INITIAL_WINDOW:
{
- Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_IW, value >> 10);
int32_t delta = value - self->mServerInitialStreamWindow;
self->mServerInitialStreamWindow = value;
@@ -2494,8 +2485,6 @@ Http2Session::ReadyToProcessDataFrame(enum internalStateType newState)
newState == DISCARDING_DATA_FRAME_PADDING);
ChangeDownstreamState(newState);
- Telemetry::Accumulate(Telemetry::SPDY_CHUNK_RECVD,
- mInputFrameDataSize >> 10);
mLastDataReadEpoch = mLastReadEpoch;
if (!mInputFrameID) {
diff --git a/netwerk/protocol/http/Http2Stream.cpp b/netwerk/protocol/http/Http2Stream.cpp
index 7a8f96855..581ebe016 100644
--- a/netwerk/protocol/http/Http2Stream.cpp
+++ b/netwerk/protocol/http/Http2Stream.cpp
@@ -21,7 +21,6 @@
#include "Http2Push.h"
#include "TunnelUtils.h"
-#include "mozilla/Telemetry.h"
#include "nsAlgorithm.h"
#include "nsHttp.h"
#include "nsHttpHandler.h"
@@ -658,16 +657,7 @@ Http2Stream::GenerateOpen()
outputOffset += frameLen;
}
- Telemetry::Accumulate(Telemetry::SPDY_SYN_SIZE, compressedData.Length());
-
- // The size of the input headers is approximate
- uint32_t ratio =
- compressedData.Length() * 100 /
- (11 + requestURI.Length() +
- mFlatHttpRequestHeaders.Length());
-
mFlatHttpRequestHeaders.Truncate();
- Telemetry::Accumulate(Telemetry::SPDY_SYN_RATIO, ratio);
return NS_OK;
}
@@ -984,7 +974,7 @@ Http2Stream::GenerateDataFrameHeader(uint32_t dataLength, bool lastFrame)
}
// ConvertResponseHeaders is used to convert the response headers
-// into HTTP/1 format and report some telemetry
+// into HTTP/1 format
nsresult
Http2Stream::ConvertResponseHeaders(Http2Decompressor *decompressor,
nsACString &aHeadersIn,
@@ -1025,13 +1015,6 @@ Http2Stream::ConvertResponseHeaders(Http2Decompressor *decompressor,
return NS_ERROR_ILLEGAL_VALUE;
}
- if (aHeadersIn.Length() && aHeadersOut.Length()) {
- Telemetry::Accumulate(Telemetry::SPDY_SYN_REPLY_SIZE, aHeadersIn.Length());
- uint32_t ratio =
- aHeadersIn.Length() * 100 / aHeadersOut.Length();
- Telemetry::Accumulate(Telemetry::SPDY_SYN_REPLY_RATIO, ratio);
- }
-
// The decoding went ok. Now we can customize and clean up.
aHeadersIn.Truncate();
@@ -1047,7 +1030,7 @@ Http2Stream::ConvertResponseHeaders(Http2Decompressor *decompressor,
}
// ConvertPushHeaders is used to convert the pushed request headers
-// into HTTP/1 format and report some telemetry
+// into HTTP/1 format
nsresult
Http2Stream::ConvertPushHeaders(Http2Decompressor *decompressor,
nsACString &aHeadersIn,
diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp
index d161f9a43..86e177e71 100644
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -49,7 +49,6 @@
#include "LoadInfo.h"
#include "nsNullPrincipal.h"
#include "nsISSLSocketControl.h"
-#include "mozilla/Telemetry.h"
#include "nsIURL.h"
#include "nsIConsoleService.h"
#include "mozilla/BinarySearch.h"
@@ -152,7 +151,8 @@ HttpBaseChannel::Init(nsIURI *aURI,
nsProxyInfo *aProxyInfo,
uint32_t aProxyResolveFlags,
nsIURI *aProxyURI,
- const nsID& aChannelId)
+ const nsID& aChannelId,
+ nsContentPolicyType aContentPolicyType)
{
LOG(("HttpBaseChannel::Init [this=%p]\n", this));
@@ -201,7 +201,7 @@ HttpBaseChannel::Init(nsIURI *aURI,
rv = mRequestHead.SetHeader(nsHttp::Host, hostLine);
if (NS_FAILED(rv)) return rv;
- rv = gHttpHandler->AddStandardRequestHeaders(&mRequestHead, isHTTPS);
+ rv = gHttpHandler->AddStandardRequestHeaders(&mRequestHead, isHTTPS, aContentPolicyType);
if (NS_FAILED(rv)) return rv;
nsAutoCString type;
@@ -997,17 +997,6 @@ HttpBaseChannel::DoApplyContentConversions(nsIStreamListener* aNextListener,
}
LOG(("converter removed '%s' content-encoding\n", val));
- if (gHttpHandler->IsTelemetryEnabled()) {
- int mode = 0;
- if (from.Equals("gzip") || from.Equals("x-gzip")) {
- mode = 1;
- } else if (from.Equals("deflate") || from.Equals("x-deflate")) {
- mode = 2;
- } else if (from.Equals("br")) {
- mode = 3;
- }
- Telemetry::Accumulate(Telemetry::HTTP_CONTENT_ENCODING, mode);
- }
nextListener = converter;
}
else {
@@ -1667,13 +1656,7 @@ HttpBaseChannel::SetRequestHeader(const nsACString& aHeader,
return NS_ERROR_INVALID_ARG;
}
- nsHttpAtom atom = nsHttp::ResolveAtom(flatHeader.get());
- if (!atom) {
- NS_WARNING("failed to resolve atom");
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- return mRequestHead.SetHeader(atom, flatValue, aMerge);
+ return mRequestHead.SetHeader(aHeader, flatValue, aMerge);
}
NS_IMETHODIMP
@@ -1690,13 +1673,7 @@ HttpBaseChannel::SetEmptyRequestHeader(const nsACString& aHeader)
return NS_ERROR_INVALID_ARG;
}
- nsHttpAtom atom = nsHttp::ResolveAtom(flatHeader.get());
- if (!atom) {
- NS_WARNING("failed to resolve atom");
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- return mRequestHead.SetEmptyHeader(atom);
+ return mRequestHead.SetEmptyHeader(aHeader);
}
NS_IMETHODIMP
@@ -1752,7 +1729,7 @@ HttpBaseChannel::SetResponseHeader(const nsACString& header,
mResponseHeadersModified = true;
- return mResponseHead->SetHeader(atom, value, merge);
+ return mResponseHead->SetHeader(header, value, merge);
}
NS_IMETHODIMP
@@ -3690,14 +3667,17 @@ HttpBaseChannel::GetPerformance()
return nullptr;
}
- // We only add to the document's performance object if it has the same
- // principal as the one triggering the load. This is to prevent navigations
- // triggered _by_ the iframe from showing up in the parent document's
- // performance entries if they have different origins.
if (!mLoadInfo->TriggeringPrincipal()->Equals(loadingDocument->NodePrincipal())) {
return nullptr;
}
+ if (mLoadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_SUBDOCUMENT &&
+ !mLoadInfo->GetIsFromProcessingFrameAttributes()) {
+ // We only report loads caused by processing the attributes of the
+ // browsing context container.
+ return nullptr;
+ }
+
nsCOMPtr<nsPIDOMWindowInner> innerWindow = loadingDocument->GetInnerWindow();
if (!innerWindow) {
return nullptr;
diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h
index 9aa696a70..8def0f23c 100644
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -99,7 +99,8 @@ public:
virtual nsresult Init(nsIURI *aURI, uint32_t aCaps, nsProxyInfo *aProxyInfo,
uint32_t aProxyResolveFlags,
nsIURI *aProxyURI,
- const nsID& aChannelId);
+ const nsID& aChannelId,
+ nsContentPolicyType aContentPolicyType);
// nsIRequest
NS_IMETHOD GetName(nsACString& aName) override;
diff --git a/netwerk/protocol/http/PHttpChannelParams.h b/netwerk/protocol/http/PHttpChannelParams.h
index 4df5c7832..b04f57306 100644
--- a/netwerk/protocol/http/PHttpChannelParams.h
+++ b/netwerk/protocol/http/PHttpChannelParams.h
@@ -98,7 +98,11 @@ struct ParamTraits<mozilla::net::nsHttpHeaderArray::nsEntry>
static void Write(Message* aMsg, const paramType& aParam)
{
- WriteParam(aMsg, aParam.header);
+ if (aParam.headerNameOriginal.IsEmpty()) {
+ WriteParam(aMsg, aParam.header);
+ } else {
+ WriteParam(aMsg, aParam.headerNameOriginal);
+ }
WriteParam(aMsg, aParam.value);
switch (aParam.variety) {
case mozilla::net::nsHttpHeaderArray::eVarietyUnknown:
@@ -124,11 +128,18 @@ struct ParamTraits<mozilla::net::nsHttpHeaderArray::nsEntry>
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
uint8_t variety;
- if (!ReadParam(aMsg, aIter, &aResult->header) ||
+ nsAutoCString header;
+ if (!ReadParam(aMsg, aIter, &header) ||
!ReadParam(aMsg, aIter, &aResult->value) ||
!ReadParam(aMsg, aIter, &variety))
return false;
+ mozilla::net::nsHttpAtom atom = mozilla::net::nsHttp::ResolveAtom(header);
+ aResult->header = atom;
+ if (!header.Equals(atom.get())) {
+ aResult->headerNameOriginal = header;
+ }
+
switch (variety) {
case 0:
aResult->variety = mozilla::net::nsHttpHeaderArray::eVarietyUnknown;
diff --git a/netwerk/protocol/http/TunnelUtils.cpp b/netwerk/protocol/http/TunnelUtils.cpp
index 4cc24a07f..6880e0187 100644
--- a/netwerk/protocol/http/TunnelUtils.cpp
+++ b/netwerk/protocol/http/TunnelUtils.cpp
@@ -23,6 +23,7 @@
#include "nsNetCID.h"
#include "nsServiceManagerUtils.h"
#include "nsComponentManagerUtils.h"
+#include "nsSocketTransport2.h"
namespace mozilla {
namespace net {
@@ -42,6 +43,7 @@ TLSFilterTransaction::TLSFilterTransaction(nsAHttpTransaction *aWrapped,
, mSegmentReader(aReader)
, mSegmentWriter(aWriter)
, mForce(false)
+ , mReadSegmentReturnValue(NS_OK)
, mNudgeCounter(0)
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
@@ -130,6 +132,19 @@ TLSFilterTransaction::Close(nsresult aReason)
}
mTransaction->Close(aReason);
mTransaction = nullptr;
+
+ RefPtr<NullHttpTransaction> baseTrans(do_QueryReferent(mWeakTrans));
+ SpdyConnectTransaction *trans = baseTrans
+ ? baseTrans->QuerySpdyConnectTransaction()
+ : nullptr;
+
+ LOG(("TLSFilterTransaction::Close %p aReason=%" PRIx32 " trans=%p\n",
+ this, static_cast<uint32_t>(aReason), trans));
+
+ if (trans) {
+ trans->Close(aReason);
+ trans = nullptr;
+ }
}
nsresult
@@ -140,7 +155,7 @@ TLSFilterTransaction::OnReadSegment(const char *aData,
LOG(("TLSFilterTransaction %p OnReadSegment %d (buffered %d)\n",
this, aCount, mEncryptedTextUsed));
- mReadSegmentBlocked = false;
+ mReadSegmentReturnValue = NS_OK;
MOZ_ASSERT(mSegmentReader);
if (!mSecInfo) {
return NS_ERROR_FAILURE;
@@ -188,10 +203,12 @@ TLSFilterTransaction::OnReadSegment(const char *aData,
return NS_OK;
}
// mTransaction ReadSegments actually obscures this code, so
- // keep it in a member var for this::ReadSegments to insepct. Similar
+ // keep it in a member var for this::ReadSegments to inspect. Similar
// to nsHttpConnection::mSocketOutCondition
- mReadSegmentBlocked = (PR_GetError() == PR_WOULD_BLOCK_ERROR);
- return mReadSegmentBlocked ? NS_BASE_STREAM_WOULD_BLOCK : NS_ERROR_FAILURE;
+ PRErrorCode code = PR_GetError();
+ mReadSegmentReturnValue = ErrorAccordingToNSPR(code);
+
+ return mReadSegmentReturnValue;
}
aCount -= written;
aData += written;
@@ -273,10 +290,18 @@ TLSFilterTransaction::OnWriteSegment(char *aData,
mFilterReadCode = NS_OK;
int32_t bytesRead = PR_Read(mFD, aData, aCount);
if (bytesRead == -1) {
- if (PR_GetError() == PR_WOULD_BLOCK_ERROR) {
+ PRErrorCode code = PR_GetError();
+ if (code == PR_WOULD_BLOCK_ERROR) {
return NS_BASE_STREAM_WOULD_BLOCK;
}
- return NS_ERROR_FAILURE;
+ // If reading from the socket succeeded (NS_SUCCEEDED(mFilterReadCode)),
+ // but the nss layer encountered an error remember the error.
+ if (NS_SUCCEEDED(mFilterReadCode)) {
+ mFilterReadCode = ErrorAccordingToNSPR(code);
+ LOG(("TLSFilterTransaction::OnWriteSegment %p nss error %" PRIx32 ".\n",
+ this, static_cast<uint32_t>(mFilterReadCode)));
+ }
+ return mFilterReadCode;
}
*outCountRead = bytesRead;
@@ -303,7 +328,7 @@ TLSFilterTransaction::FilterInput(char *aBuf, int32_t aAmount)
if (NS_SUCCEEDED(mFilterReadCode) && outCountRead) {
LOG(("TLSFilterTransaction::FilterInput rv=%x read=%d input from net "
"1 layer stripped, 1 still on\n", mFilterReadCode, outCountRead));
- if (mReadSegmentBlocked) {
+ if (mReadSegmentReturnValue == NS_BASE_STREAM_WOULD_BLOCK) {
mNudgeCounter = 0;
}
}
@@ -325,19 +350,18 @@ TLSFilterTransaction::ReadSegments(nsAHttpSegmentReader *aReader,
return NS_ERROR_UNEXPECTED;
}
- mReadSegmentBlocked = false;
+ mReadSegmentReturnValue = NS_OK;
mSegmentReader = aReader;
nsresult rv = mTransaction->ReadSegments(this, aCount, outCountRead);
LOG(("TLSFilterTransaction %p called trans->ReadSegments rv=%x %d\n",
this, rv, *outCountRead));
- if (NS_SUCCEEDED(rv) && mReadSegmentBlocked) {
- rv = NS_BASE_STREAM_WOULD_BLOCK;
+ if (NS_SUCCEEDED(rv) && (mReadSegmentReturnValue == NS_BASE_STREAM_WOULD_BLOCK)) {
LOG(("TLSFilterTransaction %p read segment blocked found rv=%x\n",
- this, rv));
+ this, static_cast<uint32_t>(rv)));
Connection()->ForceSend();
}
- return rv;
+ return NS_SUCCEEDED(rv) ? mReadSegmentReturnValue : rv;
}
nsresult
@@ -442,7 +466,10 @@ TLSFilterTransaction::Notify(nsITimer *timer)
if (timer != mTimer) {
return NS_ERROR_UNEXPECTED;
}
- StartTimerCallback();
+ nsresult rv = StartTimerCallback();
+ if (NS_FAILED(rv)) {
+ Close(rv);
+ }
return NS_OK;
}
@@ -456,7 +483,7 @@ TLSFilterTransaction::StartTimerCallback()
// This class can be called re-entrantly, so cleanup m* before ->on()
RefPtr<NudgeTunnelCallback> cb(mNudgeCallback);
mNudgeCallback = nullptr;
- cb->OnTunnelNudged(this);
+ return cb->OnTunnelNudged(this);
}
return NS_OK;
}
@@ -675,10 +702,12 @@ TLSFilterTransaction::TakeSubTransactions(
}
nsresult
-TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans)
+TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans,
+ nsAHttpTransaction *aSpdyConnectTransaction)
{
- LOG(("TLSFilterTransaction::SetProxiedTransaction [this=%p] aTrans=%p\n",
- this, aTrans));
+ LOG(("TLSFilterTransaction::SetProxiedTransaction [this=%p] aTrans=%p, "
+ "aSpdyConnectTransaction=%p\n",
+ this, aTrans, aSpdyConnectTransaction));
mTransaction = aTrans;
nsCOMPtr<nsIInterfaceRequestor> callbacks;
@@ -688,6 +717,8 @@ TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans)
secCtrl->SetNotificationCallbacks(callbacks);
}
+ mWeakTrans = do_GetWeakReference(aSpdyConnectTransaction);
+
return NS_OK;
}
@@ -1075,7 +1106,7 @@ SpdyConnectTransaction::MapStreamToHttpConnection(nsISocketTransport *aTransport
if (mForcePlainText) {
mTunneledConn->ForcePlainText();
} else {
- mTunneledConn->SetupSecondaryTLS();
+ mTunneledConn->SetupSecondaryTLS(this);
mTunneledConn->SetInSpdyTunnel(true);
}
diff --git a/netwerk/protocol/http/TunnelUtils.h b/netwerk/protocol/http/TunnelUtils.h
index 20cfaf7ee..4a003082e 100644
--- a/netwerk/protocol/http/TunnelUtils.h
+++ b/netwerk/protocol/http/TunnelUtils.h
@@ -93,10 +93,11 @@ class TLSFilterTransaction;
class NudgeTunnelCallback : public nsISupports
{
public:
- virtual void OnTunnelNudged(TLSFilterTransaction *) = 0;
+ virtual nsresult OnTunnelNudged(TLSFilterTransaction *) = 0;
};
-#define NS_DECL_NUDGETUNNELCALLBACK void OnTunnelNudged(TLSFilterTransaction *) override;
+#define NS_DECL_NUDGETUNNELCALLBACK \
+ nsresult OnTunnelNudged(TLSFilterTransaction *) override;
class TLSFilterTransaction final
: public nsAHttpTransaction
@@ -121,7 +122,8 @@ public:
nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment) override;
nsresult GetTransactionSecurityInfo(nsISupports **) override;
nsresult NudgeTunnel(NudgeTunnelCallback *callback);
- nsresult SetProxiedTransaction(nsAHttpTransaction *aTrans);
+ MOZ_MUST_USE nsresult SetProxiedTransaction(nsAHttpTransaction *aTrans,
+ nsAHttpTransaction *aSpdyConnectTransaction = nullptr);
void newIODriver(nsIAsyncInputStream *aSocketIn,
nsIAsyncOutputStream *aSocketOut,
nsIAsyncInputStream **outSocketIn,
@@ -153,6 +155,7 @@ private:
private:
RefPtr<nsAHttpTransaction> mTransaction;
+ nsWeakPtr mWeakTrans; // SpdyConnectTransaction *
nsCOMPtr<nsISupports> mSecInfo;
nsCOMPtr<nsITimer> mTimer;
RefPtr<NudgeTunnelCallback> mNudgeCallback;
@@ -168,7 +171,7 @@ private:
nsresult mFilterReadCode;
bool mForce;
- bool mReadSegmentBlocked;
+ nsresult mReadSegmentReturnValue;
uint32_t mNudgeCounter;
};
diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
index d7247eeab..481df5ff0 100644
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -83,7 +83,6 @@
#include "nsCRT.h"
#include "CacheObserver.h"
#include "mozilla/dom/Performance.h"
-#include "mozilla/Telemetry.h"
#include "AlternateServices.h"
#include "InterceptedChannel.h"
#include "nsIHttpPushListener.h"
@@ -123,30 +122,6 @@ static NS_DEFINE_CID(kStreamListenerTeeCID, NS_STREAMLISTENERTEE_CID);
static NS_DEFINE_CID(kStreamTransportServiceCID,
NS_STREAMTRANSPORTSERVICE_CID);
-enum CacheDisposition {
- kCacheHit = 1,
- kCacheHitViaReval = 2,
- kCacheMissedViaReval = 3,
- kCacheMissed = 4
-};
-
-void
-AccumulateCacheHitTelemetry(CacheDisposition hitOrMiss)
-{
- if (!CacheObserver::UseNewCache()) {
- Telemetry::Accumulate(Telemetry::HTTP_CACHE_DISPOSITION_2, hitOrMiss);
- }
- else {
- Telemetry::Accumulate(Telemetry::HTTP_CACHE_DISPOSITION_2_V2, hitOrMiss);
-
- int32_t experiment = CacheObserver::HalfLifeExperiment();
- if (experiment > 0 && hitOrMiss == kCacheMissed) {
- Telemetry::Accumulate(Telemetry::HTTP_CACHE_MISS_HALFLIFE_EXPERIMENT_2,
- experiment - 1);
- }
- }
-}
-
// Computes and returns a SHA1 hash of the input buffer. The input buffer
// must be a null-terminated string.
nsresult
@@ -324,11 +299,15 @@ nsHttpChannel::nsHttpChannel()
, mPushedStream(nullptr)
, mLocalBlocklist(false)
, mWarningReporter(nullptr)
+ , mSendUpgradeRequest(false)
, mDidReval(false)
{
LOG(("Creating nsHttpChannel [this=%p]\n", this));
mChannelCreationTime = PR_Now();
mChannelCreationTimestamp = TimeStamp::Now();
+
+ mSendUpgradeRequest =
+ Preferences::GetBool("network.http.upgrade-insecure-requests", false);
}
nsHttpChannel::~nsHttpChannel()
@@ -345,10 +324,16 @@ nsHttpChannel::Init(nsIURI *uri,
nsProxyInfo *proxyInfo,
uint32_t proxyResolveFlags,
nsIURI *proxyURI,
- const nsID& channelId)
-{
- nsresult rv = HttpBaseChannel::Init(uri, caps, proxyInfo,
- proxyResolveFlags, proxyURI, channelId);
+ const nsID& channelId,
+ nsContentPolicyType aContentPolicyType)
+{
+ nsresult rv = HttpBaseChannel::Init(uri,
+ caps,
+ proxyInfo,
+ proxyResolveFlags,
+ proxyURI,
+ channelId,
+ aContentPolicyType);
if (NS_FAILED(rv))
return rv;
@@ -388,8 +373,9 @@ nsHttpChannel::Connect()
mLoadInfo->GetExternalContentPolicyType() :
nsIContentPolicy::TYPE_OTHER;
- if (type == nsIContentPolicy::TYPE_DOCUMENT ||
- type == nsIContentPolicy::TYPE_SUBDOCUMENT) {
+ if (mSendUpgradeRequest &&
+ (type == nsIContentPolicy::TYPE_DOCUMENT ||
+ type == nsIContentPolicy::TYPE_SUBDOCUMENT)) {
rv = SetRequestHeader(NS_LITERAL_CSTRING("Upgrade-Insecure-Requests"),
NS_LITERAL_CSTRING("1"), false);
NS_ENSURE_SUCCESS(rv, rv);
@@ -500,11 +486,6 @@ nsHttpChannel::ContinueConnect()
event->Revoke();
}
- // Don't accumulate the cache hit telemetry for intercepted channels.
- if (mInterceptCache != INTERCEPTED) {
- AccumulateCacheHitTelemetry(kCacheHit);
- }
-
return rv;
}
else if (mLoadFlags & LOAD_ONLY_FROM_CACHE) {
@@ -1091,10 +1072,8 @@ ProcessXCTO(nsIURI* aURI, nsHttpResponseHead* aResponseHead, nsILoadInfo* aLoadI
if (aLoadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_IMAGE) {
if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("image/"))) {
- Accumulate(Telemetry::XCTO_NOSNIFF_BLOCK_IMAGE, 0);
return NS_OK;
}
- Accumulate(Telemetry::XCTO_NOSNIFF_BLOCK_IMAGE, 1);
// Instead of consulting Preferences::GetBool() all the time we
// can cache the result to speed things up.
static bool sXCTONosniffBlockImages = false;
@@ -1141,26 +1120,21 @@ EnsureMIMEOfScript(nsIURI* aURI, nsHttpResponseHead* aResponseHead, nsILoadInfo*
if (nsContentUtils::IsJavascriptMIMEType(typeString)) {
// script load has type script
- Telemetry::Accumulate(Telemetry::SCRIPT_BLOCK_INCORRECT_MIME, 1);
return NS_OK;
}
bool block = false;
if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("image/"))) {
// script load has type image
- Telemetry::Accumulate(Telemetry::SCRIPT_BLOCK_INCORRECT_MIME, 2);
block = true;
} else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("audio/"))) {
// script load has type audio
- Telemetry::Accumulate(Telemetry::SCRIPT_BLOCK_INCORRECT_MIME, 3);
block = true;
} else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("video/"))) {
// script load has type video
- Telemetry::Accumulate(Telemetry::SCRIPT_BLOCK_INCORRECT_MIME, 4);
block = true;
} else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/csv"))) {
// script load has type text/csv
- Telemetry::Accumulate(Telemetry::SCRIPT_BLOCK_INCORRECT_MIME, 6);
block = true;
}
@@ -1186,42 +1160,35 @@ EnsureMIMEOfScript(nsIURI* aURI, nsHttpResponseHead* aResponseHead, nsILoadInfo*
if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/plain"))) {
// script load has type text/plain
- Telemetry::Accumulate(Telemetry::SCRIPT_BLOCK_INCORRECT_MIME, 5);
return NS_OK;
}
if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/xml"))) {
// script load has type text/xml
- Telemetry::Accumulate(Telemetry::SCRIPT_BLOCK_INCORRECT_MIME, 7);
return NS_OK;
}
if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("application/octet-stream"))) {
// script load has type application/octet-stream
- Telemetry::Accumulate(Telemetry::SCRIPT_BLOCK_INCORRECT_MIME, 8);
return NS_OK;
}
if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("application/xml"))) {
// script load has type application/xml
- Telemetry::Accumulate(Telemetry::SCRIPT_BLOCK_INCORRECT_MIME, 9);
return NS_OK;
}
if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/html"))) {
// script load has type text/html
- Telemetry::Accumulate(Telemetry::SCRIPT_BLOCK_INCORRECT_MIME, 10);
return NS_OK;
}
if (contentType.IsEmpty()) {
// script load has no type
- Telemetry::Accumulate(Telemetry::SCRIPT_BLOCK_INCORRECT_MIME, 11);
return NS_OK;
}
// script load has unknown type
- Telemetry::Accumulate(Telemetry::SCRIPT_BLOCK_INCORRECT_MIME, 0);
return NS_OK;
}
@@ -1867,65 +1834,6 @@ nsHttpChannel::ProcessResponse()
LOG(("nsHttpChannel::ProcessResponse [this=%p httpStatus=%u]\n",
this, httpStatus));
- // do some telemetry
- if (gHttpHandler->IsTelemetryEnabled()) {
- // Gather data on whether the transaction and page (if this is
- // the initial page load) is being loaded with SSL.
- Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_IS_SSL,
- mConnectionInfo->EndToEndSSL());
- if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) {
- Telemetry::Accumulate(Telemetry::HTTP_PAGELOAD_IS_SSL,
- mConnectionInfo->EndToEndSSL());
- }
-
- // how often do we see something like Alternate-Protocol: "443:quic,p=1"
- nsAutoCString alt_protocol;
- mResponseHead->GetHeader(nsHttp::Alternate_Protocol, alt_protocol);
- bool saw_quic = (!alt_protocol.IsEmpty() &&
- PL_strstr(alt_protocol.get(), "quic")) ? 1 : 0;
- Telemetry::Accumulate(Telemetry::HTTP_SAW_QUIC_ALT_PROTOCOL, saw_quic);
-
- // Gather data on how many URLS get redirected
- switch (httpStatus) {
- case 200:
- Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 0);
- break;
- case 301:
- Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 1);
- break;
- case 302:
- Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 2);
- break;
- case 304:
- Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 3);
- break;
- case 307:
- Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 4);
- break;
- case 308:
- Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 5);
- break;
- case 400:
- Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 6);
- break;
- case 401:
- Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 7);
- break;
- case 403:
- Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 8);
- break;
- case 404:
- Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 9);
- break;
- case 500:
- Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 10);
- break;
- default:
- Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 11);
- break;
- }
- }
-
// Let the predictor know whether this was a cacheable response or not so
// that it knows whether or not to possibly prefetch this resource in the
// future.
@@ -2193,33 +2101,6 @@ nsHttpChannel::ContinueProcessResponse2(nsresult rv)
break;
}
- if (gHttpHandler->IsTelemetryEnabled()) {
- CacheDisposition cacheDisposition;
- if (!mDidReval) {
- cacheDisposition = kCacheMissed;
- } else if (successfulReval) {
- cacheDisposition = kCacheHitViaReval;
- } else {
- cacheDisposition = kCacheMissedViaReval;
- }
- AccumulateCacheHitTelemetry(cacheDisposition);
-
- Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_VERSION,
- mResponseHead->Version());
-
- if (mResponseHead->Version() == NS_HTTP_VERSION_0_9) {
- // DefaultPortTopLevel = 0, DefaultPortSubResource = 1,
- // NonDefaultPortTopLevel = 2, NonDefaultPortSubResource = 3
- uint32_t v09Info = 0;
- if (!(mLoadFlags & LOAD_INITIAL_DOCUMENT_URI)) {
- v09Info += 1;
- }
- if (mConnectionInfo->OriginPort() != mConnectionInfo->DefaultPort()) {
- v09Info += 2;
- }
- Telemetry::Accumulate(Telemetry::HTTP_09_INFO, v09Info);
- }
- }
return rv;
}
@@ -3212,7 +3093,6 @@ nsHttpChannel::ProcessNotModified()
PipelineFeedbackInfo(mConnectionInfo,
nsHttpConnectionMgr::RedCorruptedContent,
nullptr, 0);
- Telemetry::Accumulate(Telemetry::CACHE_LM_INCONSISTENT, true);
}
// merge any new headers with the cached response headers
@@ -3866,8 +3746,6 @@ nsHttpChannel::OnCacheEntryCheck(nsICacheEntry* entry, nsIApplicationCache* appC
(!mCachedResponseHead->ExpiresInPast() ||
!mCachedResponseHead->MustValidateIfExpired())) {
LOG(("NOT validating based on isForcedValid being true.\n"));
- Telemetry::AutoCounter<Telemetry::PREDICTOR_TOTAL_PREFETCHES_USED> used;
- ++used;
doValidation = false;
}
// If the LOAD_FROM_CACHE flag is set, any cached data can simply be used
@@ -4222,11 +4100,6 @@ nsHttpChannel::OnNormalCacheEntryAvailable(nsICacheEntry *aEntry,
if (NS_SUCCEEDED(aEntryStatus)) {
mCacheEntry = aEntry;
mCacheEntryIsWriteOnly = aNew;
-
- if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) {
- Telemetry::Accumulate(Telemetry::HTTP_OFFLINE_CACHE_DOCUMENT_LOAD,
- false);
- }
}
return NS_OK;
@@ -5897,17 +5770,13 @@ nsHttpChannel::BeginConnect()
LOG(("nsHttpChannel %p Using connection info from altsvc mapping", this));
mapping->GetConnectionInfo(getter_AddRefs(mConnectionInfo), proxyInfo, originAttributes);
- Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC, true);
- Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC_OE, !isHttps);
} else if (mConnectionInfo) {
LOG(("nsHttpChannel %p Using channel supplied connection info", this));
- Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC, false);
} else {
LOG(("nsHttpChannel %p Using default connection info", this));
mConnectionInfo = new nsHttpConnectionInfo(host, port, EmptyCString(), mUsername, proxyInfo,
originAttributes, isHttps);
- Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC, false);
}
// Set network interface id only when it's not empty to avoid
@@ -6637,8 +6506,6 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
if (mTimingEnabled && request == mCachePump) {
mCacheReadEnd = TimeStamp::Now();
-
- ReportNetVSCacheTelemetry();
}
// allow content to be cached if it was loaded successfully (bug #482935)
@@ -6829,7 +6696,6 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
chanDisposition = static_cast<ChannelDisposition>(chanDisposition + kHttpsCanceled);
}
LOG((" nsHttpChannel::OnStopRequest ChannelDisposition %d\n", chanDisposition));
- Telemetry::Accumulate(Telemetry::HTTP_CHANNEL_DISPOSITION, chanDisposition);
// if needed, check cache entry has all data we expect
if (mCacheEntry && mCachePump &&
@@ -8196,134 +8062,5 @@ nsHttpChannel::SetDoNotTrack()
}
}
-
-void
-nsHttpChannel::ReportNetVSCacheTelemetry()
-{
- nsresult rv;
- if (!mCacheEntry) {
- return;
- }
-
- // We only report telemetry if the entry is persistent (on disk)
- bool persistent;
- rv = mCacheEntry->GetPersistent(&persistent);
- if (NS_FAILED(rv) || !persistent) {
- return;
- }
-
- nsXPIDLCString tmpStr;
- rv = mCacheEntry->GetMetaDataElement("net-response-time-onstart",
- getter_Copies(tmpStr));
- if (NS_FAILED(rv)) {
- return;
- }
- uint64_t onStartNetTime = tmpStr.ToInteger64(&rv);
- if (NS_FAILED(rv)) {
- return;
- }
-
- tmpStr.Truncate();
- rv = mCacheEntry->GetMetaDataElement("net-response-time-onstop",
- getter_Copies(tmpStr));
- if (NS_FAILED(rv)) {
- return;
- }
- uint64_t onStopNetTime = tmpStr.ToInteger64(&rv);
- if (NS_FAILED(rv)) {
- return;
- }
-
- uint64_t onStartCacheTime = (mOnStartRequestTimestamp - mAsyncOpenTime).ToMilliseconds();
- int64_t onStartDiff = onStartNetTime - onStartCacheTime;
- onStartDiff += 500; // We offset the difference by 500 ms to report positive values in telemetry
-
- uint64_t onStopCacheTime = (mCacheReadEnd - mAsyncOpenTime).ToMilliseconds();
- int64_t onStopDiff = onStopNetTime - onStopCacheTime;
- onStopDiff += 500; // We offset the difference by 500 ms
-
- if (mDidReval) {
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTART_REVALIDATED, onStartDiff);
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_REVALIDATED, onStopDiff);
- } else {
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTART_NOTREVALIDATED, onStartDiff);
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_NOTREVALIDATED, onStopDiff);
- }
-
- if (mDidReval) {
- // We don't report revalidated probes as the data would be skewed.
- return;
- }
-
- uint32_t diskStorageSizeK = 0;
- rv = mCacheEntry->GetDiskStorageSizeInKB(&diskStorageSizeK);
- if (NS_FAILED(rv)) {
- return;
- }
-
- nsAutoCString contentType;
- if (mResponseHead && mResponseHead->HasContentType()) {
- mResponseHead->ContentType(contentType);
- }
- bool isImage = StringBeginsWith(contentType, NS_LITERAL_CSTRING("image/"));
- if (isImage) {
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTART_ISIMG, onStartDiff);
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_ISIMG, onStopDiff);
- } else {
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTART_NOTIMG, onStartDiff);
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_NOTIMG, onStopDiff);
- }
-
- if (mCacheOpenWithPriority) {
- if (mCacheQueueSizeWhenOpen < 5) {
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTART_QSMALL_HIGHPRI, onStartDiff);
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_QSMALL_HIGHPRI, onStopDiff);
- } else if (mCacheQueueSizeWhenOpen < 10) {
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTART_QMED_HIGHPRI, onStartDiff);
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_QMED_HIGHPRI, onStopDiff);
- } else {
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTART_QBIG_HIGHPRI, onStartDiff);
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_QBIG_HIGHPRI, onStopDiff);
- }
- } else { // The limits are higher for normal priority cache queues
- if (mCacheQueueSizeWhenOpen < 10) {
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTART_QSMALL_NORMALPRI, onStartDiff);
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_QSMALL_NORMALPRI, onStopDiff);
- } else if (mCacheQueueSizeWhenOpen < 50) {
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTART_QMED_NORMALPRI, onStartDiff);
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_QMED_NORMALPRI, onStopDiff);
- } else {
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTART_QBIG_NORMALPRI, onStartDiff);
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_QBIG_NORMALPRI, onStopDiff);
- }
- }
-
- if (diskStorageSizeK < 32) {
- if (mCacheOpenWithPriority) {
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTART_SMALL_HIGHPRI, onStartDiff);
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_SMALL_HIGHPRI, onStopDiff);
- } else {
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTART_SMALL_NORMALPRI, onStartDiff);
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_SMALL_NORMALPRI, onStopDiff);
- }
- } else if (diskStorageSizeK < 256) {
- if (mCacheOpenWithPriority) {
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTART_MED_HIGHPRI, onStartDiff);
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_MED_HIGHPRI, onStopDiff);
- } else {
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTART_MED_NORMALPRI, onStartDiff);
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_MED_NORMALPRI, onStopDiff);
- }
- } else {
- if (mCacheOpenWithPriority) {
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTART_LARGE_HIGHPRI, onStartDiff);
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_LARGE_HIGHPRI, onStopDiff);
- } else {
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTART_LARGE_NORMALPRI, onStartDiff);
- Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_LARGE_NORMALPRI, onStopDiff);
- }
- }
-}
-
} // namespace net
} // namespace mozilla
diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h
index 2e24d6e81..0038e1f71 100644
--- a/netwerk/protocol/http/nsHttpChannel.h
+++ b/netwerk/protocol/http/nsHttpChannel.h
@@ -123,7 +123,8 @@ public:
virtual nsresult Init(nsIURI *aURI, uint32_t aCaps, nsProxyInfo *aProxyInfo,
uint32_t aProxyResolveFlags,
nsIURI *aProxyURI,
- const nsID& aChannelId) override;
+ const nsID& aChannelId,
+ nsContentPolicyType aContentPolicyType) override;
nsresult OnPush(const nsACString &uri, Http2PushedStream *pushedStream);
@@ -431,9 +432,6 @@ private:
rv == NS_ERROR_MALFORMED_URI;
}
- // Report net vs cache time telemetry
- void ReportNetVSCacheTelemetry();
-
// Create a aggregate set of the current notification callbacks
// and ensure the transaction is updated to use it.
void UpdateAggregateCallbacks();
@@ -597,6 +595,10 @@ private:
HttpChannelSecurityWarningReporter* mWarningReporter;
RefPtr<ADivertableParentChannel> mParentChannel;
+
+ // Whether we send opportunistic encryption requests.
+ bool mSendUpgradeRequest;
+
protected:
virtual void DoNotifyListenerCleanup() override;
diff --git a/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp b/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
index d04f47ddc..0e7eb55c3 100644
--- a/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
+++ b/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
@@ -867,24 +867,6 @@ nsHttpChannelAuthProvider::GetCredentialsForChallenge(const char *challenge,
else if (authFlags & nsIHttpAuthenticator::IDENTITY_ENCRYPTED)
level = nsIAuthPrompt2::LEVEL_PW_ENCRYPTED;
- // Collect statistics on how frequently the various types of HTTP
- // authentication are used over SSL and non-SSL connections.
- if (gHttpHandler->IsTelemetryEnabled()) {
- if (NS_LITERAL_CSTRING("basic").LowerCaseEqualsASCII(authType)) {
- Telemetry::Accumulate(Telemetry::HTTP_AUTH_TYPE_STATS,
- UsingSSL() ? HTTP_AUTH_BASIC_SECURE : HTTP_AUTH_BASIC_INSECURE);
- } else if (NS_LITERAL_CSTRING("digest").LowerCaseEqualsASCII(authType)) {
- Telemetry::Accumulate(Telemetry::HTTP_AUTH_TYPE_STATS,
- UsingSSL() ? HTTP_AUTH_DIGEST_SECURE : HTTP_AUTH_DIGEST_INSECURE);
- } else if (NS_LITERAL_CSTRING("ntlm").LowerCaseEqualsASCII(authType)) {
- Telemetry::Accumulate(Telemetry::HTTP_AUTH_TYPE_STATS,
- UsingSSL() ? HTTP_AUTH_NTLM_SECURE : HTTP_AUTH_NTLM_INSECURE);
- } else if (NS_LITERAL_CSTRING("negotiate").LowerCaseEqualsASCII(authType)) {
- Telemetry::Accumulate(Telemetry::HTTP_AUTH_TYPE_STATS,
- UsingSSL() ? HTTP_AUTH_NEGOTIATE_SECURE : HTTP_AUTH_NEGOTIATE_INSECURE);
- }
- }
-
// Depending on the pref setting, the authentication dialog may be
// blocked for all sub-resources, blocked for cross-origin
// sub-resources, or always allowed for sub-resources.
@@ -991,22 +973,6 @@ nsHttpChannelAuthProvider::BlockPrompt()
}
}
- if (gHttpHandler->IsTelemetryEnabled()) {
- if (topDoc) {
- Telemetry::Accumulate(Telemetry::HTTP_AUTH_DIALOG_STATS,
- HTTP_AUTH_DIALOG_TOP_LEVEL_DOC);
- } else if (xhr) {
- Telemetry::Accumulate(Telemetry::HTTP_AUTH_DIALOG_STATS,
- HTTP_AUTH_DIALOG_XHR);
- } else if (!mCrossOrigin) {
- Telemetry::Accumulate(Telemetry::HTTP_AUTH_DIALOG_STATS,
- HTTP_AUTH_DIALOG_SAME_ORIGIN_SUBRESOURCE);
- } else {
- Telemetry::Accumulate(Telemetry::HTTP_AUTH_DIALOG_STATS,
- HTTP_AUTH_DIALOG_CROSS_ORIGIN_SUBRESOURCE);
- }
- }
-
switch (sAuthAllowPref) {
case SUBRESOURCE_AUTH_DIALOG_DISALLOW_ALL:
// Do not open the http-authentication credentials dialog for
diff --git a/netwerk/protocol/http/nsHttpConnection.cpp b/netwerk/protocol/http/nsHttpConnection.cpp
index c4564cd8b..505d849c0 100644
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -19,7 +19,6 @@
#include "ASpdySession.h"
#include "mozilla/ChaosMode.h"
-#include "mozilla/Telemetry.h"
#include "nsHttpConnection.h"
#include "nsHttpHandler.h"
#include "nsHttpPipeline.h"
@@ -105,18 +104,12 @@ nsHttpConnection::~nsHttpConnection()
if (!mEverUsedSpdy) {
LOG(("nsHttpConnection %p performed %d HTTP/1.x transactions\n",
this, mHttp1xTransactionCount));
- Telemetry::Accumulate(Telemetry::HTTP_REQUEST_PER_CONN,
- mHttp1xTransactionCount);
}
if (mTotalBytesRead) {
uint32_t totalKBRead = static_cast<uint32_t>(mTotalBytesRead >> 10);
LOG(("nsHttpConnection %p read %dkb on connection spdy=%d\n",
this, totalKBRead, mEverUsedSpdy));
- Telemetry::Accumulate(mEverUsedSpdy ?
- Telemetry::SPDY_KBREAD_PER_CONN :
- Telemetry::HTTP_KBREAD_PER_CONN,
- totalKBRead);
}
if (mForceSendTimer) {
mForceSendTimer->Cancel();
@@ -482,21 +475,6 @@ nsHttpConnection::EnsureNPNComplete(nsresult &aOut0RTTWriteHandshakeValue,
int16_t tlsVersion;
ssl->GetSSLVersionUsed(&tlsVersion);
- // Send the 0RTT telemetry only for tls1.3
- if (tlsVersion > nsISSLSocketControl::TLS_VERSION_1_2) {
- Telemetry::Accumulate(Telemetry::TLS_EARLY_DATA_NEGOTIATED,
- (!mEarlyDataNegotiated) ? TLS_EARLY_DATA_NOT_AVAILABLE
- : ((mWaitingFor0RTTResponse) ? TLS_EARLY_DATA_AVAILABLE_AND_USED
- : TLS_EARLY_DATA_AVAILABLE_BUT_NOT_USED));
- if (mWaitingFor0RTTResponse) {
- Telemetry::Accumulate(Telemetry::TLS_EARLY_DATA_ACCEPTED,
- earlyDataAccepted);
- }
- if (earlyDataAccepted) {
- Telemetry::Accumulate(Telemetry::TLS_EARLY_DATA_BYTES_WRITTEN,
- mContentBytesWritten0RTT);
- }
- }
mWaitingFor0RTTResponse = false;
if (!earlyDataAccepted) {
@@ -518,8 +496,6 @@ nsHttpConnection::EnsureNPNComplete(nsresult &aOut0RTTWriteHandshakeValue,
StartSpdy(mSpdySession->SpdyVersion());
}
}
-
- Telemetry::Accumulate(Telemetry::SPDY_NPN_CONNECT, UsingSpdy());
}
npnComplete:
@@ -559,16 +535,16 @@ npnComplete:
return true;
}
-void
+nsresult
nsHttpConnection::OnTunnelNudged(TLSFilterTransaction *trans)
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
LOG(("nsHttpConnection::OnTunnelNudged %p\n", this));
if (trans != mTLSFilter) {
- return;
+ return NS_OK;
}
LOG(("nsHttpConnection::OnTunnelNudged %p Calling OnSocketWritable\n", this));
- OnSocketWritable();
+ return OnSocketWritable();
}
// called on the socket thread
@@ -663,7 +639,9 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, uint32_t caps, int32_t pri
}
if (mTLSFilter) {
- mTLSFilter->SetProxiedTransaction(trans);
+ RefPtr<NullHttpTransaction> baseTrans(do_QueryReferent(mWeakTrans));
+ rv = mTLSFilter->SetProxiedTransaction(trans, baseTrans);
+ NS_ENSURE_SUCCESS(rv, rv);
mTransaction = mTLSFilter;
}
@@ -2003,7 +1981,7 @@ nsHttpConnection::OnSocketReadable()
// negotiation are known (which is determined from the write path).
// If the server speaks SPDY it is likely the readable data here is
// a spdy settings frame and without NPN it would be misinterpreted
- // as HTTP/*
+ // as HTTP
LOG(("nsHttpConnection::OnSocketReadable %p return due to inactive "
"tunnel setup but incomplete NPN state\n", this));
@@ -2043,12 +2021,14 @@ nsHttpConnection::OnSocketReadable()
}
void
-nsHttpConnection::SetupSecondaryTLS()
+nsHttpConnection::SetupSecondaryTLS(nsAHttpTransaction *aSpdyConnectTransaction)
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
MOZ_ASSERT(!mTLSFilter);
- LOG(("nsHttpConnection %p SetupSecondaryTLS %s %d\n",
- this, mConnInfo->Origin(), mConnInfo->OriginPort()));
+ LOG(("nsHttpConnection %p SetupSecondaryTLS %s %d "
+ "aSpdyConnectTransaction=%p\n",
+ this, mConnInfo->Origin(), mConnInfo->OriginPort(),
+ aSpdyConnectTransaction));
nsHttpConnectionInfo *ci = nullptr;
if (mTransaction) {
@@ -2065,6 +2045,7 @@ nsHttpConnection::SetupSecondaryTLS()
if (mTransaction) {
mTransaction = mTLSFilter;
}
+ mWeakTrans = do_GetWeakReference(aSpdyConnectTransaction);
}
void
diff --git a/netwerk/protocol/http/nsHttpConnection.h b/netwerk/protocol/http/nsHttpConnection.h
index 08eea1de2..ce7523eb5 100644
--- a/netwerk/protocol/http/nsHttpConnection.h
+++ b/netwerk/protocol/http/nsHttpConnection.h
@@ -202,7 +202,7 @@ public:
static nsresult MakeConnectString(nsAHttpTransaction *trans,
nsHttpRequestHead *request,
nsACString &result);
- void SetupSecondaryTLS();
+ void SetupSecondaryTLS(nsAHttpTransaction *aSpdyConnectTransaction = nullptr);
void SetInSpdyTunnel(bool arg);
// Check active connections for traffic (or not). SPDY connections send a
@@ -281,6 +281,7 @@ private:
// transaction is open, otherwise it is null.
RefPtr<nsAHttpTransaction> mTransaction;
RefPtr<TLSFilterTransaction> mTLSFilter;
+ nsWeakPtr mWeakTrans; // SpdyConnectTransaction *
RefPtr<nsHttpHandler> mHttpHandler; // keep gHttpHandler alive
diff --git a/netwerk/protocol/http/nsHttpConnectionInfo.cpp b/netwerk/protocol/http/nsHttpConnectionInfo.cpp
index e965fd1cc..93a40843c 100644
--- a/netwerk/protocol/http/nsHttpConnectionInfo.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionInfo.cpp
@@ -15,32 +15,26 @@
#include "nsHttpConnectionInfo.h"
#include "mozilla/net/DNS.h"
-#include "prnetdb.h"
-#include "nsICryptoHash.h"
#include "nsComponentManagerUtils.h"
+#include "nsICryptoHash.h"
#include "nsIProtocolProxyService.h"
+#include "nsNetCID.h"
+#include "prnetdb.h"
static nsresult
SHA256(const char* aPlainText, nsAutoCString& aResult)
{
- static nsICryptoHash* hasher = nullptr;
nsresult rv;
- if (!hasher) {
- rv = CallCreateInstance("@mozilla.org/security/hash;1", &hasher);
- if (NS_FAILED(rv)) {
- LOG(("nsHttpDigestAuth: no crypto hash!\n"));
- return rv;
- }
+ nsCOMPtr<nsICryptoHash> hasher = do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID, &rv);
+ if (NS_FAILED(rv)) {
+ LOG(("nsHttpDigestAuth: no crypto hash!\n"));
+ return rv;
}
-
rv = hasher->Init(nsICryptoHash::SHA256);
NS_ENSURE_SUCCESS(rv, rv);
-
rv = hasher->Update((unsigned char*) aPlainText, strlen(aPlainText));
NS_ENSURE_SUCCESS(rv, rv);
-
- rv = hasher->Finish(false, aResult);
- return rv;
+ return hasher->Finish(false, aResult);
}
namespace mozilla {
diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
index 9271b49af..907f33436 100644
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -23,7 +23,6 @@
#include "mozilla/net/DNS.h"
#include "nsISocketTransport.h"
#include "nsISSLSocketControl.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/net/DashboardTypes.h"
#include "NullHttpTransaction.h"
#include "nsIDNSRecord.h"
@@ -36,8 +35,6 @@
#include "mozilla/Unused.h"
#include "nsIURI.h"
-#include "mozilla/Telemetry.h"
-
namespace mozilla {
namespace net {
@@ -847,7 +844,6 @@ nsHttpConnectionMgr::GetSpdyPreferredEnt(nsConnectionEntry *aOriginalEntry)
"with %s connections. rv=%x isJoined=%d",
preferred->mConnInfo->Origin(), aOriginalEntry->mConnInfo->Origin(),
rv, isJoined));
- Telemetry::Accumulate(Telemetry::SPDY_NPN_JOIN, false);
return nullptr;
}
@@ -857,7 +853,6 @@ nsHttpConnectionMgr::GetSpdyPreferredEnt(nsConnectionEntry *aOriginalEntry)
"so %s will be coalesced with %s",
preferred->mConnInfo->Origin(), aOriginalEntry->mConnInfo->Origin(),
aOriginalEntry->mConnInfo->Origin(), preferred->mConnInfo->Origin()));
- Telemetry::Accumulate(Telemetry::SPDY_NPN_JOIN, true);
return preferred;
}
@@ -1189,14 +1184,6 @@ nsHttpConnectionMgr::MakeNewConnection(nsConnectionEntry *ent,
transport->SetConnectionFlags(flags);
}
- Telemetry::AutoCounter<Telemetry::HTTPCONNMGR_USED_SPECULATIVE_CONN> usedSpeculativeConn;
- ++usedSpeculativeConn;
-
- if (ent->mHalfOpens[i]->IsFromPredictor()) {
- Telemetry::AutoCounter<Telemetry::PREDICTOR_TOTAL_PRECONNECTS_USED> totalPreconnectsUsed;
- ++totalPreconnectsUsed;
- }
-
// return OK because we have essentially opened a new connection
// by converting a speculative half-open to general use
return NS_OK;
@@ -1390,14 +1377,6 @@ nsHttpConnectionMgr::AddToShortestPipeline(nsConnectionEntry *ent,
ent->SetYellowConnection(bestConn);
if (!trans->GetPendingTime().IsNull()) {
- if (trans->UsesPipelining())
- AccumulateTimeDelta(
- Telemetry::TRANSACTION_WAIT_TIME_HTTP_PIPELINES,
- trans->GetPendingTime(), TimeStamp::Now());
- else
- AccumulateTimeDelta(
- Telemetry::TRANSACTION_WAIT_TIME_HTTP,
- trans->GetPendingTime(), TimeStamp::Now());
trans->SetPendingTime(false);
}
return true;
@@ -1680,8 +1659,6 @@ nsHttpConnectionMgr::DispatchTransaction(nsConnectionEntry *ent,
rv = conn->Activate(trans, caps, priority);
MOZ_ASSERT(NS_SUCCEEDED(rv), "SPDY Cannot Fail Dispatch");
if (NS_SUCCEEDED(rv) && !trans->GetPendingTime().IsNull()) {
- AccumulateTimeDelta(Telemetry::TRANSACTION_WAIT_TIME_SPDY,
- trans->GetPendingTime(), TimeStamp::Now());
trans->SetPendingTime(false);
}
return rv;
@@ -1698,12 +1675,6 @@ nsHttpConnectionMgr::DispatchTransaction(nsConnectionEntry *ent,
rv = DispatchAbstractTransaction(ent, trans, caps, conn, priority);
if (NS_SUCCEEDED(rv) && !trans->GetPendingTime().IsNull()) {
- if (trans->UsesPipelining())
- AccumulateTimeDelta(Telemetry::TRANSACTION_WAIT_TIME_HTTP_PIPELINES,
- trans->GetPendingTime(), TimeStamp::Now());
- else
- AccumulateTimeDelta(Telemetry::TRANSACTION_WAIT_TIME_HTTP,
- trans->GetPendingTime(), TimeStamp::Now());
trans->SetPendingTime(false);
}
return rv;
@@ -1832,21 +1803,6 @@ nsHttpConnectionMgr::BuildPipeline(nsConnectionEntry *ent,
return NS_OK;
}
-void
-nsHttpConnectionMgr::ReportProxyTelemetry(nsConnectionEntry *ent)
-{
- enum { PROXY_NONE = 1, PROXY_HTTP = 2, PROXY_SOCKS = 3, PROXY_HTTPS = 4 };
-
- if (!ent->mConnInfo->UsingProxy())
- Telemetry::Accumulate(Telemetry::HTTP_PROXY_TYPE, PROXY_NONE);
- else if (ent->mConnInfo->UsingHttpsProxy())
- Telemetry::Accumulate(Telemetry::HTTP_PROXY_TYPE, PROXY_HTTPS);
- else if (ent->mConnInfo->UsingHttpProxy())
- Telemetry::Accumulate(Telemetry::HTTP_PROXY_TYPE, PROXY_HTTP);
- else
- Telemetry::Accumulate(Telemetry::HTTP_PROXY_TYPE, PROXY_SOCKS);
-}
-
nsresult
nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans)
{
@@ -1890,8 +1846,6 @@ nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans)
ent = preferredEntry;
}
- ReportProxyTelemetry(ent);
-
// Check if the transaction already has a sticky reference to a connection.
// If so, then we can just use it directly by transferring its reference
// to the new connection variable instead of searching for a new one
@@ -1988,13 +1942,9 @@ nsHttpConnectionMgr::CreateTransport(nsConnectionEntry *ent,
if (speculative) {
sock->SetSpeculative(true);
sock->SetAllow1918(allow1918);
- Telemetry::AutoCounter<Telemetry::HTTPCONNMGR_TOTAL_SPECULATIVE_CONN> totalSpeculativeConn;
- ++totalSpeculativeConn;
if (isFromPredictor) {
sock->SetIsFromPredictor(true);
- Telemetry::AutoCounter<Telemetry::PREDICTOR_TOTAL_PRECONNECTS_CREATED> totalPreconnectsCreated;
- ++totalPreconnectsCreated;
}
}
@@ -3107,8 +3057,6 @@ nsHalfOpenSocket::SetupStreams(nsISocketTransport **transport,
rv = socketTransport->SetSecurityCallbacks(this);
NS_ENSURE_SUCCESS(rv, rv);
- Telemetry::Accumulate(Telemetry::HTTP_CONNECTION_ENTRY_CACHE_HIT_1,
- mEnt->mUsedForConnection);
mEnt->mUsedForConnection = true;
nsCOMPtr<nsIOutputStream> sout;
@@ -3908,16 +3856,6 @@ nsConnectionEntry::RemoveHalfOpen(nsHalfOpenSocket *halfOpen)
// will result in it not being present in the halfopen table. That's expected.
if (mHalfOpens.RemoveElement(halfOpen)) {
- if (halfOpen->IsSpeculative()) {
- Telemetry::AutoCounter<Telemetry::HTTPCONNMGR_UNUSED_SPECULATIVE_CONN> unusedSpeculativeConn;
- ++unusedSpeculativeConn;
-
- if (halfOpen->IsFromPredictor()) {
- Telemetry::AutoCounter<Telemetry::PREDICTOR_TOTAL_PRECONNECTS_UNUSED> totalPreconnectsUnused;
- ++totalPreconnectsUnused;
- }
- }
-
MOZ_ASSERT(gHttpHandler->ConnMgr()->mNumHalfOpenConns);
if (gHttpHandler->ConnMgr()->mNumHalfOpenConns) { // just in case
gHttpHandler->ConnMgr()->mNumHalfOpenConns--;
diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.h b/netwerk/protocol/http/nsHttpConnectionMgr.h
index 7ca2a2b28..a2c88c402 100644
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
@@ -529,7 +529,6 @@ private:
nsresult ProcessNewTransaction(nsHttpTransaction *);
nsresult EnsureSocketThreadTarget();
void ClosePersistentConnections(nsConnectionEntry *ent);
- void ReportProxyTelemetry(nsConnectionEntry *ent);
nsresult CreateTransport(nsConnectionEntry *, nsAHttpTransaction *,
uint32_t, bool, bool, bool);
void AddActiveConn(nsHttpConnection *, nsConnectionEntry *);
diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp
index f9bcc391d..0f4c94202 100644
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -58,7 +58,6 @@
#include "mozilla/net/NeckoChild.h"
#include "mozilla/net/NeckoParent.h"
#include "mozilla/ipc/URIUtils.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/Unused.h"
#include "mozilla/BasePrincipal.h"
@@ -91,7 +90,6 @@
#define BROWSER_PREF_PREFIX "browser.cache."
#define DONOTTRACK_HEADER_ENABLED "privacy.donottrackheader.enabled"
#define H2MANDATORY_SUITE "security.ssl3.ecdhe_rsa_aes_128_gcm_sha256"
-#define TELEMETRY_ENABLED "toolkit.telemetry.enabled"
#define ALLOW_EXPERIMENTS "network.allow-experiments"
#define SAFE_HINT_HEADER_VALUE "safeHint.enabled"
#define SECURITY_PREFIX "security."
@@ -203,13 +201,13 @@ nsHttpHandler::nsHttpHandler()
, mCompatFirefoxEnabled(false)
, mCompatFirefoxVersion("52.9")
, mUserAgentIsDirty(true)
+ , mAcceptLanguagesIsDirty(true)
, mPromptTempRedirect(true)
, mEnablePersistentHttpsCaching(false)
, mDoNotTrackEnabled(false)
, mSafeHintEnabled(false)
, mParentalControlEnabled(false)
, mHandlerActive(false)
- , mTelemetryEnabled(false)
, mAllowExperiments(true)
, mDebugObservations(false)
, mEnableSpdy(false)
@@ -305,7 +303,6 @@ nsHttpHandler::Init()
prefBranch->AddObserver(INTL_ACCEPT_LANGUAGES, this, true);
prefBranch->AddObserver(BROWSER_PREF("disk_cache_ssl"), this, true);
prefBranch->AddObserver(DONOTTRACK_HEADER_ENABLED, this, true);
- prefBranch->AddObserver(TELEMETRY_ENABLED, this, true);
prefBranch->AddObserver(H2MANDATORY_SUITE, this, true);
prefBranch->AddObserver(HTTP_PREF("tcp_keepalive.short_lived_connections"), this, true);
prefBranch->AddObserver(HTTP_PREF("tcp_keepalive.long_lived_connections"), this, true);
@@ -419,6 +416,7 @@ nsHttpHandler::Init()
obsService->AddObserver(this, "browser:purge-session-history", true);
obsService->AddObserver(this, NS_NETWORK_LINK_TOPIC, true);
obsService->AddObserver(this, "application-background", true);
+ obsService->AddObserver(this, "string-bundles-have-flushed", true);
}
MakeNewRequestTokenBucket();
@@ -470,7 +468,9 @@ nsHttpHandler::InitConnectionMgr()
}
nsresult
-nsHttpHandler::AddStandardRequestHeaders(nsHttpRequestHead *request, bool isSecure)
+nsHttpHandler::AddStandardRequestHeaders(nsHttpRequestHead *request,
+ bool isSecure,
+ nsContentPolicyType aContentPolicyType)
{
nsresult rv;
@@ -483,14 +483,32 @@ nsHttpHandler::AddStandardRequestHeaders(nsHttpRequestHead *request, bool isSecu
// Add the "Accept" header. Note, this is set as an override because the
// service worker expects to see it. The other "default" headers are
// hidden from service worker interception.
- rv = request->SetHeader(nsHttp::Accept, mAccept,
+ nsAutoCString accept;
+ if (aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT ||
+ aContentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT) {
+ accept.Assign(mAcceptNavigation);
+ } else if (aContentPolicyType == nsIContentPolicy::TYPE_IMAGE ||
+ aContentPolicyType == nsIContentPolicy::TYPE_IMAGESET) {
+ accept.Assign(mAcceptImage);
+ } else if (aContentPolicyType == nsIContentPolicy::TYPE_STYLESHEET) {
+ accept.Assign(mAcceptStyle);
+ } else {
+ accept.Assign(mAcceptDefault);
+ }
+
+ rv = request->SetHeader(nsHttp::Accept, accept,
false, nsHttpHeaderArray::eVarietyRequestOverride);
if (NS_FAILED(rv)) return rv;
// Add the "Accept-Language" header. This header is also exposed to the
// service worker.
+ if (mAcceptLanguagesIsDirty) {
+ rv = SetAcceptLanguages();
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+ }
+
+ // Add the "Accept-Language" header
if (!mAcceptLanguages.IsEmpty()) {
- // Add the "Accept-Language" header
rv = request->SetHeader(nsHttp::Accept_Language, mAcceptLanguages,
false,
nsHttpHeaderArray::eVarietyRequestOverride);
@@ -1265,12 +1283,36 @@ nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref)
mQoSBits = (uint8_t) clamped(val, 0, 0xff);
}
+ if (PREF_CHANGED(HTTP_PREF("accept.navigation"))) {
+ nsXPIDLCString accept;
+ rv = prefs->GetCharPref(HTTP_PREF("accept.navigation"),
+ getter_Copies(accept));
+ if (NS_SUCCEEDED(rv))
+ SetAccept(accept, ACCEPT_NAVIGATION);
+ }
+
+ if (PREF_CHANGED(HTTP_PREF("accept.image"))) {
+ nsXPIDLCString accept;
+ rv = prefs->GetCharPref(HTTP_PREF("accept.image"),
+ getter_Copies(accept));
+ if (NS_SUCCEEDED(rv))
+ SetAccept(accept, ACCEPT_IMAGE);
+ }
+
+ if (PREF_CHANGED(HTTP_PREF("accept.style"))) {
+ nsXPIDLCString accept;
+ rv = prefs->GetCharPref(HTTP_PREF("accept.style"),
+ getter_Copies(accept));
+ if (NS_SUCCEEDED(rv))
+ SetAccept(accept, ACCEPT_STYLE);
+ }
+
if (PREF_CHANGED(HTTP_PREF("accept.default"))) {
nsXPIDLCString accept;
rv = prefs->GetCharPref(HTTP_PREF("accept.default"),
getter_Copies(accept));
if (NS_SUCCEEDED(rv))
- SetAccept(accept);
+ SetAccept(accept, ACCEPT_DEFAULT);
}
if (PREF_CHANGED(HTTP_PREF("accept-encoding"))) {
@@ -1511,16 +1553,10 @@ nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref)
//
if (PREF_CHANGED(INTL_ACCEPT_LANGUAGES)) {
- nsCOMPtr<nsIPrefLocalizedString> pls;
- prefs->GetComplexValue(INTL_ACCEPT_LANGUAGES,
- NS_GET_IID(nsIPrefLocalizedString),
- getter_AddRefs(pls));
- if (pls) {
- nsXPIDLString uval;
- pls->ToString(getter_Copies(uval));
- if (uval)
- SetAcceptLanguages(NS_ConvertUTF16toUTF8(uval).get());
- }
+ // We don't want to set the new accept languages here since
+ // this pref is a complex type and it may be racy with flushing
+ // string resources.
+ mAcceptLanguagesIsDirty = true;
}
//
@@ -1547,19 +1583,6 @@ nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref)
// includes telemetry and allow-experiments because of the abtest profile
bool requestTokenBucketUpdated = false;
- //
- // Telemetry
- //
-
- if (PREF_CHANGED(TELEMETRY_ENABLED)) {
- cVar = false;
- requestTokenBucketUpdated = true;
- rv = prefs->GetBoolPref(TELEMETRY_ENABLED, &cVar);
- if (NS_SUCCEEDED(rv)) {
- mTelemetryEnabled = cVar;
- }
- }
-
// "security.ssl3.ecdhe_rsa_aes_128_gcm_sha256" is the required h2 interop
// suite.
@@ -1897,19 +1920,37 @@ PrepareAcceptLanguages(const char *i_AcceptLanguages, nsACString &o_AcceptLangua
}
nsresult
-nsHttpHandler::SetAcceptLanguages(const char *aAcceptLanguages)
+nsHttpHandler::SetAcceptLanguages()
{
+ mAcceptLanguagesIsDirty = false;
+
+ const nsAdoptingCString& acceptLanguages =
+ Preferences::GetLocalizedCString(INTL_ACCEPT_LANGUAGES);
+
nsAutoCString buf;
- nsresult rv = PrepareAcceptLanguages(aAcceptLanguages, buf);
- if (NS_SUCCEEDED(rv))
+ nsresult rv = PrepareAcceptLanguages(acceptLanguages.get(), buf);
+ if (NS_SUCCEEDED(rv)) {
mAcceptLanguages.Assign(buf);
+ }
return rv;
}
nsresult
-nsHttpHandler::SetAccept(const char *aAccept)
+nsHttpHandler::SetAccept(const char *aAccept, AcceptType aType)
{
- mAccept = aAccept;
+ switch (aType) {
+ case ACCEPT_NAVIGATION:
+ mAcceptNavigation = aAccept;
+ break;
+ case ACCEPT_IMAGE:
+ mAcceptImage = aAccept;
+ break;
+ case ACCEPT_STYLE:
+ mAcceptStyle = aAccept;
+ break;
+ case ACCEPT_DEFAULT:
+ mAcceptDefault = aAccept;
+ }
return NS_OK;
}
@@ -2067,7 +2108,11 @@ nsHttpHandler::NewProxiedChannel2(nsIURI *uri,
rv = NewChannelId(&channelId);
NS_ENSURE_SUCCESS(rv, rv);
- rv = httpChannel->Init(uri, caps, proxyInfo, proxyResolveFlags, proxyURI, channelId);
+ nsContentPolicyType contentPolicyType =
+ aLoadInfo ? aLoadInfo->GetExternalContentPolicyType()
+ : nsIContentPolicy::TYPE_OTHER;
+
+ rv = httpChannel->Init(uri, caps, proxyInfo, proxyResolveFlags, proxyURI, channelId, contentPolicyType);
if (NS_FAILED(rv))
return rv;
@@ -2175,11 +2220,6 @@ nsHttpHandler::Observe(nsISupports *subject,
// depend on this value.
mSessionStartTime = NowInSeconds();
- if (!mDoNotTrackEnabled) {
- Telemetry::Accumulate(Telemetry::DNT_USAGE, 2);
- } else {
- Telemetry::Accumulate(Telemetry::DNT_USAGE, 1);
- }
} else if (!strcmp(topic, "profile-change-net-restore")) {
// initialize connection manager
InitConnectionMgr();
@@ -2233,6 +2273,8 @@ nsHttpHandler::Observe(nsISupports *subject,
if (mConnMgr) {
mConnMgr->DoShiftReloadConnectionCleanup(nullptr);
}
+ } else if (!strcmp(topic, "string-bundles-have-flushed")) {
+ mAcceptLanguagesIsDirty = true;
}
return NS_OK;
diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h
index 0904af893..67b9ebe0e 100644
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -15,6 +15,7 @@
#include "nsCOMPtr.h"
#include "nsWeakReference.h"
+#include "nsIContentPolicy.h"
#include "nsIHttpProtocolHandler.h"
#include "nsIObserver.h"
#include "nsISpeculativeConnect.h"
@@ -50,6 +51,14 @@ enum FrameCheckLevel {
FRAMECHECK_STRICT
};
+// Fetch spec different http Accept types
+enum AcceptType {
+ ACCEPT_NAVIGATION,
+ ACCEPT_IMAGE,
+ ACCEPT_STYLE,
+ ACCEPT_DEFAULT,
+};
+
//-----------------------------------------------------------------------------
// nsHttpHandler - protocol handler for HTTP and HTTPS
//-----------------------------------------------------------------------------
@@ -70,7 +79,7 @@ public:
nsHttpHandler();
nsresult Init();
- nsresult AddStandardRequestHeaders(nsHttpRequestHead *, bool isSecure);
+ nsresult AddStandardRequestHeaders(nsHttpRequestHead *, bool isSecure, nsContentPolicyType aContentPolicyType);
nsresult AddConnectionHeader(nsHttpRequestHead *,
uint32_t capabilities);
bool IsAcceptableEncoding(const char *encoding, bool isSecure);
@@ -105,8 +114,10 @@ public:
bool EnforceAssocReq() { return mEnforceAssocReq; }
bool IsPersistentHttpsCachingEnabled() { return mEnablePersistentHttpsCaching; }
- bool IsTelemetryEnabled() { return mTelemetryEnabled; }
- bool AllowExperiments() { return mTelemetryEnabled && mAllowExperiments; }
+
+ // Since telemetry has been removed, experiments should also not be allowed.
+ // Making this function return `false` for now, it will be cleaned up later.
+ bool AllowExperiments() { return false; }
bool IsSpdyEnabled() { return mEnableSpdy; }
bool IsHttp2Enabled() { return mHttp2Enabled; }
@@ -383,8 +394,8 @@ private:
void InitUserAgentComponents();
void PrefsChanged(nsIPrefBranch *prefs, const char *pref);
- nsresult SetAccept(const char *);
- nsresult SetAcceptLanguages(const char *);
+ nsresult SetAccept(const char *, AcceptType aType);
+ nsresult SetAcceptLanguages();
nsresult SetAcceptEncodings(const char *, bool mIsSecure);
nsresult InitConnectionMgr();
@@ -392,8 +403,8 @@ private:
void NotifyObservers(nsIHttpChannel *chan, const char *event);
static void TimerCallback(nsITimer * aTimer, void * aClosure);
+
private:
-
// cached services
nsMainThreadPtrHandle<nsIIOService> mIOService;
nsMainThreadPtrHandle<nsIStreamConverterService> mStreamConvSvc;
@@ -458,7 +469,10 @@ private:
bool mPipeliningOverSSL;
bool mEnforceAssocReq;
- nsCString mAccept;
+ nsCString mAcceptNavigation;
+ nsCString mAcceptImage;
+ nsCString mAcceptStyle;
+ nsCString mAcceptDefault;
nsCString mAcceptLanguages;
nsCString mHttpAcceptEncodings;
nsCString mHttpsAcceptEncodings;
@@ -491,6 +505,7 @@ private:
nsCString mUserAgent;
nsXPIDLCString mUserAgentOverride;
bool mUserAgentIsDirty; // true if mUserAgent should be rebuilt
+ bool mAcceptLanguagesIsDirty;
bool mPromptTempRedirect;
@@ -508,9 +523,6 @@ private:
// true in between init and shutdown states
Atomic<bool, Relaxed> mHandlerActive;
- // Whether telemetry is reported or not
- uint32_t mTelemetryEnabled : 1;
-
// The value of network.allow-experiments
uint32_t mAllowExperiments : 1;
diff --git a/netwerk/protocol/http/nsHttpHeaderArray.cpp b/netwerk/protocol/http/nsHttpHeaderArray.cpp
index 670300dea..1030bc91e 100644
--- a/netwerk/protocol/http/nsHttpHeaderArray.cpp
+++ b/netwerk/protocol/http/nsHttpHeaderArray.cpp
@@ -18,12 +18,37 @@ namespace net {
//-----------------------------------------------------------------------------
// nsHttpHeaderArray <public>
//-----------------------------------------------------------------------------
+
+nsresult
+nsHttpHeaderArray::SetHeader(const nsACString &headerName,
+ const nsACString &value,
+ bool merge,
+ nsHttpHeaderArray::HeaderVariety variety)
+{
+ nsHttpAtom header = nsHttp::ResolveAtom(PromiseFlatCString(headerName).get());
+ if (!header) {
+ NS_WARNING("failed to resolve atom");
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ return SetHeader(header, headerName, value, merge, variety);
+}
+
nsresult
nsHttpHeaderArray::SetHeader(nsHttpAtom header,
const nsACString &value,
bool merge,
nsHttpHeaderArray::HeaderVariety variety)
{
+ return SetHeader(header, EmptyCString(), value, merge, variety);
+}
+
+nsresult
+nsHttpHeaderArray::SetHeader(nsHttpAtom header,
+ const nsACString &headerName,
+ const nsACString &value,
+ bool merge,
+ nsHttpHeaderArray::HeaderVariety variety)
+{
MOZ_ASSERT((variety == eVarietyResponse) ||
(variety == eVarietyRequestDefault) ||
(variety == eVarietyRequestOverride),
@@ -51,7 +76,7 @@ nsHttpHeaderArray::SetHeader(nsHttpAtom header,
MOZ_ASSERT(!entry || variety != eVarietyRequestDefault,
"Cannot set default entry which overrides existing entry!");
if (!entry) {
- return SetHeader_internal(header, value, variety);
+ return SetHeader_internal(header, headerName, value, variety);
} else if (merge && !IsSingletonHeader(header)) {
return MergeHeader(header, entry, value, variety);
} else {
@@ -59,7 +84,7 @@ nsHttpHeaderArray::SetHeader(nsHttpAtom header,
if (entry->variety == eVarietyResponseNetOriginalAndResponse) {
MOZ_ASSERT(variety == eVarietyResponse);
entry->variety = eVarietyResponseNetOriginal;
- return SetHeader_internal(header, value, variety);
+ return SetHeader_internal(header, headerName, value, variety);
} else {
entry->value = value;
entry->variety = variety;
@@ -71,6 +96,7 @@ nsHttpHeaderArray::SetHeader(nsHttpAtom header,
nsresult
nsHttpHeaderArray::SetHeader_internal(nsHttpAtom header,
+ const nsACString &headerName,
const nsACString &value,
nsHttpHeaderArray::HeaderVariety variety)
{
@@ -79,14 +105,26 @@ nsHttpHeaderArray::SetHeader_internal(nsHttpAtom header,
return NS_ERROR_OUT_OF_MEMORY;
}
entry->header = header;
+ // Only save original form of a header if it is different than the header
+ // atom string.
+ if (!headerName.Equals(header.get())) {
+ entry->headerNameOriginal = headerName;
+ }
entry->value = value;
entry->variety = variety;
return NS_OK;
}
nsresult
-nsHttpHeaderArray::SetEmptyHeader(nsHttpAtom header, HeaderVariety variety)
+nsHttpHeaderArray::SetEmptyHeader(const nsACString &headerName,
+ HeaderVariety variety)
{
+ nsHttpAtom header = nsHttp::ResolveAtom(PromiseFlatCString(headerName).get());
+ if (!header) {
+ NS_WARNING("failed to resolve atom");
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
MOZ_ASSERT((variety == eVarietyResponse) ||
(variety == eVarietyRequestDefault) ||
(variety == eVarietyRequestOverride),
@@ -104,11 +142,12 @@ nsHttpHeaderArray::SetEmptyHeader(nsHttpAtom header, HeaderVariety variety)
entry->variety = eVarietyResponseNetOriginal;
}
- return SetHeader_internal(header, EmptyCString(), variety);
+ return SetHeader_internal(header, headerName, EmptyCString(), variety);
}
nsresult
nsHttpHeaderArray::SetHeaderFromNet(nsHttpAtom header,
+ const nsACString &headerNameOriginal,
const nsACString &value,
bool response)
{
@@ -125,7 +164,7 @@ nsHttpHeaderArray::SetHeaderFromNet(nsHttpAtom header,
LOG(("Ignoring Empty Header: %s\n", header.get()));
if (response) {
// Set header as original but not as response header.
- return SetHeader_internal(header, value,
+ return SetHeader_internal(header, headerNameOriginal, value,
eVarietyResponseNetOriginal);
}
return NS_OK; // ignore empty headers by default
@@ -135,7 +174,7 @@ nsHttpHeaderArray::SetHeaderFromNet(nsHttpAtom header,
if (response) {
variety = eVarietyResponseNetOriginalAndResponse;
}
- return SetHeader_internal(header, value, variety);
+ return SetHeader_internal(header, headerNameOriginal, value, variety);
} else if (!IsSingletonHeader(header)) {
HeaderVariety variety = eVarietyRequestOverride;
@@ -147,7 +186,7 @@ nsHttpHeaderArray::SetHeaderFromNet(nsHttpAtom header,
return rv;
}
if (response) {
- rv = SetHeader_internal(header, value,
+ rv = SetHeader_internal(header, headerNameOriginal, value,
eVarietyResponseNetOriginal);
}
return rv;
@@ -164,7 +203,7 @@ nsHttpHeaderArray::SetHeaderFromNet(nsHttpAtom header,
}
if (response) {
- return SetHeader_internal(header, value,
+ return SetHeader_internal(header, headerNameOriginal, value,
eVarietyResponseNetOriginal);
}
}
@@ -174,6 +213,7 @@ nsHttpHeaderArray::SetHeaderFromNet(nsHttpAtom header,
nsresult
nsHttpHeaderArray::SetResponseHeaderFromCache(nsHttpAtom header,
+ const nsACString &headerNameOriginal,
const nsACString &value,
nsHttpHeaderArray::HeaderVariety variety)
{
@@ -183,7 +223,7 @@ nsHttpHeaderArray::SetResponseHeaderFromCache(nsHttpAtom header,
"eVarietyResponseNetOriginal");
if (variety == eVarietyResponseNetOriginal) {
- return SetHeader_internal(header, value,
+ return SetHeader_internal(header, headerNameOriginal, value,
eVarietyResponseNetOriginal);
} else {
nsTArray<nsEntry>::index_type index = 0;
@@ -203,7 +243,8 @@ nsHttpHeaderArray::SetResponseHeaderFromCache(nsHttpAtom header,
}
} while (index != mHeaders.NoIndex);
// If we are here, we have not found an entry so add a new one.
- return SetHeader_internal(header, value, eVarietyResponse);
+ return SetHeader_internal(header, headerNameOriginal, value,
+ eVarietyResponse);
}
}
@@ -260,8 +301,16 @@ nsHttpHeaderArray::GetOriginalHeader(nsHttpAtom aHeader,
if (entry.variety == eVarietyResponse) {
continue;
}
+
+ nsAutoCString hdr;
+ if (entry.headerNameOriginal.IsEmpty()) {
+ hdr = nsDependentCString(entry.header);
+ } else {
+ hdr = entry.headerNameOriginal;
+ }
+
rv = NS_OK;
- if (NS_FAILED(aVisitor->VisitHeader(nsDependentCString(entry.header),
+ if (NS_FAILED(aVisitor->VisitHeader(hdr,
entry.value))) {
break;
}
@@ -298,8 +347,14 @@ nsHttpHeaderArray::VisitHeaders(nsIHttpHeaderVisitor *visitor, nsHttpHeaderArray
} else if (filter == eFilterResponseOriginal && entry.variety == eVarietyResponse) {
continue;
}
- rv = visitor->VisitHeader(
- nsDependentCString(entry.header), entry.value);
+
+ nsAutoCString hdr;
+ if (entry.headerNameOriginal.IsEmpty()) {
+ hdr = nsDependentCString(entry.header);
+ } else {
+ hdr = entry.headerNameOriginal;
+ }
+ rv = visitor->VisitHeader(hdr, entry.value);
if NS_FAILED(rv) {
return rv;
}
@@ -310,6 +365,7 @@ nsHttpHeaderArray::VisitHeaders(nsIHttpHeaderVisitor *visitor, nsHttpHeaderArray
/*static*/ nsresult
nsHttpHeaderArray::ParseHeaderLine(const nsACString& line,
nsHttpAtom *hdr,
+ nsACString *headerName,
nsACString *val)
{
//
@@ -360,6 +416,7 @@ nsHttpHeaderArray::ParseHeaderLine(const nsACString& line,
// assign return values
if (hdr) *hdr = atom;
if (val) val->Assign(p, p2 - p + 1);
+ if (headerName) headerName->Assign(sub);
return NS_OK;
}
@@ -397,7 +454,11 @@ nsHttpHeaderArray::Flatten(nsACString &buf, bool pruneProxyHeaders,
continue;
}
- buf.Append(entry.header);
+ if (entry.headerNameOriginal.IsEmpty()) {
+ buf.Append(entry.header);
+ } else {
+ buf.Append(entry.headerNameOriginal);
+ }
buf.AppendLiteral(": ");
buf.Append(entry.value);
buf.AppendLiteral("\r\n");
@@ -415,7 +476,11 @@ nsHttpHeaderArray::FlattenOriginalHeader(nsACString &buf)
continue;
}
- buf.Append(entry.header);
+ if (entry.headerNameOriginal.IsEmpty()) {
+ buf.Append(entry.header);
+ } else {
+ buf.Append(entry.headerNameOriginal);
+ }
buf.AppendLiteral(": ");
buf.Append(entry.value);
buf.AppendLiteral("\r\n");
@@ -423,11 +488,13 @@ nsHttpHeaderArray::FlattenOriginalHeader(nsACString &buf)
}
const char *
-nsHttpHeaderArray::PeekHeaderAt(uint32_t index, nsHttpAtom &header) const
+nsHttpHeaderArray::PeekHeaderAt(uint32_t index, nsHttpAtom &header,
+ nsACString &headerNameOriginal) const
{
const nsEntry &entry = mHeaders[index];
header = entry.header;
+ headerNameOriginal = entry.headerNameOriginal;
return entry.value.get();
}
diff --git a/netwerk/protocol/http/nsHttpHeaderArray.h b/netwerk/protocol/http/nsHttpHeaderArray.h
index 91b91f04a..3ffdfa814 100644
--- a/netwerk/protocol/http/nsHttpHeaderArray.h
+++ b/netwerk/protocol/http/nsHttpHeaderArray.h
@@ -49,19 +49,30 @@ public:
};
// Used by internal setters: to set header from network use SetHeaderFromNet
+ nsresult SetHeader(const nsACString &headerName,
+ const nsACString &value,
+ bool merge, HeaderVariety variety);
nsresult SetHeader(nsHttpAtom header, const nsACString &value,
bool merge, HeaderVariety variety);
+ nsresult SetHeader(nsHttpAtom header,
+ const nsACString &headerName,
+ const nsACString &value,
+ bool merge, HeaderVariety variety);
// Used by internal setters to set an empty header
- nsresult SetEmptyHeader(nsHttpAtom header, HeaderVariety variety);
+ nsresult SetEmptyHeader(const nsACString &headerName, HeaderVariety variety);
// Merges supported headers. For other duplicate values, determines if error
// needs to be thrown or 1st value kept.
// For the response header we keep the original headers as well.
- nsresult SetHeaderFromNet(nsHttpAtom header, const nsACString &value,
+ nsresult SetHeaderFromNet(nsHttpAtom header,
+ const nsACString &headerNameOriginal,
+ const nsACString &value,
bool response);
- nsresult SetResponseHeaderFromCache(nsHttpAtom header, const nsACString &value,
+ nsresult SetResponseHeaderFromCache(nsHttpAtom header,
+ const nsACString &headerNameOriginal,
+ const nsACString &value,
HeaderVariety variety);
nsresult GetHeader(nsHttpAtom header, nsACString &value) const;
@@ -97,15 +108,17 @@ public:
// parse a header line, return the header atom and a pointer to the
// header value (the substring of the header line -- do not free).
static nsresult ParseHeaderLine(const nsACString& line,
- nsHttpAtom *header=nullptr,
- nsACString* value=nullptr);
+ nsHttpAtom *header = nullptr,
+ nsACString *headerNameOriginal = nullptr,
+ nsACString *value = nullptr);
void Flatten(nsACString &, bool pruneProxyHeaders, bool pruneTransients);
void FlattenOriginalHeader(nsACString &);
uint32_t Count() const { return mHeaders.Length(); }
- const char *PeekHeaderAt(uint32_t i, nsHttpAtom &header) const;
+ const char *PeekHeaderAt(uint32_t i, nsHttpAtom &header,
+ nsACString &headerNameOriginal) const;
void Clear();
@@ -113,6 +126,7 @@ public:
struct nsEntry
{
nsHttpAtom header;
+ nsCString headerNameOriginal;
nsCString value;
HeaderVariety variety = eVarietyUnknown;
@@ -140,7 +154,9 @@ private:
int32_t LookupEntry(nsHttpAtom header, nsEntry **);
nsresult MergeHeader(nsHttpAtom header, nsEntry *entry,
const nsACString &value, HeaderVariety variety);
- nsresult SetHeader_internal(nsHttpAtom header, const nsACString &value,
+ nsresult SetHeader_internal(nsHttpAtom header,
+ const nsACString &headerName,
+ const nsACString &value,
HeaderVariety variety);
// Header cannot be merged: only one value possible
@@ -257,7 +273,11 @@ nsHttpHeaderArray::MergeHeader(nsHttpAtom header,
if (entry->variety == eVarietyResponseNetOriginalAndResponse) {
MOZ_ASSERT(variety == eVarietyResponse);
entry->variety = eVarietyResponseNetOriginal;
- nsresult rv = SetHeader_internal(header, newValue, eVarietyResponse);
+ // Copy entry->headerNameOriginal because in SetHeader_internal we are going
+ // to a new one and a realocation can happen.
+ nsCString headerNameOriginal = entry->headerNameOriginal;
+ nsresult rv = SetHeader_internal(header, headerNameOriginal,
+ newValue, eVarietyResponse);
if (NS_FAILED(rv)) {
return rv;
}
diff --git a/netwerk/protocol/http/nsHttpPipeline.cpp b/netwerk/protocol/http/nsHttpPipeline.cpp
index 293de8e39..4f5777244 100644
--- a/netwerk/protocol/http/nsHttpPipeline.cpp
+++ b/netwerk/protocol/http/nsHttpPipeline.cpp
@@ -291,6 +291,11 @@ nsHttpPipeline::PushBack(const char *data, uint32_t length)
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
MOZ_ASSERT(mPushBackLen == 0, "push back buffer already has data!");
+ // Some bad behaving proxies may yank the connection out from under us.
+ // Check if we still have a connection to work with.
+ if (!mConnection)
+ return NS_ERROR_FAILURE;
+
// If we have no chance for a pipeline (e.g. due to an Upgrade)
// then push this data down to original connection
if (!mConnection->IsPersistent())
diff --git a/netwerk/protocol/http/nsHttpRequestHead.cpp b/netwerk/protocol/http/nsHttpRequestHead.cpp
index 094a79457..b366a8d54 100644
--- a/netwerk/protocol/http/nsHttpRequestHead.cpp
+++ b/netwerk/protocol/http/nsHttpRequestHead.cpp
@@ -131,6 +131,20 @@ nsHttpRequestHead::Origin(nsACString &aOrigin)
}
nsresult
+nsHttpRequestHead::SetHeader(const nsACString &h, const nsACString &v,
+ bool m /*= false*/)
+{
+ ReentrantMonitorAutoEnter mon(mReentrantMonitor);
+
+ if (mInVisitHeaders) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return mHeaders.SetHeader(h, v, m,
+ nsHttpHeaderArray::eVarietyRequestOverride);
+}
+
+nsresult
nsHttpRequestHead::SetHeader(nsHttpAtom h, const nsACString &v,
bool m /*= false*/)
{
@@ -158,7 +172,7 @@ nsHttpRequestHead::SetHeader(nsHttpAtom h, const nsACString &v, bool m,
}
nsresult
-nsHttpRequestHead::SetEmptyHeader(nsHttpAtom h)
+nsHttpRequestHead::SetEmptyHeader(const nsACString &h)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
@@ -253,6 +267,7 @@ nsHttpRequestHead::ParseHeaderSet(const char *buffer)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
nsHttpAtom hdr;
+ nsAutoCString headerNameOriginal;
nsAutoCString val;
while (buffer) {
const char *eof = strchr(buffer, '\r');
@@ -262,9 +277,13 @@ nsHttpRequestHead::ParseHeaderSet(const char *buffer)
if (NS_SUCCEEDED(nsHttpHeaderArray::ParseHeaderLine(
nsDependentCSubstring(buffer, eof - buffer),
&hdr,
+ &headerNameOriginal,
&val))) {
- mHeaders.SetHeaderFromNet(hdr, val, false);
+ mHeaders.SetHeaderFromNet(hdr,
+ headerNameOriginal,
+ val,
+ false);
}
buffer = eof + 1;
if (*buffer == '\n') {
diff --git a/netwerk/protocol/http/nsHttpRequestHead.h b/netwerk/protocol/http/nsHttpRequestHead.h
index 415968083..b7020d33a 100644
--- a/netwerk/protocol/http/nsHttpRequestHead.h
+++ b/netwerk/protocol/http/nsHttpRequestHead.h
@@ -57,10 +57,12 @@ public:
int32_t port);
void Origin(nsACString &aOrigin);
+ nsresult SetHeader(const nsACString &h, const nsACString &v,
+ bool m=false);
nsresult SetHeader(nsHttpAtom h, const nsACString &v, bool m=false);
nsresult SetHeader(nsHttpAtom h, const nsACString &v, bool m,
nsHttpHeaderArray::HeaderVariety variety);
- nsresult SetEmptyHeader(nsHttpAtom h);
+ nsresult SetEmptyHeader(const nsACString &h);
nsresult GetHeader(nsHttpAtom h, nsACString &v);
nsresult ClearHeader(nsHttpAtom h);
diff --git a/netwerk/protocol/http/nsHttpResponseHead.cpp b/netwerk/protocol/http/nsHttpResponseHead.cpp
index 6d384c488..fa6430b82 100644
--- a/netwerk/protocol/http/nsHttpResponseHead.cpp
+++ b/netwerk/protocol/http/nsHttpResponseHead.cpp
@@ -137,6 +137,26 @@ nsHttpResponseHead::Immutable()
}
nsresult
+nsHttpResponseHead::SetHeader(const nsACString &hdr,
+ const nsACString &val,
+ bool merge)
+{
+ ReentrantMonitorAutoEnter monitor(mReentrantMonitor);
+
+ if (mInVisitHeaders) {
+ return NS_ERROR_FAILURE;
+ }
+
+ nsHttpAtom atom = nsHttp::ResolveAtom(PromiseFlatCString(hdr).get());
+ if (!atom) {
+ NS_WARNING("failed to resolve atom");
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ return SetHeader_locked(atom, hdr, val, merge);
+}
+
+nsresult
nsHttpResponseHead::SetHeader(nsHttpAtom hdr,
const nsACString &val,
bool merge)
@@ -147,24 +167,25 @@ nsHttpResponseHead::SetHeader(nsHttpAtom hdr,
return NS_ERROR_FAILURE;
}
- return SetHeader_locked(hdr, val, merge);
+ return SetHeader_locked(hdr, EmptyCString(), val, merge);
}
nsresult
-nsHttpResponseHead::SetHeader_locked(nsHttpAtom hdr,
+nsHttpResponseHead::SetHeader_locked(nsHttpAtom atom,
+ const nsACString &hdr,
const nsACString &val,
bool merge)
{
- nsresult rv = mHeaders.SetHeader(hdr, val, merge,
+ nsresult rv = mHeaders.SetHeader(atom, hdr, val, merge,
nsHttpHeaderArray::eVarietyResponse);
if (NS_FAILED(rv)) return rv;
// respond to changes in these headers. we need to reparse the entire
// header since the change may have merged in additional values.
- if (hdr == nsHttp::Cache_Control)
- ParseCacheControl(mHeaders.PeekHeader(hdr));
- else if (hdr == nsHttp::Pragma)
- ParsePragma(mHeaders.PeekHeader(hdr));
+ if (atom == nsHttp::Cache_Control)
+ ParseCacheControl(mHeaders.PeekHeader(atom));
+ else if (atom == nsHttp::Pragma)
+ ParsePragma(mHeaders.PeekHeader(atom));
return NS_OK;
}
@@ -316,6 +337,7 @@ nsHttpResponseHead::ParseCachedOriginalHeaders(char *block)
char *p = block;
nsHttpAtom hdr = {0};
+ nsAutoCString headerNameOriginal;
nsAutoCString val;
nsresult rv;
@@ -331,12 +353,13 @@ nsHttpResponseHead::ParseCachedOriginalHeaders(char *block)
*p = 0;
if (NS_FAILED(nsHttpHeaderArray::ParseHeaderLine(
- nsDependentCString(block, p - block), &hdr, &val))) {
+ nsDependentCString(block, p - block), &hdr, &headerNameOriginal, &val))) {
return NS_OK;
}
rv = mHeaders.SetResponseHeaderFromCache(hdr,
+ headerNameOriginal,
val,
nsHttpHeaderArray::eVarietyResponseNetOriginal);
@@ -567,18 +590,21 @@ nsresult
nsHttpResponseHead::ParseHeaderLine_locked(const nsACString &line, bool originalFromNetHeaders)
{
nsHttpAtom hdr = {0};
+ nsAutoCString headerNameOriginal;
nsAutoCString val;
- if (NS_FAILED(nsHttpHeaderArray::ParseHeaderLine(line, &hdr, &val))) {
+ if (NS_FAILED(nsHttpHeaderArray::ParseHeaderLine(line, &hdr, &headerNameOriginal, &val))) {
return NS_OK;
}
nsresult rv;
if (originalFromNetHeaders) {
rv = mHeaders.SetHeaderFromNet(hdr,
+ headerNameOriginal,
val,
true);
} else {
rv = mHeaders.SetResponseHeaderFromCache(hdr,
+ headerNameOriginal,
val,
nsHttpHeaderArray::eVarietyResponse);
}
@@ -856,7 +882,8 @@ nsHttpResponseHead::UpdateHeaders(nsHttpResponseHead *aOther)
uint32_t i, count = aOther->mHeaders.Count();
for (i=0; i<count; ++i) {
nsHttpAtom header;
- const char *val = aOther->mHeaders.PeekHeaderAt(i, header);
+ nsAutoCString headerNameOriginal;
+ const char *val = aOther->mHeaders.PeekHeaderAt(i, header, headerNameOriginal);
if (!val) {
continue;
@@ -890,7 +917,8 @@ nsHttpResponseHead::UpdateHeaders(nsHttpResponseHead *aOther)
LOG(("new response header [%s: %s]\n", header.get(), val));
// overwrite the current header value with the new value...
- SetHeader_locked(header, nsDependentCString(val));
+ SetHeader_locked(header, headerNameOriginal,
+ nsDependentCString(val));
}
}
diff --git a/netwerk/protocol/http/nsHttpResponseHead.h b/netwerk/protocol/http/nsHttpResponseHead.h
index 0a912f4b4..8b51386ea 100644
--- a/netwerk/protocol/http/nsHttpResponseHead.h
+++ b/netwerk/protocol/http/nsHttpResponseHead.h
@@ -65,6 +65,8 @@ public:
*/
int64_t TotalEntitySize();
+ nsresult SetHeader(const nsACString &h, const nsACString &v,
+ bool m=false);
nsresult SetHeader(nsHttpAtom h, const nsACString &v, bool m=false);
nsresult GetHeader(nsHttpAtom h, nsACString &v);
void ClearHeader(nsHttpAtom h);
@@ -137,8 +139,8 @@ public:
bool HasContentType();
bool HasContentCharset();
private:
- nsresult SetHeader_locked(nsHttpAtom h, const nsACString &v,
- bool m=false);
+ nsresult SetHeader_locked(nsHttpAtom atom, const nsACString &h,
+ const nsACString &v, bool m=false);
void AssignDefaultStatusText();
void ParseVersion(const char *);
void ParseCacheControl(const char *);
diff --git a/netwerk/protocol/http/nsHttpTransaction.cpp b/netwerk/protocol/http/nsHttpTransaction.cpp
index 8d837d172..76e0a4ad9 100644
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -1164,7 +1164,9 @@ nsHttpTransaction::Close(nsresult reason)
}
// closing this pipe triggers the channel's OnStopRequest method.
- mPipeOut->CloseWithStatus(reason);
+ if (mPipeOut) {
+ mPipeOut->CloseWithStatus(reason);
+ }
#ifdef WIN32 // bug 1153929
MOZ_DIAGNOSTIC_ASSERT(mPipeOut);