mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 958447 - respect Retry-After header from token server. r=rnewman
This commit is contained in:
parent
87465ce098
commit
4242ccd1ec
@ -17,6 +17,7 @@ Cu.import("resource://gre/modules/Preferences.jsm");
|
|||||||
Cu.import("resource://gre/modules/Log.jsm");
|
Cu.import("resource://gre/modules/Log.jsm");
|
||||||
Cu.import("resource://services-common/rest.js");
|
Cu.import("resource://services-common/rest.js");
|
||||||
Cu.import("resource://services-common/utils.js");
|
Cu.import("resource://services-common/utils.js");
|
||||||
|
Cu.import("resource://services-common/observers.js");
|
||||||
|
|
||||||
const Prefs = new Preferences("services.common.tokenserverclient.");
|
const Prefs = new Preferences("services.common.tokenserverclient.");
|
||||||
|
|
||||||
@ -328,6 +329,9 @@ TokenServerClient.prototype = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Any response status can have an X-Backoff header.
|
||||||
|
this._maybeNotifyBackoff(response, "x-backoff");
|
||||||
|
|
||||||
// The service shouldn't have any 3xx, so we don't need to handle those.
|
// The service shouldn't have any 3xx, so we don't need to handle those.
|
||||||
if (response.status != 200) {
|
if (response.status != 200) {
|
||||||
// We /should/ have a Cornice error report in the JSON. We log that to
|
// We /should/ have a Cornice error report in the JSON. We log that to
|
||||||
@ -379,6 +383,10 @@ TokenServerClient.prototype = {
|
|||||||
error.cause = "unknown-service";
|
error.cause = "unknown-service";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A Retry-After header should theoretically only appear on a 503, but
|
||||||
|
// we'll look for it on any error response.
|
||||||
|
this._maybeNotifyBackoff(response, "retry-after");
|
||||||
|
|
||||||
cb(error, null);
|
cb(error, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -405,6 +413,23 @@ TokenServerClient.prototype = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Given an optional header value, notify that a backoff has been requested.
|
||||||
|
_maybeNotifyBackoff: function (response, headerName) {
|
||||||
|
let headerVal = response.headers[headerName];
|
||||||
|
if (!headerVal) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let backoffInterval;
|
||||||
|
try {
|
||||||
|
backoffInterval = parseInt(headerVal, 10);
|
||||||
|
} catch (ex) {
|
||||||
|
this._log.error("TokenServer response had invalid backoff value in '" +
|
||||||
|
headerName + "' header: " + headerVal);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Observers.notify("tokenserver:backoff:interval", backoffInterval);
|
||||||
|
},
|
||||||
|
|
||||||
// override points for testing.
|
// override points for testing.
|
||||||
newRESTRequest: function(url) {
|
newRESTRequest: function(url) {
|
||||||
return new RESTRequest(url);
|
return new RESTRequest(url);
|
||||||
|
@ -92,6 +92,7 @@ SyncScheduler.prototype = {
|
|||||||
Svc.Obs.add("weave:engine:sync:applied", this);
|
Svc.Obs.add("weave:engine:sync:applied", this);
|
||||||
Svc.Obs.add("weave:service:setup-complete", this);
|
Svc.Obs.add("weave:service:setup-complete", this);
|
||||||
Svc.Obs.add("weave:service:start-over", this);
|
Svc.Obs.add("weave:service:start-over", this);
|
||||||
|
Svc.Obs.add("tokenserver:backoff:interval", this);
|
||||||
|
|
||||||
if (Status.checkSetup() == STATUS_OK) {
|
if (Status.checkSetup() == STATUS_OK) {
|
||||||
Svc.Idle.addIdleObserver(this, Svc.Prefs.get("scheduler.idleTime"));
|
Svc.Idle.addIdleObserver(this, Svc.Prefs.get("scheduler.idleTime"));
|
||||||
@ -181,6 +182,7 @@ SyncScheduler.prototype = {
|
|||||||
this.nextSync = 0;
|
this.nextSync = 0;
|
||||||
this.handleSyncError();
|
this.handleSyncError();
|
||||||
break;
|
break;
|
||||||
|
case "tokenserver:backoff:interval":
|
||||||
case "weave:service:backoff:interval":
|
case "weave:service:backoff:interval":
|
||||||
let requested_interval = subject * 1000;
|
let requested_interval = subject * 1000;
|
||||||
this._log.debug("Got backoff notification: " + requested_interval + "ms");
|
this._log.debug("Got backoff notification: " + requested_interval + "ms");
|
||||||
|
@ -13,6 +13,7 @@ Cu.import("resource://gre/modules/FxAccounts.jsm");
|
|||||||
Cu.import("resource://gre/modules/FxAccountsClient.jsm");
|
Cu.import("resource://gre/modules/FxAccountsClient.jsm");
|
||||||
Cu.import("resource://gre/modules/FxAccountsCommon.js");
|
Cu.import("resource://gre/modules/FxAccountsCommon.js");
|
||||||
Cu.import("resource://services-common/tokenserverclient.js");
|
Cu.import("resource://services-common/tokenserverclient.js");
|
||||||
|
Cu.import("resource://services-sync/service.js");
|
||||||
Cu.import("resource://services-sync/status.js");
|
Cu.import("resource://services-sync/status.js");
|
||||||
Cu.import("resource://services-sync/constants.js");
|
Cu.import("resource://services-sync/constants.js");
|
||||||
|
|
||||||
@ -363,6 +364,36 @@ add_task(function test_getTokenErrors() {
|
|||||||
Assert.equal(Status.login, LOGIN_FAILED_NETWORK_ERROR, "login state is LOGIN_FAILED_NETWORK_ERROR");
|
Assert.equal(Status.login, LOGIN_FAILED_NETWORK_ERROR, "login state is LOGIN_FAILED_NETWORK_ERROR");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
add_task(function test_getTokenErrorWithRetry() {
|
||||||
|
_("tokenserver sends an observer notification on various backoff headers.");
|
||||||
|
|
||||||
|
// Set Sync's backoffInterval to zero - after we simulated the backoff header
|
||||||
|
// it should reflect the value we sent.
|
||||||
|
Status.backoffInterval = 0;
|
||||||
|
_("Arrange for a 503 with a Retry-After header.");
|
||||||
|
yield initializeIdentityWithTokenServerFailure({
|
||||||
|
status: 503,
|
||||||
|
headers: {"content-type": "application/json",
|
||||||
|
"retry-after": "100"},
|
||||||
|
body: JSON.stringify({}),
|
||||||
|
});
|
||||||
|
// The observer should have fired - check it got the value in the response.
|
||||||
|
Assert.equal(Status.login, LOGIN_FAILED_NETWORK_ERROR, "login was rejected");
|
||||||
|
// Sync will have the value in ms with some slop - so check it is at least that.
|
||||||
|
Assert.ok(Status.backoffInterval >= 100000);
|
||||||
|
|
||||||
|
_("Arrange for a 200 with an X-Backoff header.");
|
||||||
|
Status.backoffInterval = 0;
|
||||||
|
yield initializeIdentityWithTokenServerFailure({
|
||||||
|
status: 503,
|
||||||
|
headers: {"content-type": "application/json",
|
||||||
|
"x-backoff": "200"},
|
||||||
|
body: JSON.stringify({}),
|
||||||
|
});
|
||||||
|
// The observer should have fired - check it got the value in the response.
|
||||||
|
Assert.ok(Status.backoffInterval >= 200000);
|
||||||
|
});
|
||||||
|
|
||||||
add_task(function test_getHAWKErrors() {
|
add_task(function test_getHAWKErrors() {
|
||||||
_("BrowserIDManager correctly handles various HAWK failures.");
|
_("BrowserIDManager correctly handles various HAWK failures.");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user