Explorar o código

Merge pull request #820 from EmanuelPeixoto/fix-upload-http-status

Fix upload-speed inflation on HTTP errors and document request body limits
sstidl hai 10 horas
pai
achega
1af6517eb9
Modificáronse 2 ficheiros con 41 adicións e 8 borrados
  1. 23 0
      doc.md
  2. 18 8
      speedtest_worker.js

+ 23 - 0
doc.md

@@ -60,6 +60,29 @@ Let's install the speed test.
 
 Put all files on your web server via FTP or by copying them directly. You can install it in the root, or in a subdirectory.
 
+**Web server upload limit:** The upload test sends POST requests up to 20 MB (configurable with `xhr_ul_blob_megabytes`). Without proper configuration, the server will reject these with HTTP 413, causing wildly inaccurate upload speeds. Configure your web server to accept large request bodies:
+
+Nginx:
+```
+client_max_body_size 128m;
+```
+
+Apache:
+```
+LimitRequestBody 134217728
+```
+
+IIS: Add the following to `web.config` (value is in bytes):
+```xml
+<system.webServer>
+  <security>
+    <requestFiltering>
+      <requestLimits maxAllowedContentLength="134217728" />
+    </requestFiltering>
+  </security>
+</system.webServer>
+```
+
 __Important:__ The speed test needs write permissions in the installation folder!
 
 #### ipinfo.io

+ 18 - 8
speedtest_worker.js

@@ -502,18 +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() {
+							// 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