/
githubmirror
/
amphtml
Обзор
Документация
Войти
/
githubmirror
/
amphtml
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/service/cache-cid-api.js
149 строк
4 KB
Alan Orozco
🚮 Remove `dict()` (#37383)
14 янв 2022, 21:45
Не верифицирован
14 янв 2022, 21:45
42c3b1d
Код
Авторство
О чём код?
import {Services} from '#service'; import {dev} from '#utils/log'; import {getSourceOrigin} from '../url'; /** * The Client ID service key. * @const @private {string} */ const SERVICE_KEY_ = 'AIzaSyDKtqGxnoeIqVM33Uf7hRSa3GJxuzR7mLc'; /** * Tag for debug logging. * @const @private {string} */ const TAG_ = 'CacheCidApi'; /** * The URL for the cache-served CID API. * @const @private {string} */ const CACHE_API_URL = 'https://ampcid.google.com/v1/cache:getClientId?key='; /** * The XHR timeout in milliseconds for requests to the CID API. * @const @private {number} */ const TIMEOUT_ = 30000; /** * Exposes CID API for cache-served pages without a viewer. */ export class CacheCidApi { /** @param {!./ampdoc-impl.AmpDoc} ampdoc */ constructor(ampdoc) { /** @private {!./ampdoc-impl.AmpDoc} */ this.ampdoc_ = ampdoc; /** @private {!./viewer-interface.ViewerInterface} */ this.viewer_ = Services.viewerForDoc(this.ampdoc_); /** @private {?Promise<?string>} */ this.publisherCidPromise_ = null; /** @private {!./timer-impl.Timer} */ this.timer_ = Services.timerFor(this.ampdoc_.win); } /** * Returns true if the page is embedded in CCT and is served by a proxy. * @return {boolean} */ isSupported() { return this.viewer_.isCctEmbedded() && this.viewer_.isProxyOrigin(); } /** * Returns scoped CID retrieved from the Viewer. * @param {string} scope * @return {!Promise<?string>} */ getScopedCid(scope) { if (!this.viewer_.isCctEmbedded()) { return /** @type {!Promise<?string>} */ (Promise.resolve(null)); } if (!this.publisherCidPromise_) { const url = CACHE_API_URL + SERVICE_KEY_; this.publisherCidPromise_ = this.fetchCid_(url); } return this.publisherCidPromise_.then((publisherCid) => { return publisherCid ? this.scopeCid_(publisherCid, scope) : null; }); } /** * Returns scoped CID retrieved from the Viewer. * @param {string} url * @param {boolean=} useAlternate * @return {!Promise<?string>} */ fetchCid_(url, useAlternate = true) { const payload = { 'publisherOrigin': getSourceOrigin(this.ampdoc_.win.location), }; // Make the XHR request to the cache endpoint. const timeoutMessage = 'fetchCidTimeout'; return this.timer_ .timeoutPromise( TIMEOUT_, Services.xhrFor(this.ampdoc_.win).fetchJson(url, { method: 'POST', ampCors: false, credentials: 'include', mode: 'cors', body: payload, }), timeoutMessage ) .then((res) => { return res.json().then((response) => { if (response['optOut']) { return null; } const cid = response['publisherClientId']; if (!cid && useAlternate && response['alternateUrl']) { // If an alternate url is provided, try again with the alternate url // The client is still responsible for appending API keys to the URL. const alt = `${response['alternateUrl']}?key=${SERVICE_KEY_}`; return this.fetchCid_(dev().assertString(alt), false); } return cid; }); }) .catch((e) => { if (e && e.response) { e.response.json().then((res) => { dev().error(TAG_, JSON.stringify(res)); }); } else { const isTimeout = e && e.message == timeoutMessage; if (isTimeout) { dev().expectedError(TAG_, e); } else { dev().error(TAG_, e); } } return null; }); } /** * Returns scoped CID extracted from the fetched publisherCid. * @param {string} publisherCid * @param {string} scope * @return {!Promise<string>} */ scopeCid_(publisherCid, scope) { const text = publisherCid + ';' + scope; return Services.cryptoFor(this.ampdoc_.win) .sha384Base64(text) .then((enc) => { return 'amp-' + enc; }); } }