diff options
Diffstat (limited to '')
-rw-r--r-- | dom/security/metrics.yaml | 21 | ||||
-rw-r--r-- | dom/security/nsHTTPSOnlyUtils.cpp | 75 | ||||
-rw-r--r-- | dom/security/nsHTTPSOnlyUtils.h | 38 | ||||
-rw-r--r-- | dom/security/test/https-first/browser_httpsfirst.js | 8 |
4 files changed, 109 insertions, 33 deletions
diff --git a/dom/security/metrics.yaml b/dom/security/metrics.yaml index d48069e4b1..1fa025f002 100644 --- a/dom/security/metrics.yaml +++ b/dom/security/metrics.yaml @@ -14,8 +14,9 @@ httpsfirst: upgraded: type: counter description: > - Counts how often a load is marked to be upgraded to HTTPS because of - HTTPS-First (`dom.security.https_first` enabled). + Counts how often a load is successfully upgraded to HTTPS because of + HTTPS-First (`dom.security.https_first` enabled). This does not include + loads that get downgraded again. bugs: - https://bugzilla.mozilla.org/show_bug.cgi?id=1868380 data_reviews: @@ -30,9 +31,10 @@ httpsfirst: upgraded_schemeless: type: counter description: > - Counts how often a load is marked to be upgraded to HTTPS because of + Counts how often a load is successfully upgraded to HTTPS because of schemeless HTTPS-First (`dom.security.https_first` disabled, but load - marked as schemeless). + marked as schemeless). This does not include loads that get downgraded + again. bugs: - https://bugzilla.mozilla.org/show_bug.cgi?id=1868380 data_reviews: @@ -48,7 +50,7 @@ httpsfirst: type: counter description: > How many regular HTTPS-First (`dom.security.https_first` enabled) - upgrades get downgraded again. + upgrades fail and get downgraded again. bugs: - https://bugzilla.mozilla.org/show_bug.cgi?id=1868380 data_reviews: @@ -64,7 +66,7 @@ httpsfirst: type: counter description: > How many schemeless HTTPS-First (`dom.security.https_first` disabled, but - load marked as schemeless) upgrades get downgraded again. + load marked as schemeless) upgrades fail and get downgraded again. bugs: - https://bugzilla.mozilla.org/show_bug.cgi?id=1868380 data_reviews: @@ -118,8 +120,7 @@ httpsfirst: description: > If a HTTPS-First (`dom.security.https_first` enabled) upgrade isn't successful, measures the timespan between the navigation start and the - downgrade. This does not include the case in which the https request times - out and the http request sent after 3s gets a response faster. + downgrade. time_unit: millisecond bugs: - https://bugzilla.mozilla.org/show_bug.cgi?id=1868380 @@ -137,9 +138,7 @@ httpsfirst: description: > If a schemeless HTTPS-First (`dom.security.https_first` disabled, but load marked as schemeless) upgrade isn't successful, measures the timespan - between the navigation start and the downgrade. This does not include the - case in which the https request times out and the http request sent after - 3s gets a response faster. + between the navigation start and the downgrade. time_unit: millisecond bugs: - https://bugzilla.mozilla.org/show_bug.cgi?id=1868380 diff --git a/dom/security/nsHTTPSOnlyUtils.cpp b/dom/security/nsHTTPSOnlyUtils.cpp index 0bc99179dc..b5512d8f78 100644 --- a/dom/security/nsHTTPSOnlyUtils.cpp +++ b/dom/security/nsHTTPSOnlyUtils.cpp @@ -448,8 +448,6 @@ bool nsHTTPSOnlyUtils::ShouldUpgradeHttpsFirstRequest(nsIURI* aURI, nsHTTPSOnlyUtils::LogLocalizedString("HTTPSFirstSchemeless", params, nsIScriptError::warningFlag, aLoadInfo, aURI, true); - - mozilla::glean::httpsfirst::upgraded_schemeless.Add(); } else { nsAutoCString scheme; @@ -464,10 +462,6 @@ bool nsHTTPSOnlyUtils::ShouldUpgradeHttpsFirstRequest(nsIURI* aURI, isSpeculative ? "HTTPSOnlyUpgradeSpeculativeConnection" : "HTTPSOnlyUpgradeRequest", params, nsIScriptError::warningFlag, aLoadInfo, aURI, true); - - if (!isSpeculative) { - mozilla::glean::httpsfirst::upgraded.Add(); - } } // Set flag so we know that we upgraded the request @@ -594,7 +588,17 @@ nsHTTPSOnlyUtils::PotentiallyDowngradeHttpsFirstRequest( nsIScriptError::warningFlag, loadInfo, uri, true); - // Record telemety + return newURI.forget(); +} + +void nsHTTPSOnlyUtils::UpdateLoadStateAfterHTTPSFirstDowngrade( + mozilla::net::DocumentLoadListener* aDocumentLoadListener, + nsDocShellLoadState* aLoadState) { + // We have to exempt the load from HTTPS-First to prevent a upgrade-downgrade + // loop + aLoadState->SetIsExemptFromHTTPSFirstMode(true); + + // Add downgrade data for later telemetry usage to load state nsDOMNavigationTiming* timing = aDocumentLoadListener->GetTiming(); if (timing) { mozilla::TimeStamp navigationStart = timing->GetNavigationStartTimeStamp(); @@ -602,31 +606,60 @@ nsHTTPSOnlyUtils::PotentiallyDowngradeHttpsFirstRequest( mozilla::TimeDuration duration = mozilla::TimeStamp::Now() - navigationStart; + nsCOMPtr<nsIChannel> channel = aDocumentLoadListener->GetChannel(); + nsCOMPtr<nsILoadInfo> loadInfo = channel->LoadInfo(); + bool isPrivateWin = loadInfo->GetOriginAttributes().mPrivateBrowsingId > 0; bool isSchemeless = loadInfo->GetWasSchemelessInput() && !nsHTTPSOnlyUtils::IsHttpsFirstModeEnabled(isPrivateWin); - using namespace mozilla::glean::httpsfirst; - auto downgradedMetric = isSchemeless ? downgraded_schemeless : downgraded; - auto downgradedOnTimerMetric = - isSchemeless ? downgraded_on_timer_schemeless : downgraded_on_timer; - auto downgradeTimeMetric = - isSchemeless ? downgrade_time_schemeless : downgrade_time; - nsresult channelStatus; channel->GetStatus(&channelStatus); - if (channelStatus == NS_ERROR_NET_TIMEOUT_EXTERNAL) { - downgradedOnTimerMetric.AddToNumerator(); - } else { - downgradeTimeMetric.AccumulateRawDuration(duration); - } - downgradedMetric.Add(); + + RefPtr downgradeData = mozilla::MakeRefPtr<HTTPSFirstDowngradeData>(); + downgradeData->downgradeTime = duration; + downgradeData->isOnTimer = channelStatus == NS_ERROR_NET_TIMEOUT_EXTERNAL; + downgradeData->isSchemeless = isSchemeless; + aLoadState->SetHttpsFirstDowngradeData(downgradeData); } } +} - return newURI.forget(); +void nsHTTPSOnlyUtils::SubmitHTTPSFirstTelemetry( + nsCOMPtr<nsILoadInfo> const& aLoadInfo, + RefPtr<HTTPSFirstDowngradeData> const& aHttpsFirstDowngradeData) { + using namespace mozilla::glean::httpsfirst; + if (aHttpsFirstDowngradeData) { + // Successfully downgraded load + + auto downgradedMetric = aHttpsFirstDowngradeData->isSchemeless + ? downgraded_schemeless + : downgraded; + auto downgradedOnTimerMetric = aHttpsFirstDowngradeData->isSchemeless + ? downgraded_on_timer_schemeless + : downgraded_on_timer; + auto downgradeTimeMetric = aHttpsFirstDowngradeData->isSchemeless + ? downgrade_time_schemeless + : downgrade_time; + + if (aHttpsFirstDowngradeData->isOnTimer) { + downgradedOnTimerMetric.AddToNumerator(); + } + downgradedMetric.Add(); + downgradeTimeMetric.AccumulateRawDuration( + aHttpsFirstDowngradeData->downgradeTime); + } else if (aLoadInfo->GetHttpsOnlyStatus() & + nsILoadInfo::HTTPS_ONLY_UPGRADED_HTTPS_FIRST) { + // Successfully upgraded load + + if (aLoadInfo->GetWasSchemelessInput()) { + upgraded_schemeless.Add(); + } else { + upgraded.Add(); + } + } } /* static */ diff --git a/dom/security/nsHTTPSOnlyUtils.h b/dom/security/nsHTTPSOnlyUtils.h index 775fbf39e0..d582e62f36 100644 --- a/dom/security/nsHTTPSOnlyUtils.h +++ b/dom/security/nsHTTPSOnlyUtils.h @@ -176,6 +176,31 @@ class nsHTTPSOnlyUtils { */ static uint32_t GetStatusForSubresourceLoad(uint32_t aHttpsOnlyStatus); + /** + * When a downgrade is happening because of HTTPS-First, this function will + * update the load state for the new load accordingly. This includes + * information about the downgrade for later telemetry use. + * @param aDocumentLoadListener The calling document load listener. + * @param aLoadState The load state to be updated + */ + static void UpdateLoadStateAfterHTTPSFirstDowngrade( + mozilla::net::DocumentLoadListener* aDocumentLoadListener, + nsDocShellLoadState* aLoadState); + + /** + * When a load is successful, this should be called by the document load + * listener. In two cases, telemetry is then recorded: + * a) If downgrade data has been passed, the passed load is a successful + * downgrade, which means telemetry based on the downgrade data will be + * submitted. + * b) If the passed load info indicates that this load has been upgraded by + * HTTPS-First, this means the upgrade was successful, which will be + * recorded to telemetry. + */ + static void SubmitHTTPSFirstTelemetry( + nsCOMPtr<nsILoadInfo> const& aLoadInfo, + RefPtr<HTTPSFirstDowngradeData> const& aHttpsFirstDowngradeData); + private: /** * Checks if it can be ruled out that the error has something @@ -257,4 +282,17 @@ class TestHTTPAnswerRunnable final : public mozilla::Runnable, RefPtr<nsITimer> mTimer; }; +/** + * Data about a HTTPS-First downgrade used for Telemetry. We need to store this + * instead of directly submitting it when deciding to downgrade, because it is + * only interesting for us if the downgraded load is actually succesful. + */ +struct HTTPSFirstDowngradeData + : public mozilla::RefCounted<HTTPSFirstDowngradeData> { + MOZ_DECLARE_REFCOUNTED_TYPENAME(HTTPSFirstDowngradeData) + mozilla::TimeDuration downgradeTime; + bool isOnTimer = false; + bool isSchemeless = false; +}; + #endif /* nsHTTPSOnlyUtils_h___ */ diff --git a/dom/security/test/https-first/browser_httpsfirst.js b/dom/security/test/https-first/browser_httpsfirst.js index e0bba26f73..060d7d362c 100644 --- a/dom/security/test/https-first/browser_httpsfirst.js +++ b/dom/security/test/https-first/browser_httpsfirst.js @@ -90,8 +90,14 @@ add_task(async function () { "http://" ); + await runPrefTest( + "http://invalid.example.com", + "Should downgrade non-reachable site.", + "http://" + ); + info("Checking expected telemetry"); - is(Glean.httpsfirst.upgraded.testGetValue(), 5); + is(Glean.httpsfirst.upgraded.testGetValue(), 1); is(Glean.httpsfirst.upgradedSchemeless.testGetValue(), null); is(Glean.httpsfirst.downgraded.testGetValue(), 3); is(Glean.httpsfirst.downgradedSchemeless.testGetValue(), null); |