Bug 1833216 - Add two more telemetry probes for ORB r=farre,necko-reviewers

Add `ORB_BLOCK_REASON` to learn more about the reasoning of orb blocking in the wild.

Add ORB_BLOCK_INITIATOR to learn about the initiators. We can add more probes in the future if we want to target a specific initiator.

Differential Revision: https://phabricator.services.mozilla.com/D178102
This commit is contained in:
Sean Feng 2023-05-23 20:42:35 +00:00
Родитель e87ecf485e
Коммит f5a6348688
6 изменённых файлов: 122 добавлений и 19 удалений

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

@ -3130,8 +3130,9 @@ bool HttpBaseChannel::ShouldBlockOpaqueResponse() const {
}
OpaqueResponse HttpBaseChannel::BlockOrFilterOpaqueResponse(
OpaqueResponseBlocker* aORB, const nsAString& aReason, const char* aFormat,
...) {
OpaqueResponseBlocker* aORB, const nsAString& aReason,
const OpaqueResponseBlockedTelemetryReason aTelemetryReason,
const char* aFormat, ...) {
const bool shouldFilter =
ShouldFilterOpaqueResponse(OpaqueResponseFilterFetch::BlockedByORB);
@ -3145,6 +3146,8 @@ OpaqueResponse HttpBaseChannel::BlockOrFilterOpaqueResponse(
}
if (shouldFilter) {
Telemetry::AccumulateCategorical(
Telemetry::LABELS_ORB_BLOCK_INITIATOR::FILTERED_FETCH);
// The existence of `mORB` depends on `BlockOrFilterOpaqueResponse` being
// called before or after sniffing has completed.
// Another requirement is that `OpaqueResponseFilter` must come after
@ -3160,7 +3163,7 @@ OpaqueResponse HttpBaseChannel::BlockOrFilterOpaqueResponse(
return OpaqueResponse::Allow;
}
LogORBError(aReason);
LogORBError(aReason, aTelemetryReason);
return OpaqueResponse::Block;
}
@ -3241,12 +3244,14 @@ HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff() {
case OpaqueResponseBlockedReason::BLOCKED_BLOCKLISTED_NEVER_SNIFFED:
return BlockOrFilterOpaqueResponse(
mORB, u"mimeType is an opaque-blocklisted-never-sniffed MIME type"_ns,
OpaqueResponseBlockedTelemetryReason::MIME_NEVER_SNIFFED,
"BLOCKED_BLOCKLISTED_NEVER_SNIFFED");
case OpaqueResponseBlockedReason::BLOCKED_206_AND_BLOCKLISTED:
// Step 3.3
return BlockOrFilterOpaqueResponse(
mORB,
u"response's status is 206 and mimeType is an opaque-blocklisted MIME type"_ns,
OpaqueResponseBlockedTelemetryReason::RESP_206_BLCLISTED,
"BLOCKED_206_AND_BLOCKEDLISTED");
case OpaqueResponseBlockedReason::
BLOCKED_NOSNIFF_AND_EITHER_BLOCKLISTED_OR_TEXTPLAIN:
@ -3254,6 +3259,7 @@ HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff() {
return BlockOrFilterOpaqueResponse(
mORB,
u"nosniff is true and mimeType is an opaque-blocklisted MIME type or its essence is 'text/plain'"_ns,
OpaqueResponseBlockedTelemetryReason::NOSNIFF_BLC_OR_TEXTP,
"BLOCKED_NOSNIFF_AND_EITHER_BLOCKLISTED_OR_TEXTPLAIN");
default:
break;
@ -3277,6 +3283,7 @@ HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff() {
!IsFirstPartialResponse(*mResponseHead)) {
return BlockOrFilterOpaqueResponse(
mORB, u"response status is 206 and not first partial response"_ns,
OpaqueResponseBlockedTelemetryReason::RESP_206_BLCLISTED,
"Is not a valid partial response given 0");
}
@ -3332,14 +3339,17 @@ OpaqueResponse HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff(
bool isMediaRequest;
mLoadInfo->GetIsMediaRequest(&isMediaRequest);
if (isMediaRequest) {
return BlockOrFilterOpaqueResponse(mORB, u"after sniff: media request"_ns,
"media request");
return BlockOrFilterOpaqueResponse(
mORB, u"after sniff: media request"_ns,
OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_MEDIA,
"media request");
}
// Step 11
if (aNoSniff) {
return BlockOrFilterOpaqueResponse(mORB, u"after sniff: nosniff is true"_ns,
"nosniff");
return BlockOrFilterOpaqueResponse(
mORB, u"after sniff: nosniff is true"_ns,
OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_NOSNIFF, "nosniff");
}
// Step 12
@ -3347,6 +3357,7 @@ OpaqueResponse HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff(
(mResponseHead->Status() < 200 || mResponseHead->Status() > 299)) {
return BlockOrFilterOpaqueResponse(
mORB, u"after sniff: status code is not in allowed range"_ns,
OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_STA_CODE,
"status code (%d) is not allowed", mResponseHead->Status());
}
@ -3363,6 +3374,7 @@ OpaqueResponse HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff(
return BlockOrFilterOpaqueResponse(
mORB,
u"after sniff: content-type declares image/video/audio, but sniffing fails"_ns,
OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_CT_FAIL,
"ContentType is image/video/audio");
}
@ -3373,9 +3385,11 @@ bool HttpBaseChannel::NeedOpaqueResponseAllowedCheckAfterSniff() const {
return mORB ? mORB->IsSniffing() : false;
}
void HttpBaseChannel::BlockOpaqueResponseAfterSniff(const nsAString& aReason) {
void HttpBaseChannel::BlockOpaqueResponseAfterSniff(
const nsAString& aReason,
const OpaqueResponseBlockedTelemetryReason aTelemetryReason) {
MOZ_DIAGNOSTIC_ASSERT(mORB);
LogORBError(aReason);
LogORBError(aReason, aTelemetryReason);
mORB->BlockResponse(this, NS_ERROR_FAILURE);
}
@ -6191,7 +6205,9 @@ HttpBaseChannel::GetIsProxyUsed(bool* aIsProxyUsed) {
return NS_OK;
}
void HttpBaseChannel::LogORBError(const nsAString& aReason) {
void HttpBaseChannel::LogORBError(
const nsAString& aReason,
const OpaqueResponseBlockedTelemetryReason aTelemetryReason) {
RefPtr<dom::Document> doc;
mLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
@ -6215,6 +6231,33 @@ void HttpBaseChannel::LogORBError(const nsAString& aReason) {
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "ORB"_ns, doc,
nsContentUtils::eNECKO_PROPERTIES,
"ResourceBlockedORB", params);
Telemetry::LABELS_ORB_BLOCK_REASON label{
static_cast<uint32_t>(aTelemetryReason)};
Telemetry::AccumulateCategorical(label);
switch (mLoadInfo->GetExternalContentPolicyType()) {
case ExtContentPolicy::TYPE_FETCH:
Telemetry::AccumulateCategorical(
Telemetry::LABELS_ORB_BLOCK_INITIATOR::BLOCKED_FETCH);
break;
case ExtContentPolicy::TYPE_IMAGE:
Telemetry::AccumulateCategorical(
Telemetry::LABELS_ORB_BLOCK_INITIATOR::IMAGE);
break;
case ExtContentPolicy::TYPE_SCRIPT:
Telemetry::AccumulateCategorical(
Telemetry::LABELS_ORB_BLOCK_INITIATOR::SCRIPT);
break;
case ExtContentPolicy::TYPE_MEDIA:
Telemetry::AccumulateCategorical(
Telemetry::LABELS_ORB_BLOCK_INITIATOR::MEDIA);
break;
default:
Telemetry::AccumulateCategorical(
Telemetry::LABELS_ORB_BLOCK_INITIATOR::OTHER);
break;
}
}
NS_IMETHODIMP HttpBaseChannel::SetEarlyHintLinkType(

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

@ -70,7 +70,6 @@ namespace net {
extern mozilla::LazyLogModule gHttpLog;
class OpaqueResponseBlocker;
class OpaqueResponseBlockingInfo;
class PreferredAlternativeDataTypeParams;
enum CacheDisposition : uint8_t {
@ -459,7 +458,8 @@ class HttpBaseChannel : public nsHashPropertyBag,
[[nodiscard]] nsresult OverrideSecurityInfo(
nsITransportSecurityInfo* aSecurityInfo);
void LogORBError(const nsAString& aReason);
void LogORBError(const nsAString& aReason,
const OpaqueResponseBlockedTelemetryReason aTelemetryReason);
public: /* Necko internal use only... */
int64_t GetAltDataLength() { return mAltDataLength; }
@ -655,9 +655,10 @@ class HttpBaseChannel : public nsHashPropertyBag,
bool ShouldFilterOpaqueResponse(OpaqueResponseFilterFetch aFilterType) const;
bool ShouldBlockOpaqueResponse() const;
OpaqueResponse BlockOrFilterOpaqueResponse(OpaqueResponseBlocker* aORB,
const nsAString& aReason,
const char* aFormat, ...);
OpaqueResponse BlockOrFilterOpaqueResponse(
OpaqueResponseBlocker* aORB, const nsAString& aReason,
const OpaqueResponseBlockedTelemetryReason aTelemetryReason,
const char* aFormat, ...);
OpaqueResponse PerformOpaqueResponseSafelistCheckBeforeSniff();
@ -665,7 +666,9 @@ class HttpBaseChannel : public nsHashPropertyBag,
const nsACString& aContentType, bool aNoSniff);
bool NeedOpaqueResponseAllowedCheckAfterSniff() const;
void BlockOpaqueResponseAfterSniff(const nsAString& aReason);
void BlockOpaqueResponseAfterSniff(
const nsAString& aReason,
const OpaqueResponseBlockedTelemetryReason aTelemetryReason);
void AllowOpaqueResponseAfterSniff();
void SetChannelBlockedByOpaqueResponse();
bool Http3Allowed() const;

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

@ -436,7 +436,9 @@ OpaqueResponseBlocker::EnsureOpaqueResponseIsAllowedAfterJavaScriptValidation(
}
return aChannel->BlockOrFilterOpaqueResponse(
this, u"Javascript validation failed"_ns, "Javascript validation failed");
this, u"Javascript validation failed"_ns,
OpaqueResponseBlockedTelemetryReason::JS_VALIDATION_FAILED,
"Javascript validation failed");
}
static void RecordTelemetry(const TimeStamp& aStartOfValidation,

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

@ -47,6 +47,20 @@ enum class OpaqueResponseBlockedReason : uint32_t {
BLOCKED_SHOULD_SNIFF
};
enum class OpaqueResponseBlockedTelemetryReason : uint32_t {
MIME_NEVER_SNIFFED,
RESP_206_BLCLISTED,
NOSNIFF_BLC_OR_TEXTP,
RESP_206_NO_FIRST,
AFTER_SNIFF_MEDIA,
AFTER_SNIFF_NOSNIFF,
AFTER_SNIFF_STA_CODE,
AFTER_SNIFF_CT_FAIL,
MEDIA_NOT_INITIAL,
MEDIA_INCORRECT_RESP,
JS_VALIDATION_FAILED
};
enum class OpaqueResponse { Block, Allow, SniffCompressed, Sniff };
OpaqueResponseBlockedReason GetOpaqueResponseBlockedReason(

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

@ -9854,14 +9854,16 @@ void nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck(
if (!isInitialRequest) {
// Step 8.1
BlockOpaqueResponseAfterSniff(
u"media request after sniffing, but not initial request"_ns);
u"media request after sniffing, but not initial request"_ns,
OpaqueResponseBlockedTelemetryReason::MEDIA_NOT_INITIAL);
return;
}
if (mResponseHead->Status() != 200 && mResponseHead->Status() != 206) {
// Step 8.2
BlockOpaqueResponseAfterSniff(
u"media request's response status is neither 200 nor 206"_ns);
u"media request's response status is neither 200 nor 206"_ns,
OpaqueResponseBlockedTelemetryReason::MEDIA_INCORRECT_RESP);
return;
}
}

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

@ -18144,6 +18144,45 @@
"bug_numbers": [1812051],
"description": "If any opaque response was blocked for a given top-level window context."
},
"ORB_BLOCK_REASON": {
"record_in_processes": ["main"],
"products": ["firefox"],
"alert_emails": ["sefeng@mozilla.com", "afarre@mozilla.com"],
"expires_in_version": "never",
"kind": "categorical",
"labels": [
"MIME_NEVER_SNIFFED",
"RESP_206_BLCLISTED",
"NOSNIFF_BLC_OR_TEXTP",
"RESP_206_NO_FIRST",
"AFTER_SNIFF_MEDIA",
"AFTER_SNIFF_NOSNIFF",
"AFTER_SNIFF_STA_CODE",
"AFTER_SNIFF_CT_FAIL",
"MEDIA_NOT_INITIAL",
"MEDIA_INCORRECT_RESP",
"JS_VALIDATION_FAILED"
],
"bug_numbers": [1833216],
"description": "The reason of why this request was blocked by ORB"
},
"ORB_BLOCK_INITIATOR": {
"record_in_processes": ["main"],
"products": ["firefox"],
"alert_emails": ["sefeng@mozilla.com", "afarre@mozilla.com"],
"expires_in_version": "never",
"kind": "categorical",
"labels": [
"FILTERED_FETCH",
"BLOCKED_FETCH",
"IMAGE",
"SCRIPT",
"MEDIA",
"OTHER"
],
"bug_numbers": [1833216],
"description": "The initiator of this ORB blocked request."
},
"EVENT_LONGTASK": {
"record_in_processes": ["main", "content"],
"products": ["firefox", "fennec"],