mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1719070 - UA: Add support for a Nimbus experiment to override Firefox's User-Agent string. r=andreio,necko-reviewers,dragana
The ANDROID #ifdefs are necessary because Nimbus does not yet support Android in Gecko. The planned UA experiment won't include Android, so that's not a problem. Differential Revision: https://phabricator.services.mozilla.com/D121112
This commit is contained in:
parent
fef38775ad
commit
162a8620f1
@ -398,4 +398,63 @@ add_task(async function runOverrideTest() {
|
||||
await testWorkerNavigator();
|
||||
|
||||
await testUserAgentHeader();
|
||||
|
||||
// Pop general.appname.override etc
|
||||
await SpecialPowers.popPrefEnv();
|
||||
|
||||
// Pop privacy.resistFingerprinting
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
|
||||
// Only test the Firefox and Gecko experiment prefs on desktop.
|
||||
if (AppConstants.platform != "android") {
|
||||
add_task(async function setupFirefoxVersionExperiment() {
|
||||
// Mock Nimbus experiment settings
|
||||
const { ExperimentFakes } = ChromeUtils.import(
|
||||
"resource://testing-common/NimbusTestUtils.jsm"
|
||||
);
|
||||
let doExperimentCleanup = await ExperimentFakes.enrollWithFeatureConfig({
|
||||
featureId: "firefox100",
|
||||
value: { firefoxVersion: 100 },
|
||||
});
|
||||
|
||||
let experimentOscpu;
|
||||
switch (AppConstants.platform) {
|
||||
case "win":
|
||||
experimentOscpu =
|
||||
cpuArch == "x86_64"
|
||||
? "Windows NT 10.0; Win64; x64"
|
||||
: "Windows NT 10.0";
|
||||
break;
|
||||
case "macosx":
|
||||
experimentOscpu = "Macintosh; Intel Mac OS X 10.15";
|
||||
break;
|
||||
default:
|
||||
experimentOscpu = "X11; Linux x86_64";
|
||||
break;
|
||||
}
|
||||
|
||||
let experimentUserAgent = `Mozilla/5.0 (${experimentOscpu}; rv:100.0) Gecko/20100101 Firefox/100.0`;
|
||||
|
||||
expectedResults = {
|
||||
testDesc: "FirefoxVersionExperimentTest",
|
||||
appVersion: DEFAULT_APPVERSION[AppConstants.platform],
|
||||
hardwareConcurrency: navigator.hardwareConcurrency,
|
||||
oscpu: DEFAULT_OSCPU[AppConstants.platform],
|
||||
platform: DEFAULT_PLATFORM[AppConstants.platform],
|
||||
userAgentNavigator: experimentUserAgent,
|
||||
userAgentHeader: experimentUserAgent,
|
||||
};
|
||||
|
||||
await testNavigator();
|
||||
|
||||
// Skip worker tests due to intermittent bug 1713764. This is unlikely to be
|
||||
// a scenario that affects users enrolled in our "Firefox 100" experiment.
|
||||
// await testWorkerNavigator();
|
||||
|
||||
await testUserAgentHeader();
|
||||
|
||||
// Clear Nimbus experiment prefs and session data
|
||||
await doExperimentCleanup();
|
||||
});
|
||||
}
|
||||
|
@ -98,6 +98,10 @@
|
||||
# include "nsCocoaFeatures.h"
|
||||
#endif
|
||||
|
||||
#ifndef ANDROID
|
||||
# include "mozilla/browser/NimbusFeatures.h"
|
||||
#endif // ANDROID
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "mozilla/net/HttpChannelChild.h"
|
||||
|
||||
@ -124,6 +128,11 @@
|
||||
#define NS_HTTP_PROTOCOL_FLAGS \
|
||||
(URI_STD | ALLOWS_PROXY | ALLOWS_PROXY_HTTP | URI_LOADABLE_BY_ANYONE)
|
||||
|
||||
#ifndef ANDROID
|
||||
# define UA_EXPERIMENT_NAME "firefox100"_ns
|
||||
# define UA_EXPERIMENT_VAR "firefoxVersion"_ns
|
||||
#endif // ANDROID
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
using mozilla::dom::Promise;
|
||||
@ -132,6 +141,42 @@ namespace mozilla::net {
|
||||
|
||||
LazyLogModule gHttpLog("nsHttp");
|
||||
|
||||
#ifndef ANDROID
|
||||
static void ExperimentUserAgentUpdated(const char* /* aNimbusPref */,
|
||||
void* aUserData) {
|
||||
MOZ_ASSERT(aUserData != nullptr);
|
||||
nsACString* aExperimentUserAgent = static_cast<nsACString*>(aUserData);
|
||||
|
||||
// Is this user enrolled in the Firefox 100 experiment?
|
||||
int firefoxVersion =
|
||||
NimbusFeatures::GetInt(UA_EXPERIMENT_NAME, UA_EXPERIMENT_VAR, 0);
|
||||
if (firefoxVersion <= 0) {
|
||||
aExperimentUserAgent->SetIsVoid(true);
|
||||
return;
|
||||
}
|
||||
|
||||
const char uaFormat[] =
|
||||
# ifdef XP_WIN
|
||||
# ifdef HAVE_64BIT_BUILD
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:%d.0) Gecko/20100101 "
|
||||
"Firefox/%d.0"
|
||||
# else
|
||||
"Mozilla/5.0 (Windows NT 10.0; rv:%d.0) Gecko/20100101 Firefox/%d.0"
|
||||
# endif
|
||||
# elif defined(XP_MACOSX)
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:%d.0) Gecko/20100101 "
|
||||
"Firefox/%d.0"
|
||||
# else
|
||||
// Linux, Android, FreeBSD, etc
|
||||
"Mozilla/5.0 (X11; Linux x86_64; rv:%d.0) Gecko/20100101 Firefox/%d.0"
|
||||
# endif
|
||||
;
|
||||
|
||||
aExperimentUserAgent->Truncate();
|
||||
aExperimentUserAgent->AppendPrintf(uaFormat, firefoxVersion, firefoxVersion);
|
||||
}
|
||||
#endif // ANDROID
|
||||
|
||||
#ifdef ANDROID
|
||||
static nsCString GetDeviceModelId() {
|
||||
// Assumed to be running on the main thread
|
||||
@ -233,6 +278,10 @@ nsHttpHandler::nsHttpHandler()
|
||||
|
||||
mUserAgentOverride.SetIsVoid(true);
|
||||
|
||||
#ifndef ANDROID
|
||||
mExperimentUserAgent.SetIsVoid(true);
|
||||
#endif // ANDROID
|
||||
|
||||
MOZ_ASSERT(!gHttpHandler, "HTTP handler already created!");
|
||||
|
||||
nsCOMPtr<nsIXULRuntime> runtime = do_GetService("@mozilla.org/xre/runtime;1");
|
||||
@ -338,6 +387,13 @@ nsresult nsHttpHandler::Init() {
|
||||
Preferences::RegisterPrefixCallbacks(nsHttpHandler::PrefsChanged,
|
||||
gCallbackPrefs, this);
|
||||
PrefsChanged(nullptr);
|
||||
|
||||
#ifndef ANDROID
|
||||
// monitor Firefox Version Experiment enrollment
|
||||
NimbusFeatures::OnUpdate(UA_EXPERIMENT_NAME, UA_EXPERIMENT_VAR,
|
||||
ExperimentUserAgentUpdated, &mExperimentUserAgent);
|
||||
#endif // ANDROID
|
||||
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::NETWORKING_HTTP3_ENABLED,
|
||||
mHttp3Enabled);
|
||||
|
||||
@ -699,6 +755,14 @@ const nsCString& nsHttpHandler::UserAgent() {
|
||||
return mUserAgentOverride;
|
||||
}
|
||||
|
||||
#ifndef ANDROID
|
||||
if (!mExperimentUserAgent.IsVoid()) {
|
||||
LOG(("using Firefox 100 Experiment User-Agent : %s\n",
|
||||
mExperimentUserAgent.get()));
|
||||
return mExperimentUserAgent;
|
||||
}
|
||||
#endif // ANDROID
|
||||
|
||||
if (mUserAgentIsDirty) {
|
||||
BuildUserAgent();
|
||||
mUserAgentIsDirty = false;
|
||||
|
@ -647,6 +647,11 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
|
||||
nsCString mUserAgent;
|
||||
nsCString mSpoofedUserAgent;
|
||||
nsCString mUserAgentOverride;
|
||||
|
||||
#ifndef ANDROID
|
||||
nsCString mExperimentUserAgent;
|
||||
#endif // ANDROID
|
||||
|
||||
bool mUserAgentIsDirty{true}; // true if mUserAgent should be rebuilt
|
||||
bool mAcceptLanguagesIsDirty{true};
|
||||
|
||||
|
@ -84,6 +84,16 @@ const FeatureManifest = {
|
||||
},
|
||||
},
|
||||
},
|
||||
firefox100: {
|
||||
description: "Firefox User-Agent version",
|
||||
isEarlyStartup: true,
|
||||
variables: {
|
||||
firefoxVersion: {
|
||||
type: "int",
|
||||
description: "Firefox version to spoof (or `0` to use default version)",
|
||||
},
|
||||
},
|
||||
},
|
||||
newtab: {
|
||||
description: "The about:newtab page",
|
||||
isEarlyStartup: true,
|
||||
|
Loading…
Reference in New Issue
Block a user