Bug 1397061 - Adjust clock skew according to CDN cache age r=mgoodwin
MozReview-Commit-ID: 9HPiNIp8bJM
--- a/services/settings/remote-settings.js
+++ b/services/settings/remote-settings.js
@@ -159,17 +159,20 @@ async function fetchLatestChanges(url, l
// expected data (e.g. error response - Bug 1259145)
throw new Error(`Server error response ${JSON.stringify(payload)}`);
}
changes = payload.data;
}
// The server should always return ETag. But we've had situations where the CDN
// was interfering.
const currentEtag = response.headers.has("ETag") ? response.headers.get("ETag") : undefined;
- const serverTimeMillis = Date.parse(response.headers.get("Date"));
+ let serverTimeMillis = Date.parse(response.headers.get("Date"));
+ // Since the response is served via a CDN, the Date header value could have been cached.
+ const ageSeconds = response.headers.has("Age") ? parseInt(response.headers.get("Age"), 10) : 0;
+ serverTimeMillis += ageSeconds * 1000;
// Check if the server asked the clients to back off.
let backoffSeconds;
if (response.headers.has("Backoff")) {
const value = parseInt(response.headers.get("Backoff"), 10);
if (!isNaN(value)) {
backoffSeconds = value;
}
--- a/services/settings/test/unit/test_remote_settings_poll.js
+++ b/services/settings/test/unit/test_remote_settings_poll.js
@@ -243,16 +243,39 @@ add_task(async function test_check_clock
clockDifference = Services.prefs.getIntPref(PREF_CLOCK_SKEW_SECONDS);
// we previously set the serverTime to Date.now() + 10000 ms past epoch
Assert.ok(clockDifference <= 0 && clockDifference >= -10);
});
add_task(clear_state);
+add_task(async function test_check_clockskew_takes_age_into_account() {
+ const currentTime = Date.now();
+ const skewSeconds = 5;
+ const ageCDNSeconds = 3600;
+ const serverTime = currentTime - (skewSeconds * 1000) - (ageCDNSeconds * 1000);
+
+ function serverResponse(request, response) {
+ response.setHeader("Content-Type", "application/json; charset=UTF-8");
+ response.setHeader("Date", (new Date(serverTime)).toUTCString());
+ response.setHeader("Age", `${ageCDNSeconds}`);
+ response.write(JSON.stringify({data: []}));
+ response.setStatusLine(null, 200, "OK");
+ }
+ server.registerPathHandler(CHANGES_PATH, serverResponse);
+
+ await RemoteSettings.pollChanges();
+
+ const clockSkew = Services.prefs.getIntPref(PREF_CLOCK_SKEW_SECONDS);
+ Assert.ok(clockSkew >= skewSeconds, `clockSkew is ${clockSkew}`);
+});
+add_task(clear_state);
+
+
add_task(async function test_backoff() {
const startHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY);
function simulateBackoffResponse(request, response) {
response.setHeader("Content-Type", "application/json; charset=UTF-8");
response.setHeader("Backoff", "10");
response.write(JSON.stringify({data: []}));
response.setStatusLine(null, 200, "OK");