diff --git a/services/settings/Attachments.sys.mjs b/services/settings/Attachments.sys.mjs --- a/services/settings/Attachments.sys.mjs +++ b/services/settings/Attachments.sys.mjs @@ -133,6 +133,7 @@ export class Downloader { * @param {Boolean} options.fallbackToDump Use the remote settings dump as a * potential source of the attachment. * (default: `false`) + * @param {string} options.serverUrl * @throws {Downloader.DownloadError} if the file could not be fetched. * @throws {Downloader.BadContentError} if the downloaded content integrity is not valid. * @throws {Downloader.ServerInfoError} if the server response is not valid. @@ -149,6 +150,7 @@ export class Downloader { attachmentId = record?.id, fallbackToCache = false, fallbackToDump = false, + serverUrl, } = options || {}; if (!attachmentId) { // Check for pre-condition. This should not happen, but it is explicitly @@ -200,6 +202,7 @@ export class Downloader { const newBuffer = await this.downloadAsBytes(record, { retries, checkHash, + serverUrl, }); const blob = new Blob([newBuffer]); // Store in cache but don't wait for it before returning. @@ -367,6 +370,7 @@ export class Downloader { * @param {Object} options Some download options. * @param {Number} options.retries Number of times download should be retried (default: `3`) * @param {Boolean} options.checkHash Check content integrity (default: `true`) + * @param {String} options.serverUrl * @throws {Downloader.DownloadError} if the file could not be fetched. * @throws {Downloader.BadContentError} if the downloaded content integrity is not valid. * @returns {ArrayBuffer} the file content. @@ -375,10 +379,11 @@ export class Downloader { const { attachment: { location, hash, size }, } = record; + const { retries = 3, checkHash = true, serverUrl } = options; - const remoteFileUrl = (await this._baseAttachmentsURL()) + location; + const remoteFileUrl = + (await this._baseAttachmentsURL(serverUrl)) + location; - const { retries = 3, checkHash = true } = options; let retried = 0; while (true) { try { @@ -427,9 +432,9 @@ export class Downloader { await this._rmDirs(); } - async _baseAttachmentsURL() { - if (!this._cdnURLs[lazy.Utils.SERVER_URL]) { - const resp = await lazy.Utils.fetch(`${lazy.Utils.SERVER_URL}/`); + async _baseAttachmentsURL(serverUrl = lazy.Utils.SERVER_URL) { + if (!this._cdnURLs[serverUrl]) { + const resp = await lazy.Utils.fetch(`${serverUrl}/`); let serverInfo; try { serverInfo = await resp.json(); @@ -443,10 +448,9 @@ export class Downloader { }, } = serverInfo; // Make sure the URL always has a trailing slash. - this._cdnURLs[lazy.Utils.SERVER_URL] = - base_url + (base_url.endsWith("/") ? "" : "/"); + this._cdnURLs[serverUrl] = base_url + (base_url.endsWith("/") ? "" : "/"); } - return this._cdnURLs[lazy.Utils.SERVER_URL]; + return this._cdnURLs[serverUrl]; } async _fetchAttachment(url) { diff --git a/services/settings/RemoteSettingsClient.sys.mjs b/services/settings/RemoteSettingsClient.sys.mjs --- a/services/settings/RemoteSettingsClient.sys.mjs +++ b/services/settings/RemoteSettingsClient.sys.mjs @@ -305,6 +305,7 @@ export class RemoteSettingsClient extend localFields = [], keepAttachmentsIds = [], lastCheckTimePref, + serverUrl, } = {} ) { // Remote Settings cannot be used in child processes (no access to disk, @@ -334,6 +335,7 @@ export class RemoteSettingsClient extend this._lastCheckTimePref = lastCheckTimePref; this._verifier = null; this._syncRunning = false; + this._serverUrl = serverUrl; // This attribute allows signature verification to be disabled, when running tests // or when pulling data from a dev server. @@ -375,9 +377,12 @@ export class RemoteSettingsClient extend } httpClient() { - const api = new lazy.KintoHttpClient(lazy.Utils.SERVER_URL, { - fetchFunc: lazy.Utils.fetch, // Use fetch() wrapper. - }); + const api = new lazy.KintoHttpClient( + this._serverUrl || lazy.Utils.SERVER_URL, + { + fetchFunc: lazy.Utils.fetch, // Use fetch() wrapper. + } + ); return api.bucket(this.bucketName).collection(this.collectionName); } @@ -600,7 +605,7 @@ export class RemoteSettingsClient extend // We want to know which timestamp we are expected to obtain in order to leverage // cache busting. We don't provide ETag because we don't want a 304. const { changes } = await lazy.Utils.fetchLatestChanges( - lazy.Utils.SERVER_URL, + this._serverUrl || lazy.Utils.SERVER_URL, { filters: { collection: this.collectionName, diff --git a/toolkit/components/translations/actors/TranslationsParent.sys.mjs b/toolkit/components/translations/actors/TranslationsParent.sys.mjs --- a/toolkit/components/translations/actors/TranslationsParent.sys.mjs +++ b/toolkit/components/translations/actors/TranslationsParent.sys.mjs @@ -854,9 +854,8 @@ export class TranslationsParent extends // Place the records into a promise to prevent any races. TranslationsParent.#languageIdModelRecord = (async () => { /** @type {LanguageIdModelRecord[]} */ - let modelRecords = await TranslationsParent.getMaxVersionRecords( - client - ); + let modelRecords = + await TranslationsParent.getMaxVersionRecords(client); if (modelRecords.length === 0) { throw new Error( @@ -881,7 +880,10 @@ export class TranslationsParent extends try { /** @type {{buffer: ArrayBuffer}} */ const { buffer } = await client.attachments.download( - await TranslationsParent.#languageIdModelRecord + await TranslationsParent.#languageIdModelRecord, + { + serverUrl: "https://firefox.settings.services.mozilla.com/v1", + } ); const duration = (Date.now() - now) / 1000; @@ -968,7 +970,10 @@ export class TranslationsParent extends /** @type {{buffer: ArrayBuffer}} */ const { buffer } = await client.attachments.download( - await TranslationsParent.#languageIdWasmRecord + await TranslationsParent.#languageIdWasmRecord, + { + serverUrl: "https://firefox.settings.services.mozilla.com/v1", + } ); const duration = (Date.now() - start) / 1000; @@ -1147,7 +1152,9 @@ export class TranslationsParent extends } /** @type {RemoteSettingsClient} */ - const client = lazy.RemoteSettings("translations-models"); + const client = lazy.RemoteSettings("translations-models", { + serverUrl: "https://firefox.settings.services.mozilla.com/v1", + }); TranslationsParent.#translationModelsRemoteClient = client; client.on("sync", TranslationsParent.#handleTranslationsModelsSync); return client; @@ -1456,7 +1463,10 @@ export class TranslationsParent extends /** @type {{buffer: ArrayBuffer}} */ const { buffer } = await client.attachments.download( - await TranslationsParent.#bergamotWasmRecord + await TranslationsParent.#bergamotWasmRecord, + { + serverUrl: "https://firefox.settings.services.mozilla.com/v1", + } ); const duration = Date.now() - start; @@ -1507,7 +1517,9 @@ export class TranslationsParent extends )) { const download = () => { lazy.console.log("Downloading record", record.name, record.id); - return client.attachments.download(record); + return client.attachments.download(record, { + serverUrl: "https://firefox.settings.services.mozilla.com/v1", + }); }; queue.push({ download }); } @@ -1531,7 +1543,10 @@ export class TranslationsParent extends onFailure: () => { console.error("Failed to download", record.name); }, - download: () => client.attachments.download(record), + download: () => + client.attachments.download(record, { + serverUrl: "https://firefox.settings.services.mozilla.com/v1", + }), }); } @@ -1700,7 +1715,9 @@ export class TranslationsParent extends await chaosMode(1 / 3); /** @type {{buffer: ArrayBuffer }} */ - const { buffer } = await client.attachments.download(record); + const { buffer } = await client.attachments.download(record, { + serverUrl: "https://firefox.settings.services.mozilla.com/v1", + }); results[record.fileType] = { buffer,