glean/src/platform/browser/sendbeacon_fallback_uploader.ts (33 lines of code) (raw):

/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import type PingRequest from "../../core/upload/ping_request.js"; import log, { LoggingLevel } from "../../core/log.js"; import Uploader from "../../core/upload/uploader.js"; import BrowserFetchUploader from "./fetch_uploader.js"; import BrowserSendBeaconUploader from "./sendbeacon_uploader.js"; import { UploadResultStatus } from "../../core/upload/uploader.js"; import type { UploadResult } from "../../core/upload/uploader.js"; import { Context } from "../../core/context.js"; const LOG_TAG = "platform.browser.SendBeaconFallbackUploader"; class BrowserSendBeaconFallbackUploader extends Uploader { fetchUploader = BrowserFetchUploader; sendBeaconUploader = BrowserSendBeaconUploader; // eslint-disable-next-line @typescript-eslint/require-await async post( url: string, pingRequest: PingRequest<string | Uint8Array> ): Promise<UploadResult> { // Some options require us to submit custom headers. Unfortunately not all the // uploaders support them (e.g. `sendBeacon`). In case headers are required, switch // back to the `fetch` uploader that supports headers. // Then try `sendBeacon` first, // fall back to `fetch` if `sendBeacon` reports an error or `sendBeacon` is // not defined. const hasNoCustomHeaders = !Context.config?.sourceTags && !Context.config?.debugViewTag; if (hasNoCustomHeaders && !!navigator && !!navigator.sendBeacon) { const beaconStatus = await this.sendBeaconUploader.post(url, pingRequest, false); if (beaconStatus.result == UploadResultStatus.Success) { return beaconStatus; } log(LOG_TAG, "The `sendBeacon` call was not serviced by the browser. Falling back to the `fetch` uploader.", LoggingLevel.Warn); } else { log(LOG_TAG, "`sendBeacon` is not available. Falling back to the `fetch` uploader.", LoggingLevel.Warn); } return this.fetchUploader.post(url, pingRequest); } supportsCustomHeaders(): boolean { return false; } } export default new BrowserSendBeaconFallbackUploader();