22 * License, v. 2.0. If a copy of the MPL was not distributed with this
33 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44
5- import { gzipSync , strToU8 } from "fflate" ;
6-
75import type { QueuedPing } from "./manager.js" ;
86import type Uploader from "./uploader.js" ;
97import type { UploadTask } from "./task.js" ;
@@ -14,17 +12,11 @@ import Policy from "./policy.js";
1412import { UploadResult , UploadResultStatus } from "./uploader.js" ;
1513import { UploadTaskTypes } from "./task.js" ;
1614import { GLEAN_VERSION } from "../constants.js" ;
15+ import { PingBodyOverflowError } from "./ping_body_overflow_error.js" ;
16+ import PingRequest from "./ping_request.js" ;
1717
1818const PING_UPLOAD_WORKER_LOG_TAG = "core.Upload.PingUploadWorker" ;
1919
20- // Error to be thrown in case the final ping body is larger than MAX_PING_BODY_SIZE.
21- class PingBodyOverflowError extends Error {
22- constructor ( message ?: string ) {
23- super ( message ) ;
24- this . name = "PingBodyOverflow" ;
25- }
26- }
27-
2820class PingUploadWorker {
2921 // Whether or not someone is blocking on the currentJob.
3022 isBlocking = false ;
@@ -47,10 +39,7 @@ class PingUploadWorker {
4739 * @param ping The ping to include the headers in.
4840 * @returns The updated ping.
4941 */
50- private buildPingRequest ( ping : QueuedPing ) : {
51- headers : Record < string , string > ;
52- payload : string | Uint8Array ;
53- } {
42+ private buildPingRequest ( ping : QueuedPing ) : PingRequest < string | Uint8Array > {
5443 let headers = ping . headers || { } ;
5544 headers = {
5645 ...ping . headers ,
@@ -60,33 +49,15 @@ class PingUploadWorker {
6049 } ;
6150
6251 const stringifiedBody = JSON . stringify ( ping . payload ) ;
63- // We prefer using `strToU8` instead of TextEncoder directly,
64- // because it will polyfill TextEncoder if it's not present in the environment.
65- // Environments that don't provide TextEncoder are IE and most importantly QML.
66- const encodedBody = strToU8 ( stringifiedBody ) ;
67-
68- let finalBody : string | Uint8Array ;
69- let bodySizeInBytes : number ;
70- try {
71- finalBody = gzipSync ( encodedBody ) ;
72- bodySizeInBytes = finalBody . length ;
73- headers [ "Content-Encoding" ] = "gzip" ;
74- } catch {
75- finalBody = stringifiedBody ;
76- bodySizeInBytes = encodedBody . length ;
77- }
7852
79- if ( bodySizeInBytes > this . policy . maxPingBodySize ) {
53+ if ( stringifiedBody . length > this . policy . maxPingBodySize ) {
8054 throw new PingBodyOverflowError (
8155 `Body for ping ${ ping . identifier } exceeds ${ this . policy . maxPingBodySize } bytes. Discarding.`
8256 ) ;
8357 }
8458
85- headers [ "Content-Length" ] = bodySizeInBytes . toString ( ) ;
86- return {
87- headers,
88- payload : finalBody
89- } ;
59+ headers [ "Content-Length" ] = stringifiedBody . length . toString ( ) ;
60+ return new PingRequest ( ping . identifier , headers , stringifiedBody , this . policy . maxPingBodySize ) ;
9061 }
9162
9263 /**
@@ -99,12 +70,24 @@ class PingUploadWorker {
9970 try {
10071 const finalPing = this . buildPingRequest ( ping ) ;
10172
73+ let safeUploader = this . uploader ;
74+ if ( ! this . uploader . supportsCustomHeaders ( ) ) {
75+ // Some options require us to submit custom headers. Unfortunately not all the
76+ // uploaders support them (e.g. `sendBeacon`). In case headers are required, switch
77+ // back to the default uploader that, for now, supports headers.
78+ const needsHeaders = ! (
79+ ( Context . config . sourceTags === undefined ) && ( Context . config . debugViewTag === undefined )
80+ ) ;
81+ if ( needsHeaders ) {
82+ safeUploader = Context . platform . uploader ;
83+ }
84+ }
85+
10286 // The POST call has to be asynchronous. Once the API call is triggered,
10387 // we rely on the browser's "keepalive" header.
104- return this . uploader . post (
88+ return safeUploader . post (
10589 `${ this . serverEndpoint } ${ ping . path } ` ,
106- finalPing . payload ,
107- finalPing . headers
90+ finalPing
10891 ) ;
10992 } catch ( e ) {
11093 log (
0 commit comments