Backed out changeset 5d44356db349 (bug 1763527) for causing build bustages. CLOSED TREE

This commit is contained in:
Butkovits Atila 2022-04-29 13:41:02 +03:00
Родитель 8502847db2
Коммит 4aff968e83
7 изменённых файлов: 463 добавлений и 0 удалений

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

@ -2866,18 +2866,24 @@ bool HttpBaseChannel::EnsureOpaqueResponseIsAllowed() {
return true;
}
InitiateORBTelemetry();
switch (GetOpaqueResponseBlockedReason(*mResponseHead)) {
case OpaqueResponseBlockedReason::ALLOWED_SAFE_LISTED:
ReportORBTelemetry("Allowed_SafeListed"_ns);
return true;
case OpaqueResponseBlockedReason::BLOCKED_BLOCKLISTED_NEVER_SNIFFED:
// XXXtt: Report To Console.
ReportORBTelemetry("Blocked_BlockListedNeverSniffed"_ns);
return false;
case OpaqueResponseBlockedReason::BLOCKED_206_AND_BLOCKLISTED:
// XXXtt: Report To Console.
ReportORBTelemetry("Blocked_206AndBlockListed"_ns);
return false;
case OpaqueResponseBlockedReason::
BLOCKED_NOSNIFF_AND_EITHER_BLOCKLISTED_OR_TEXTPLAIN:
// XXXtt: Report To Console.
ReportORBTelemetry("Blocked_NosniffAndEitherBlockListedOrTextPlain"_ns);
return false;
default:
break;
@ -2891,6 +2897,7 @@ bool HttpBaseChannel::EnsureOpaqueResponseIsAllowed() {
bool isMediaInitialRequest;
mLoadInfo->GetIsMediaInitialRequest(&isMediaInitialRequest);
if (!isMediaInitialRequest) {
ReportORBTelemetry("Allowed_SubsequentMediaRequest"_ns);
return true;
}
}
@ -2937,16 +2944,19 @@ HttpBaseChannel::EnsureOpaqueResponseIsAllowedAfterSniff() {
mLoadInfo->GetIsMediaRequest(&isMediaRequest);
if (isMediaRequest) {
// XXXtt: Report To Console.
ReportORBTelemetry("Blocked_UnexpectedMediaRequest"_ns);
return false;
}
nsAutoCString contentType;
nsresult rv = GetContentType(contentType);
if (NS_FAILED(rv)) {
ReportORBTelemetry("Blocked_UnexpectedContentType"_ns);
return Err(rv);
}
if (!mResponseHead) {
ReportORBTelemetry("Allowed_UnexpectedResponseHead"_ns);
return true;
}
@ -2954,16 +2964,19 @@ HttpBaseChannel::EnsureOpaqueResponseIsAllowedAfterSniff() {
if (mResponseHead->GetContentTypeOptionsHeader(contentTypeOptionsHeader) &&
contentTypeOptionsHeader.EqualsIgnoreCase("nosniff")) {
// XXXtt: Report To Console.
ReportORBTelemetry("Blocked_NoSniffHeaderAfterSniff"_ns);
return false;
}
if (mResponseHead->Status() < 200 || mResponseHead->Status() > 299) {
// XXXtt: Report To Console.
ReportORBTelemetry("Blocked_ResponseNotOk"_ns);
return false;
}
if (contentType.EqualsLiteral(UNKNOWN_CONTENT_TYPE) ||
contentType.EqualsLiteral(APPLICATION_OCTET_STREAM)) {
ReportORBTelemetry("Allowed_FailtoGetMIMEType"_ns);
return true;
}
@ -2971,6 +2984,7 @@ HttpBaseChannel::EnsureOpaqueResponseIsAllowedAfterSniff() {
StringBeginsWith(contentType, "video/"_ns) ||
StringBeginsWith(contentType, "audio/"_ns)) {
// XXXtt: Report To Console.
ReportORBTelemetry("Blocked_ContentTypeBeginsWithImageOrVideoOrAudio"_ns);
return false;
}
@ -2981,9 +2995,13 @@ HttpBaseChannel::EnsureOpaqueResponseIsAllowedAfterSniff() {
rv = GetContentLength(&contentLength);
if (NS_FAILED(rv)) {
// XXXtt: Report To Console.
ReportORBTelemetry("Blocked_GetContentLengthFailed"_ns);
return false;
}
ReportORBTelemetry(contentLength);
ReportORBTelemetry("Allowed_NotImplementOrPass"_ns);
return true;
}
@ -5231,6 +5249,27 @@ void HttpBaseChannel::EnsureTopBrowsingContextId() {
}
}
void HttpBaseChannel::InitiateORBTelemetry() {
MOZ_ASSERT(!mOpaqueResponseBlockingInfo);
MOZ_RELEASE_ASSERT(mLoadInfo);
mOpaqueResponseBlockingInfo = MakeRefPtr<OpaqueResponseBlockingInfo>(
mLoadInfo->GetExternalContentPolicyType());
}
void HttpBaseChannel::ReportORBTelemetry(const nsCString& aKey) {
MOZ_ASSERT(mOpaqueResponseBlockingInfo);
mOpaqueResponseBlockingInfo->Report(aKey);
mOpaqueResponseBlockingInfo = nullptr;
}
void HttpBaseChannel::ReportORBTelemetry(int64_t aContentLength) {
MOZ_ASSERT(mOpaqueResponseBlockingInfo);
mOpaqueResponseBlockingInfo->ReportContentLength(aContentLength);
}
void HttpBaseChannel::SetCorsPreflightParameters(
const nsTArray<nsCString>& aUnsafeHeaders,
bool aShouldStripRequestBodyHeader) {

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

@ -707,6 +707,8 @@ class HttpBaseChannel : public nsHashPropertyBag,
UniquePtr<nsTArray<nsCString>> mRedirectedCachekeys;
nsCOMPtr<nsIRequestContext> mRequestContext;
RefPtr<OpaqueResponseBlockingInfo> mOpaqueResponseBlockingInfo;
NetAddr mSelfAddr;
NetAddr mPeerAddr;
@ -969,6 +971,11 @@ class HttpBaseChannel : public nsHashPropertyBag,
void RemoveAsNonTailRequest();
void EnsureTopBrowsingContextId();
void InitiateORBTelemetry();
void ReportORBTelemetry(const nsCString& aKey);
void ReportORBTelemetry(int64_t aContentLength);
};
NS_DEFINE_STATIC_IID_ACCESSOR(HttpBaseChannel, HTTP_BASE_CHANNEL_IID)

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

@ -6,6 +6,8 @@
#include "mozilla/net/OpaqueResponseUtils.h"
#include "mozilla/Telemetry.h"
#include "mozilla/TelemetryHistogramEnums.h"
#include "nsContentUtils.h"
#include "nsHttpResponseHead.h"
#include "nsMimeTypes.h"
@ -168,5 +170,87 @@ bool IsFirstPartialResponse(nsHttpResponseHead& aResponseHead) {
return responseFirstBytePos == 0;
}
OpaqueResponseBlockingInfo::OpaqueResponseBlockingInfo(
ExtContentPolicyType aContentPolicyType)
: mStartTime(TimeStamp::Now()) {
switch (aContentPolicyType) {
case ExtContentPolicy::TYPE_OTHER:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::Other;
break;
case ExtContentPolicy::TYPE_SCRIPT:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::Script;
break;
case ExtContentPolicy::TYPE_IMAGE:
case ExtContentPolicy::TYPE_IMAGESET:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::Image;
break;
case ExtContentPolicy::TYPE_STYLESHEET:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::Style;
break;
case ExtContentPolicy::TYPE_OBJECT:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::Object;
break;
case ExtContentPolicy::TYPE_DOCUMENT:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::Document;
break;
case ExtContentPolicy::TYPE_SUBDOCUMENT:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::Subdocument;
break;
case ExtContentPolicy::TYPE_PING:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::Ping;
break;
case ExtContentPolicy::TYPE_XMLHTTPREQUEST:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::XHR;
break;
case ExtContentPolicy::TYPE_OBJECT_SUBREQUEST:
mDestination =
Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::ObjectSubrequest;
break;
case ExtContentPolicy::TYPE_DTD:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::DTD;
break;
case ExtContentPolicy::TYPE_FONT:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::Font;
break;
case ExtContentPolicy::TYPE_MEDIA:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::Media;
break;
case ExtContentPolicy::TYPE_WEBSOCKET:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::Websocket;
break;
case ExtContentPolicy::TYPE_CSP_REPORT:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::CspReport;
break;
case ExtContentPolicy::TYPE_XSLT:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::XSLT;
break;
case ExtContentPolicy::TYPE_BEACON:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::Beacon;
break;
case ExtContentPolicy::TYPE_FETCH:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::Fetch;
break;
case ExtContentPolicy::TYPE_WEB_MANIFEST:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::WebManifest;
break;
default:
mDestination = Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING::Unexpected;
break;
}
}
void OpaqueResponseBlockingInfo::Report(const nsCString& aKey) {
Telemetry::AccumulateCategoricalKeyed(aKey, mDestination);
AccumulateTimeDelta(Telemetry::OPAQUE_RESPONSE_BLOCKING_TIME_MS, mStartTime);
}
void OpaqueResponseBlockingInfo::ReportContentLength(int64_t aContentLength) {
// XXX: We might want to filter negative cases (when the content length is
// unknown).
Telemetry::ScalarAdd(
Telemetry::ScalarID::OPAQUE_RESPONSE_BLOCKING_PARSING_SIZE_KB,
aContentLength > 0 ? aContentLength >> 10 : aContentLength);
}
} // namespace net
} // namespace mozilla

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

@ -9,9 +9,14 @@
#define mozilla_net_OpaqueResponseUtils_h
#include "nsIContentPolicy.h"
#include "mozilla/TimeStamp.h"
namespace mozilla {
namespace Telemetry {
enum class LABELS_OPAQUE_RESPONSE_BLOCKING : uint32_t;
}
namespace net {
class nsHttpResponseHead;
@ -33,6 +38,24 @@ Result<std::tuple<int64_t, int64_t, int64_t>, nsresult>
ParseContentRangeHeaderString(const nsAutoCString& aRangeStr);
bool IsFirstPartialResponse(nsHttpResponseHead& aResponseHead);
class OpaqueResponseBlockingInfo final {
const TimeStamp mStartTime;
Telemetry::LABELS_OPAQUE_RESPONSE_BLOCKING mDestination;
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(OpaqueResponseBlockingInfo);
explicit OpaqueResponseBlockingInfo(ExtContentPolicyType aContentPolicyType);
void Report(const nsCString& aKey);
void ReportContentLength(int64_t aContentLength);
private:
~OpaqueResponseBlockingInfo() = default;
};
} // namespace net
} // namespace mozilla

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

@ -9291,23 +9291,27 @@ void nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck(
if (!isInitialRequest) {
mBlockOpaqueResponseAfterSniff = true;
ReportORBTelemetry("Blocked_NotAnInitialRequest"_ns);
return;
}
if (mResponseHead->Status() != 200 && mResponseHead->Status() != 206) {
mBlockOpaqueResponseAfterSniff = true;
ReportORBTelemetry("Blocked_Not200Or206"_ns);
return;
}
if (mResponseHead->Status() == 206 &&
!IsFirstPartialResponse(*mResponseHead)) {
mBlockOpaqueResponseAfterSniff = true;
ReportORBTelemetry("Blocked_InvaliidPartialResponse"_ns);
return;
}
}
}
mCheckIsOpaqueResponseAllowedAfterSniff = false;
ReportORBTelemetry("Allowed_SniffAsImageOrAudioOrVideo"_ns);
}
}

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

@ -0,0 +1,261 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const DIRPATH = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content/",
""
);
const ORIGIN1 = "https://example.com";
const URL = `${ORIGIN1}/${DIRPATH}dummy.html`;
// Cross origin urls.
const ORIGIN2 = "https://example.org";
const SAFE_LISTED_URL = `${ORIGIN2}/${DIRPATH}res.css`;
const BLOCKED_LISTED_NEVER_SNIFFED_URL = `${ORIGIN2}/${DIRPATH}res.csv`;
const BLOCKED_LISTED_206_URL = `${ORIGIN2}/${DIRPATH}res_206.html`;
const BLOCKED_LISTED_NOSNIFF_URL = `${ORIGIN2}/${DIRPATH}res_nosniff.html`;
const IMAGE_URL = `${ORIGIN2}/${DIRPATH}res_img.png`;
const NOSNIFF_URL = `${ORIGIN2}/${DIRPATH}res_nosniff2.html`;
const NOT_OK_URL = `${ORIGIN2}/${DIRPATH}res_not_ok.html`;
const UNKNOWN_URL = `${ORIGIN2}/${DIRPATH}res.unknown`;
const IMAGE_UNKNOWN_URL = `${ORIGIN2}/${DIRPATH}res_img_unknown.png`;
const MEDIA_URL = `${ORIGIN2}/${DIRPATH}res.mp3`;
const MEDIA_206_URL = `${ORIGIN2}/${DIRPATH}res_206.mp3`;
const MEDIA_INVALID_PARTIAL_URL = `${ORIGIN2}/${DIRPATH}res_invalid_partial.mp3`;
const MEDIA_NOT_200OR206_URL = `${ORIGIN2}/${DIRPATH}res_not_200or206.mp3`;
const IMAGE_UNKNOWN_DECOEDER_URL = `${ORIGIN2}/${DIRPATH}res_img_for_unknown_decoder`;
const SUBDOCUMENT_URL = `${ORIGIN2}/${DIRPATH}/res_sub_document.html`;
const OBJECT_URL = `${ORIGIN2}/${DIRPATH}/res_object.html`;
add_task(async function() {
await SpecialPowers.pushPrefEnv({
set: [["browser.opaqueResponseBlocking", true]],
});
let histogram = Services.telemetry.getKeyedHistogramById(
"OPAQUE_RESPONSE_BLOCKING"
);
const testcases = [
{
url: SAFE_LISTED_URL,
key: "Allowed_SafeListed",
shouldRecorded: true,
},
{
url: BLOCKED_LISTED_NEVER_SNIFFED_URL,
key: "Blocked_BlockListedNeverSniffed",
shouldRecorded: true,
},
{
url: BLOCKED_LISTED_206_URL,
key: "Blocked_206AndBlockListed",
shouldRecorded: true,
},
{
url: BLOCKED_LISTED_NOSNIFF_URL,
key: "Blocked_NosniffAndEitherBlockListedOrTextPlain",
shouldRecorded: true,
},
{
url: IMAGE_URL,
key: "Allowed_SniffAsImageOrAudioOrVideo",
shouldRecorded: true,
},
{
url: NOSNIFF_URL,
key: "Blocked_NoSniffHeaderAfterSniff",
shouldRecorded: true,
},
{
url: NOT_OK_URL,
key: "Blocked_ResponseNotOk",
shouldRecorded: true,
},
{
url: UNKNOWN_URL,
key: "Allowed_FailtoGetMIMEType",
shouldRecorded: true,
},
{
url: IMAGE_UNKNOWN_URL,
key: "Blocked_ContentTypeBeginsWithImageOrVideoOrAudio",
shouldRecorded: true,
},
{
url: MEDIA_URL,
key: "Allowed_SniffAsImageOrAudioOrVideo",
shouldRecorded: true,
loadType: "media",
},
{
url: MEDIA_206_URL,
key: "Allowed_SniffAsImageOrAudioOrVideo",
shouldRecorded: true,
loadType: "media",
},
{
url: MEDIA_INVALID_PARTIAL_URL,
key: "Blocked_InvaliidPartialResponse",
shouldRecorded: true,
loadType: "media",
},
{
url: MEDIA_NOT_200OR206_URL,
key: "Blocked_Not200Or206",
shouldRecorded: true,
loadType: "media",
},
{
url: IMAGE_UNKNOWN_DECOEDER_URL,
key: "Allowed_SniffAsImageOrAudioOrVideo",
shouldRecorded: true,
},
{
url: SUBDOCUMENT_URL,
key: "Allowed_NotImplementOrPass",
shouldRecorded: false,
loadType: "iframe",
},
{
url: IMAGE_URL,
key: "Allowed_SniffAsImageOrAudioOrVideo",
shouldRecorded: false,
loadType: "object",
},
{
url: OBJECT_URL,
key: "Allowed_SniffAsImageOrAudioOrVideo",
shouldRecorded: false,
loadType: "object",
},
{
url: IMAGE_URL,
key: "Allowed_SniffAsImageOrAudioOrVideo",
shouldRecorded: false,
loadType: "embed",
},
];
for (let testcase of testcases) {
histogram.clear();
await BrowserTestUtils.withNewTab(URL, async function(browser) {
BrowserTestUtils.loadURI(browser, URL);
await BrowserTestUtils.browserLoaded(browser);
info(`Fetching cross-origin url: ${testcase.url}.`);
await SpecialPowers.spawn(
browser,
[testcase.url, testcase.loadType, testcase.iframe],
async (url, loadType, iframe) => {
async function ensureDecodeFinished() {
// Calling drawWindow (via snapshotWindowWithOptions) sync decodes
// images by default, as long as this asks for the same image
// surface with the same options it should force the decode that
// was kicked off by being in the document to finish.
SpecialPowers.snapshotWindowWithOptions(
content.window,
undefined /* use the default rect */,
undefined /* use the default bgcolor */,
// Use flags to make this snapshot as close as possible to
// drawing to the screen.
{
DRAWWINDOW_DRAW_VIEW: true,
DRAWWINDOW_USE_WIDGET_LAYERS: true,
DRAWWINDOW_DRAW_CARET: true,
}
);
// And then wait two frames to make sure the results of that
// decode are flushed to the screen.
await new Promise(r =>
content.requestAnimationFrame(() =>
content.requestAnimationFrame(r)
)
);
}
try {
if (loadType == "media") {
const audio = content.document.createElement("audio");
audio.src = url;
content.document.body.appendChild(audio);
audio.load();
await new Promise(res => {
audio.onloadedmetadata = () => {
audio.src = "";
audio.onloadedmetadata = undefined;
audio.load();
res();
};
});
return;
}
if (loadType == "iframe") {
const subframe = content.document.createElement("iframe");
subframe.src = url;
const onloadPromise = new Promise(res => {
subframe.onload = res;
});
content.document.body.appendChild(subframe);
await onloadPromise;
content.document.body.removeChild(subframe);
return;
}
if (loadType == "object") {
const object = content.document.createElement("object");
object.data = url;
const onloadPromise = new Promise(res => {
object.onload = res;
});
content.document.body.appendChild(object);
await onloadPromise;
await ensureDecodeFinished();
content.document.body.removeChild(object);
return;
}
if (loadType == "embed") {
const embed = content.document.createElement("embed");
embed.src = url;
const onloadPromise = new Promise(res => {
embed.onload = res;
});
content.document.body.appendChild(embed);
await onloadPromise;
await ensureDecodeFinished();
content.document.body.removeChild(embed);
return;
}
await content.window.fetch(url, { mode: "no-cors" });
} catch (e) {
/* Ignore result */
}
}
);
});
info(`Validating if the telemetry probe has been reported.`);
let snapshot = histogram.snapshot();
let keys = testcase.keys;
if (!keys) {
keys = [testcase.key];
}
for (let key of keys) {
if (testcase.shouldRecorded) {
ok(snapshot.hasOwnProperty(key), `Should have recorded key ${key}`);
} else {
ok(
!snapshot.hasOwnProperty(key),
`Should not have recorded key ${key}`
);
}
}
}
});

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

@ -16884,6 +16884,51 @@
"alert_emails": ["necko@mozilla.com", "mwoodrow@mozilla.com"],
"description": "Time spent waiting on the main-thread to be available to run AsyncOpen, for image preload requests"
},
"OPAQUE_RESPONSE_BLOCKING_TIME_MS" : {
"record_in_processes": ["main"],
"products": ["firefox"],
"expires_in_version": "102",
"kind": "exponential",
"high": 60000,
"n_buckets": 20,
"keyed": false,
"description": "The amount of time to process ORB.",
"alert_emails": ["annevk@annevk.nl", "necko@mozilla.com"],
"bug_numbers": [1683131, 1720613, 1736689]
},
"OPAQUE_RESPONSE_BLOCKING": {
"record_in_processes": ["main"],
"products": ["firefox"],
"alert_emails": ["annevk@annevk.nl", "necko@mozilla.com"],
"bug_numbers": [1683131, 1720613, 1736689],
"expires_in_version": "102",
"kind": "categorical",
"releaseChannelCollection": "opt-out",
"description": "Find out how many opaque responses are allowed, or blocked by ORB per source.",
"keyed": true,
"labels": [
"Other",
"Script",
"Image",
"Style",
"Object",
"Document",
"Subdocument",
"Ping",
"XHR",
"ObjectSubrequest",
"DTD",
"Font",
"Media",
"Websocket",
"CspReport",
"WebManifest",
"XSLT",
"Beacon",
"Fetch",
"Unexpected"
]
},
"DOWNLOADS_USER_ACTION_ON_BLOCKED_DOWNLOAD": {
"record_in_processes": ["main"],
"products": ["firefox"],