| 238 | } |
| 239 | |
| 240 | _post(batch, bytes) { |
| 241 | let attempts = 0; |
| 242 | |
| 243 | return new Promise((resolve, reject) => { |
| 244 | const sendRequest = (batch, bytes) => { |
| 245 | const controller = new safeGlobalAbortController(); |
| 246 | attempts++; |
| 247 | const timerId = setTimeout(() => { |
| 248 | controller.abort(); |
| 249 | if (attempts > this._maxRetries) { |
| 250 | reject('HTTP log shipping failed, reached timeout (' + this._requestTimeout + ' ms)'); |
| 251 | } else { |
| 252 | setTimeout(() => sendRequest(batch, bytes), this._retryDelay); |
| 253 | } |
| 254 | }, this._requestTimeout); |
| 255 | |
| 256 | safeGlobalFetch(this._endpoint, { |
| 257 | keepalive: true, |
| 258 | method: "POST", |
| 259 | headers: { |
| 260 | "Content-Type": "application/json", |
| 261 | "X-Seq-ApiKey": this._apiKey ? this._apiKey : null, |
| 262 | "Content-Length": bytes, |
| 263 | }, |
| 264 | body: `${HEADER}${batch.join(',')}${FOOTER}`, |
| 265 | signal: controller.signal, |
| 266 | }) |
| 267 | .then((res) => { |
| 268 | clearTimeout(timerId); |
| 269 | let httpErr = null; |
| 270 | if (res.status !== 200 && res.status !== 201) { |
| 271 | httpErr = 'HTTP log shipping failed: ' + res.status; |
| 272 | if (this._httpOrNetworkError(res) && attempts < this._maxRetries) { |
| 273 | return setTimeout(() => sendRequest(batch, bytes), this._retryDelay); |
| 274 | } |
| 275 | return reject(httpErr); |
| 276 | } |
| 277 | return resolve(true); |
| 278 | }) |
| 279 | .catch((err) => { |
| 280 | clearTimeout(timerId); |
| 281 | reject(err); |
| 282 | }) |
| 283 | } |
| 284 | |
| 285 | return sendRequest(batch, bytes); |
| 286 | }); |
| 287 | } |
| 288 | } |
| 289 | |
| 290 | |