mirror of
https://github.com/tenrok/axios.git
synced 2026-06-20 20:00:40 +03:00
fix(progress): clamp loaded to total for computable upload/download events (#7458)
* fix(progress): clamp loaded value to total in progress reducer * test(progress): cover out-of-order events in reducer clamp case * fix(progress): keep bytesNotified monotonic for out-of-order events --------- Co-authored-by: Jay <jasonsaayman@gmail.com>
This commit is contained in:
@@ -7,13 +7,13 @@ export const progressEventReducer = (listener, isDownloadStream, freq = 3) => {
|
|||||||
const _speedometer = speedometer(50, 250);
|
const _speedometer = speedometer(50, 250);
|
||||||
|
|
||||||
return throttle((e) => {
|
return throttle((e) => {
|
||||||
const loaded = e.loaded;
|
const rawLoaded = e.loaded;
|
||||||
const total = e.lengthComputable ? e.total : undefined;
|
const total = e.lengthComputable ? e.total : undefined;
|
||||||
const progressBytes = loaded - bytesNotified;
|
const loaded = total != null ? Math.min(rawLoaded, total) : rawLoaded;
|
||||||
|
const progressBytes = Math.max(0, loaded - bytesNotified);
|
||||||
const rate = _speedometer(progressBytes);
|
const rate = _speedometer(progressBytes);
|
||||||
const inRange = loaded <= total;
|
|
||||||
|
|
||||||
bytesNotified = loaded;
|
bytesNotified = Math.max(bytesNotified, loaded);
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
loaded,
|
loaded,
|
||||||
@@ -21,7 +21,7 @@ export const progressEventReducer = (listener, isDownloadStream, freq = 3) => {
|
|||||||
progress: total ? loaded / total : undefined,
|
progress: total ? loaded / total : undefined,
|
||||||
bytes: progressBytes,
|
bytes: progressBytes,
|
||||||
rate: rate ? rate : undefined,
|
rate: rate ? rate : undefined,
|
||||||
estimated: rate && total && inRange ? (total - loaded) / rate : undefined,
|
estimated: rate && total ? (total - loaded) / rate : undefined,
|
||||||
event: e,
|
event: e,
|
||||||
lengthComputable: total != null,
|
lengthComputable: total != null,
|
||||||
[isDownloadStream ? 'download' : 'upload']: true,
|
[isDownloadStream ? 'download' : 'upload']: true,
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import assert from 'assert';
|
||||||
|
import { progressEventReducer } from '../../../lib/helpers/progressEventReducer.js';
|
||||||
|
|
||||||
|
describe('helpers::progressEventReducer', () => {
|
||||||
|
it('should clamp loaded/progress and avoid negative bytes for out-of-order events', () => {
|
||||||
|
const events = [];
|
||||||
|
const [onProgress, flush] = progressEventReducer((data) => {
|
||||||
|
events.push(data);
|
||||||
|
}, false, Number.POSITIVE_INFINITY);
|
||||||
|
|
||||||
|
onProgress({ lengthComputable: true, loaded: 80, total: 100 });
|
||||||
|
onProgress({ lengthComputable: true, loaded: 60, total: 100 });
|
||||||
|
onProgress({ lengthComputable: true, loaded: 180, total: 100 });
|
||||||
|
flush();
|
||||||
|
|
||||||
|
assert.strictEqual(events.length, 3);
|
||||||
|
assert.strictEqual(events[0].bytes, 80);
|
||||||
|
assert.strictEqual(events[1].bytes, 0);
|
||||||
|
|
||||||
|
const last = events[events.length - 1];
|
||||||
|
assert.strictEqual(last.loaded, 100);
|
||||||
|
assert.strictEqual(last.total, 100);
|
||||||
|
assert.strictEqual(last.progress, 1);
|
||||||
|
assert.strictEqual(last.upload, true);
|
||||||
|
assert.strictEqual(last.bytes, 20);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user