fix upload race: use captured x in onload, remove upload.onload restart

- xhr.onload now owns the complete lifecycle: checks x.status on
  the captured local variable, restarts only on 2xx.
- xhr.upload.onload no longer calls testStream() to avoid race
  with xhr.onload overwriting xhr[i] before status is read.
- xhr.upload.onerror also uses the captured x for consistency.
This commit is contained in:
EmanuelPeixoto 2026-07-28 16:10:41 -03:00
parent 2afc380e19
commit 397308de03

View file

@ -502,28 +502,28 @@ function ulTest(done) {
prevLoaded = event.loaded;
}.bind(this);
xhr[i].upload.onload = function() {
// this stream sent all the garbage data, start again
tverb("ul stream finished " + i);
testStream(i, 0);
// body uploaded, but response not yet available.
// xhr.onload below handles the full lifecycle.
}.bind(this);
xhr[i].upload.onerror = function() {
tverb("ul stream failed " + i);
if (settings.xhr_ignoreErrors === 0) failed = true; //abort
try {
xhr[i].abort();
} catch (e) {}
if (settings.xhr_ignoreErrors === 0) failed = true;
try { x.abort(); } catch (e) {}
delete xhr[i];
if (settings.xhr_ignoreErrors === 1) testStream(i, 0); //restart stream
if (settings.xhr_ignoreErrors === 1) testStream(i, 0);
}.bind(this);
xhr[i].onload = function() {
// check HTTP status after full response is available
if (xhr[i].status >= 200 && xhr[i].status < 300) return;
tverb("ul stream failed with HTTP " + xhr[i].status + " " + i);
if (settings.xhr_ignoreErrors === 0) failed = true; //abort
try {
xhr[i].abort();
} catch (e) {}
delete xhr[i];
// response complete — check status on captured x, not xhr[i]
if (x.status >= 200 && x.status < 300) {
tverb("ul stream finished " + i);
testStream(i, 0);
} else {
tverb("ul stream failed with HTTP " + x.status + " " + i);
if (settings.xhr_ignoreErrors === 0) failed = true;
try { x.abort(); } catch (e) {}
delete xhr[i];
if (settings.xhr_ignoreErrors === 1) testStream(i, 0);
}
}.bind(this);
// send xhr
xhr[i].open("POST", settings.url_ul + url_sep(settings.url_ul) + (settings.mpot ? "cors=true&" : "") + "r=" + Math.random(), true); // random string to prevent caching