From 6517ee346256138a7487bb559f46623e6646f230 Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Fri, 22 Jul 2016 13:32:37 -0700 Subject: [PATCH] Backed out 6 changesets (bug 1244227) for m(cl) failures Backed out changeset 0cf1259b7073 (bug 1244227) Backed out changeset d5866b9dd3d9 (bug 1244227) Backed out changeset 49b5309e3415 (bug 1244227) Backed out changeset 33bc49f015a7 (bug 1244227) Backed out changeset f680f6460f07 (bug 1244227) Backed out changeset 5a4bb3258978 (bug 1244227) --- .../client/netmonitor/har/test/browser.ini | 1 - .../test/browser_net_har_throttle_upload.js | 60 --- .../test/html_har_post-data-test-page.html | 6 - devtools/client/netmonitor/test/browser.ini | 1 - .../netmonitor/test/browser_net_throttle.js | 53 --- .../test/html_har_post-data-test-page.html | 33 ++ devtools/client/webconsole/webconsole.js | 31 -- devtools/server/actors/webconsole.js | 17 +- devtools/shared/webconsole/moz.build | 1 - devtools/shared/webconsole/network-monitor.js | 244 +++++------ .../webconsole/test/unit/test_throttle.js | 140 ------ .../shared/webconsole/test/unit/xpcshell.ini | 1 - devtools/shared/webconsole/throttle.js | 400 ------------------ netwerk/base/ThrottleQueue.cpp | 392 ----------------- netwerk/base/ThrottleQueue.h | 65 --- netwerk/base/moz.build | 2 - netwerk/base/nsIThrottledInputChannel.idl | 80 ---- netwerk/build/nsNetCID.h | 10 - netwerk/build/nsNetModule.cpp | 5 - netwerk/protocol/http/HttpBaseChannel.cpp | 23 - netwerk/protocol/http/HttpBaseChannel.h | 5 - netwerk/protocol/http/nsHttpTransaction.cpp | 21 - netwerk/test/unit/test_throttlechannel.js | 41 -- netwerk/test/unit/test_throttlequeue.js | 23 - netwerk/test/unit/test_throttling.js | 57 --- netwerk/test/unit/xpcshell.ini | 3 - 26 files changed, 147 insertions(+), 1568 deletions(-) delete mode 100644 devtools/client/netmonitor/har/test/browser_net_har_throttle_upload.js delete mode 100644 devtools/client/netmonitor/test/browser_net_throttle.js create mode 100644 devtools/client/netmonitor/test/html_har_post-data-test-page.html delete mode 100644 devtools/shared/webconsole/test/unit/test_throttle.js delete mode 100644 devtools/shared/webconsole/throttle.js delete mode 100644 netwerk/base/ThrottleQueue.cpp delete mode 100644 netwerk/base/ThrottleQueue.h delete mode 100644 netwerk/base/nsIThrottledInputChannel.idl delete mode 100644 netwerk/test/unit/test_throttlechannel.js delete mode 100644 netwerk/test/unit/test_throttlequeue.js delete mode 100644 netwerk/test/unit/test_throttling.js diff --git a/devtools/client/netmonitor/har/test/browser.ini b/devtools/client/netmonitor/har/test/browser.ini index 14d4f846fad3..6923c64f3c37 100644 --- a/devtools/client/netmonitor/har/test/browser.ini +++ b/devtools/client/netmonitor/har/test/browser.ini @@ -9,4 +9,3 @@ support-files = [browser_net_har_copy_all_as_har.js] [browser_net_har_post_data.js] -[browser_net_har_throttle_upload.js] diff --git a/devtools/client/netmonitor/har/test/browser_net_har_throttle_upload.js b/devtools/client/netmonitor/har/test/browser_net_har_throttle_upload.js deleted file mode 100644 index 51ec10a3b637..000000000000 --- a/devtools/client/netmonitor/har/test/browser_net_har_throttle_upload.js +++ /dev/null @@ -1,60 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -// Test timing of upload when throttling. - -"use strict"; - -add_task(function* () { - let [ , debuggee, monitor ] = yield initNetMonitor( - HAR_EXAMPLE_URL + "html_har_post-data-test-page.html"); - - info("Starting test... "); - - let { NetMonitorView } = monitor.panelWin; - let { RequestsMenu } = NetMonitorView; - - const size = 4096; - const request = { - "NetworkMonitor.throttleData": { - roundTripTimeMean: 0, - roundTripTimeMax: 0, - downloadBPSMean: 200000, - downloadBPSMax: 200000, - uploadBPSMean: size / 3, - uploadBPSMax: size / 3, - }, - }; - let client = monitor._controller.webConsoleClient; - - info("sending throttle request"); - let deferred = promise.defer(); - client.setPreferences(request, response => { - deferred.resolve(response); - }); - yield deferred.promise; - - RequestsMenu.lazyUpdate = false; - - // Execute one POST request on the page and wait till its done. - debuggee.executeTest2(size); - yield waitForNetworkEvents(monitor, 0, 1); - - // Copy HAR into the clipboard (asynchronous). - let jsonString = yield RequestsMenu.copyAllAsHar(); - let har = JSON.parse(jsonString); - - // Check out the HAR log. - isnot(har.log, null, "The HAR log must exist"); - is(har.log.pages.length, 1, "There must be one page"); - is(har.log.entries.length, 1, "There must be one request"); - - let entry = har.log.entries[0]; - is(entry.request.postData.text, "x".repeat(size), - "Check post data payload"); - - ok(entry.timings.send >= 2000, "upload should have taken more than 2 seconds"); - - // Clean up - teardown(monitor).then(finish); -}); diff --git a/devtools/client/netmonitor/har/test/html_har_post-data-test-page.html b/devtools/client/netmonitor/har/test/html_har_post-data-test-page.html index 816dad08efc1..6cc4efa84ddb 100644 --- a/devtools/client/netmonitor/har/test/html_har_post-data-test-page.html +++ b/devtools/client/netmonitor/har/test/html_har_post-data-test-page.html @@ -27,12 +27,6 @@ var data = "{'first': 'John', 'last': 'Doe'}"; post(url, data); } - - function executeTest2(size) { - var url = "html_har_post-data-test-page.html"; - var data = "x".repeat(size); - post(url, data); - } diff --git a/devtools/client/netmonitor/test/browser.ini b/devtools/client/netmonitor/test/browser.ini index f2f07092431e..7408d14f30e9 100644 --- a/devtools/client/netmonitor/test/browser.ini +++ b/devtools/client/netmonitor/test/browser.ini @@ -138,7 +138,6 @@ skip-if = (e10s && debug && os == 'mac') # Bug 1253037 [browser_net_statistics-03.js] [browser_net_status-codes.js] [browser_net_streaming-response.js] -[browser_net_throttle.js] [browser_net_timeline_ticks.js] [browser_net_timing-division.js] [browser_net_persistent_logs.js] diff --git a/devtools/client/netmonitor/test/browser_net_throttle.js b/devtools/client/netmonitor/test/browser_net_throttle.js deleted file mode 100644 index deefd1b4822e..000000000000 --- a/devtools/client/netmonitor/test/browser_net_throttle.js +++ /dev/null @@ -1,53 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -// Network throttling integration test. - -"use strict"; - -add_task(function* () { - requestLongerTimeout(2); - - let [, , monitor] = yield initNetMonitor(SIMPLE_URL); - const {ACTIVITY_TYPE, NetMonitorController, NetMonitorView} = - monitor.panelWin; - - info("Starting test... "); - - const request = { - "NetworkMonitor.throttleData": { - roundTripTimeMean: 0, - roundTripTimeMax: 0, - // Must be smaller than the length of the content of SIMPLE_URL - // in bytes. - downloadBPSMean: 200, - downloadBPSMax: 200, - uploadBPSMean: 10000, - uploadBPSMax: 10000, - }, - }; - let client = monitor._controller.webConsoleClient; - - info("sending throttle request"); - let deferred = promise.defer(); - client.setPreferences(request, response => { - deferred.resolve(response); - }); - yield deferred.promise; - - const startTime = Date.now(); - let eventPromise = - monitor.panelWin.once(monitor.panelWin.EVENTS.RECEIVED_EVENT_TIMINGS); - yield NetMonitorController - .triggerActivity(ACTIVITY_TYPE.RELOAD.WITH_CACHE_DISABLED); - const endTime = Date.now(); - ok(endTime - startTime > 1000, "download took more than one second"); - - yield eventPromise; - let requestItem = NetMonitorView.RequestsMenu.getItemAtIndex(0); - ok(requestItem.attachment.eventTimings.timings.receive > 1000, - "download reported as taking more than one second"); - - yield teardown(monitor); - finish(); -}); diff --git a/devtools/client/netmonitor/test/html_har_post-data-test-page.html b/devtools/client/netmonitor/test/html_har_post-data-test-page.html new file mode 100644 index 000000000000..050ea55d1106 --- /dev/null +++ b/devtools/client/netmonitor/test/html_har_post-data-test-page.html @@ -0,0 +1,33 @@ + + + + + + + + + + Network Monitor Test Page + + + +

HAR POST data test

+ + + + + diff --git a/devtools/client/webconsole/webconsole.js b/devtools/client/webconsole/webconsole.js index ac78fdd0c729..417cf05605a7 100644 --- a/devtools/client/webconsole/webconsole.js +++ b/devtools/client/webconsole/webconsole.js @@ -387,7 +387,6 @@ WebConsoleFrame.prototype = { _destroyer: null, _saveRequestAndResponseBodies: true, - _throttleData: null, // Chevron width at the starting of Web Console's input box. _chevronWidth: 0, @@ -425,36 +424,6 @@ WebConsoleFrame.prototype = { return deferred.promise; }, - /** - * Setter for throttling data. - * - * @param boolean value - * The new value you want to set; @see NetworkThrottleManager. - */ - setThrottleData: function(value) { - if (!this.webConsoleClient) { - // Don't continue if the webconsole disconnected. - return promise.resolve(null); - } - - let deferred = promise.defer(); - let toSet = { - "NetworkMonitor.throttleData": value, - }; - - // Make sure the web console client connection is established first. - this.webConsoleClient.setPreferences(toSet, response => { - if (!response.error) { - this._throttleData = value; - deferred.resolve(response); - } else { - deferred.reject(response.error); - } - }); - - return deferred.promise; - }, - /** * Getter for the persistent logging preference. * @type boolean diff --git a/devtools/server/actors/webconsole.js b/devtools/server/actors/webconsole.js index 83fba08f9734..bd999f8145aa 100644 --- a/devtools/server/actors/webconsole.js +++ b/devtools/server/actors/webconsole.js @@ -1054,18 +1054,11 @@ WebConsoleActor.prototype = for (let key in aRequest.preferences) { this._prefs[key] = aRequest.preferences[key]; - if (this.networkMonitor) { - if (key == "NetworkMonitor.saveRequestAndResponseBodies") { - this.networkMonitor.saveRequestAndResponseBodies = this._prefs[key]; - if (this.networkMonitorChild) { - this.networkMonitorChild.saveRequestAndResponseBodies = - this._prefs[key]; - } - } else if (key == "NetworkMonitor.throttleData") { - this.networkMonitor.throttleData = this._prefs[key]; - if (this.networkMonitorChild) { - this.networkMonitorChild.throttleData = this._prefs[key]; - } + if (key == "NetworkMonitor.saveRequestAndResponseBodies" && + this.networkMonitor) { + this.networkMonitor.saveRequestAndResponseBodies = this._prefs[key]; + if (this.networkMonitorChild) { + this.networkMonitorChild.saveRequestAndResponseBodies = this._prefs[key]; } } } diff --git a/devtools/shared/webconsole/moz.build b/devtools/shared/webconsole/moz.build index 424d2540299a..49f9cf8a5554 100644 --- a/devtools/shared/webconsole/moz.build +++ b/devtools/shared/webconsole/moz.build @@ -15,7 +15,6 @@ DevToolsModules( 'network-monitor.js', 'server-logger-monitor.js', 'server-logger.js', - 'throttle.js', 'utils.js', 'worker-utils.js', ) diff --git a/devtools/shared/webconsole/network-monitor.js b/devtools/shared/webconsole/network-monitor.js index e86b2f21194c..4680eee6e320 100644 --- a/devtools/shared/webconsole/network-monitor.js +++ b/devtools/shared/webconsole/network-monitor.js @@ -18,7 +18,6 @@ loader.lazyImporter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm"); loader.lazyServiceGetter(this, "gActivityDistributor", "@mozilla.org/network/http-activity-distributor;1", "nsIHttpActivityDistributor"); -const {NetworkThrottleManager} = require("devtools/shared/webconsole/throttle"); // ///////////////////////////////////////////////////////////////////////////// // Network logging @@ -303,12 +302,50 @@ function NetworkResponseListener(owner, httpActivity) { this.receivedData = ""; this.httpActivity = httpActivity; this.bodySize = 0; + let channel = this.httpActivity.channel; + this._wrappedNotificationCallbacks = channel.notificationCallbacks; + channel.notificationCallbacks = this; } NetworkResponseListener.prototype = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIStreamListener, Ci.nsIInputStreamCallback, - Ci.nsIRequestObserver, Ci.nsISupports]), + Ci.nsIRequestObserver, Ci.nsIInterfaceRequestor, + Ci.nsISupports]), + + // nsIInterfaceRequestor implementation + + /** + * This object implements nsIProgressEventSink, but also needs to forward + * interface requests to the notification callbacks of other objects. + */ + getInterface(iid) { + if (iid.equals(Ci.nsIProgressEventSink)) { + return this; + } + if (this._wrappedNotificationCallbacks) { + return this._wrappedNotificationCallbacks.getInterface(iid); + } + throw Cr.NS_ERROR_NO_INTERFACE; + }, + + /** + * Forward notifications for interfaces this object implements, in case other + * objects also implemented them. + */ + _forwardNotification(iid, method, args) { + if (!this._wrappedNotificationCallbacks) { + return; + } + try { + let impl = this._wrappedNotificationCallbacks.getInterface(iid); + impl[method].apply(impl, args); + } catch (e) { + if (e.result != Cr.NS_ERROR_NO_INTERFACE) { + throw e; + } + } + }, /** * This NetworkResponseListener tracks the NetworkMonitor.openResponses object @@ -317,6 +354,12 @@ NetworkResponseListener.prototype = { */ _foundOpenResponse: false, + /** + * If the channel already had notificationCallbacks, hold them here internally + * so that we can forward getInterface requests to that object. + */ + _wrappedNotificationCallbacks: null, + /** * The response listener owner. */ @@ -413,6 +456,9 @@ NetworkResponseListener.prototype = { this.request = request; this._getSecurityInfo(); this._findOpenResponse(); + // We need to track the offset for the onDataAvailable calls where + // we pass the data from our pipe to the coverter. + this.offset = 0; // In the multi-process mode, the conversion happens on the child // side while we can only monitor the channel on the parent @@ -473,6 +519,23 @@ NetworkResponseListener.prototype = { this.sink.outputStream.close(); }, + // nsIProgressEventSink implementation + + /** + * Handle progress event as data is transferred. This is used to record the + * size on the wire, which may be compressed / encoded. + */ + onProgress: function (request, context, progress, progressMax) { + this.transferredSize = progress; + // Need to forward as well to keep things like Download Manager's progress + // bar working properly. + this._forwardNotification(Ci.nsIProgressEventSink, "onProgress", arguments); + }, + + onStatus: function () { + this._forwardNotification(Ci.nsIProgressEventSink, "onStatus", arguments); + }, + /** * Find the open response object associated to the current request. The * NetworkMonitor._httpResponseExaminer() method saves the response headers in @@ -580,6 +643,9 @@ NetworkResponseListener.prototype = { this.httpActivity.discardResponseBody ); + this._wrappedNotificationCallbacks = null; + this.httpActivity.channel = null; + this.httpActivity.owner = null; this.httpActivity = null; this.sink = null; this.inputStream = null; @@ -610,23 +676,20 @@ NetworkResponseListener.prototype = { } if (available != -1) { - if (this.transferredSize === null) { - this.transferredSize = 0; - } - if (available != 0) { if (this.converter) { this.converter.onDataAvailable(this.request, null, stream, - this.transferredSize, available); + this.offset, available); } else { - this.onDataAvailable(this.request, null, stream, this.transferredSize, + this.onDataAvailable(this.request, null, stream, this.offset, available); } } - this.transferredSize += available; + this.offset += available; this.setAsyncListener(stream, this); } else { this.onStreamClose(); + this.offset = 0; } }, }; @@ -666,11 +729,7 @@ function NetworkMonitor(filters, owner) { this.openResponses = {}; this._httpResponseExaminer = DevToolsUtils.makeInfallible(this._httpResponseExaminer).bind(this); - this._httpModifyExaminer = - DevToolsUtils.makeInfallible(this._httpModifyExaminer).bind(this); this._serviceWorkerRequest = this._serviceWorkerRequest.bind(this); - this.throttleData = null; - this._throttler = null; } exports.NetworkMonitor = NetworkMonitor; @@ -695,13 +754,6 @@ NetworkMonitor.prototype = { 0x804b0006: "STATUS_RECEIVING_FROM" }, - httpDownloadActivities: [ - gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_START, - gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_HEADER, - gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_COMPLETE, - gActivityDistributor.ACTIVITY_SUBTYPE_TRANSACTION_CLOSE - ], - // Network response bodies are piped through a buffer of the given size (in // bytes). responsePipeSegmentSize: null, @@ -738,8 +790,6 @@ NetworkMonitor.prototype = { "http-on-examine-response", false); Services.obs.addObserver(this._httpResponseExaminer, "http-on-examine-cached-response", false); - Services.obs.addObserver(this._httpModifyExaminer, - "http-on-modify-request", false); } // In child processes, only watch for service worker requests // everything else only happens in the parent process @@ -747,13 +797,6 @@ NetworkMonitor.prototype = { "service-worker-synthesized-response", false); }, - _getThrottler: function () { - if (this.throttleData !== null && this._throttler === null) { - this._throttler = new NetworkThrottleManager(this.throttleData); - } - return this._throttler; - }, - _serviceWorkerRequest: function (subject, topic, data) { let channel = subject.QueryInterface(Ci.nsIHttpChannel); @@ -868,62 +911,6 @@ NetworkMonitor.prototype = { } }, - /** - * Observe notifications for the http-on-modify-request topic, coming from - * the nsIObserverService. - * - * @private - * @param nsIHttpChannel aSubject - * @returns void - */ - _httpModifyExaminer: function (subject) { - let throttler = this._getThrottler(); - if (throttler) { - let channel = subject.QueryInterface(Ci.nsIHttpChannel); - if (matchRequest(channel, this.filters)) { - throttler.manageUpload(channel); - } - } - }, - - /** - * A helper function for observeActivity. This does whatever work - * is required by a particular http activity event. Arguments are - * the same as for observeActivity. - */ - _dispatchActivity: function (httpActivity, channel, activityType, - activitySubtype, timestamp, extraSizeData, - extraStringData) { - let transCodes = this.httpTransactionCodes; - - // Store the time information for this activity subtype. - if (activitySubtype in transCodes) { - let stage = transCodes[activitySubtype]; - if (stage in httpActivity.timings) { - httpActivity.timings[stage].last = timestamp; - } else { - httpActivity.timings[stage] = { - first: timestamp, - last: timestamp, - }; - } - } - - switch (activitySubtype) { - case gActivityDistributor.ACTIVITY_SUBTYPE_REQUEST_BODY_SENT: - this._onRequestBodySent(httpActivity); - break; - case gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_HEADER: - this._onResponseHeader(httpActivity, extraStringData); - break; - case gActivityDistributor.ACTIVITY_SUBTYPE_TRANSACTION_CLOSE: - this._onTransactionClose(httpActivity); - break; - default: - break; - } - }, - /** * Begin observing HTTP traffic that originates inside the current tab. * @@ -973,20 +960,33 @@ NetworkMonitor.prototype = { return; } - // If we're throttling, we must not report events as they arrive - // from platform, but instead let the throttler emit the events - // after some time has elapsed. - if (httpActivity.downloadThrottle && - this.httpDownloadActivities.indexOf(activitySubtype) >= 0) { - let callback = this._dispatchActivity.bind(this); - httpActivity.downloadThrottle - .addActivityCallback(callback, httpActivity, channel, activityType, - activitySubtype, timestamp, extraSizeData, - extraStringData); - } else { - this._dispatchActivity(httpActivity, channel, activityType, - activitySubtype, timestamp, extraSizeData, - extraStringData); + let transCodes = this.httpTransactionCodes; + + // Store the time information for this activity subtype. + if (activitySubtype in transCodes) { + let stage = transCodes[activitySubtype]; + if (stage in httpActivity.timings) { + httpActivity.timings[stage].last = timestamp; + } else { + httpActivity.timings[stage] = { + first: timestamp, + last: timestamp, + }; + } + } + + switch (activitySubtype) { + case gActivityDistributor.ACTIVITY_SUBTYPE_REQUEST_BODY_SENT: + this._onRequestBodySent(httpActivity); + break; + case gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_HEADER: + this._onResponseHeader(httpActivity, extraStringData); + break; + case gActivityDistributor.ACTIVITY_SUBTYPE_TRANSACTION_CLOSE: + this._onTransactionClose(httpActivity); + break; + default: + break; } }), @@ -1081,7 +1081,7 @@ NetworkMonitor.prototype = { httpActivity.owner = this.owner.onNetworkEvent(event, channel); - this._setupResponseListener(httpActivity, fromCache); + this._setupResponseListener(httpActivity); httpActivity.owner.addRequestHeaders(headers, extraStringData); httpActivity.owner.addRequestCookies(cookies); @@ -1151,17 +1151,10 @@ NetworkMonitor.prototype = { * @param object httpActivity * The HTTP activity object we are tracking. */ - _setupResponseListener: function (httpActivity, fromCache) { + _setupResponseListener: function (httpActivity) { let channel = httpActivity.channel; channel.QueryInterface(Ci.nsITraceableChannel); - if (!fromCache) { - let throttler = this._getThrottler(); - if (throttler) { - httpActivity.downloadThrottle = throttler.manage(channel); - } - } - // The response will be written into the outputStream of this pipe. // This allows us to buffer the data we are receiving and read it // asynchronously. @@ -1344,10 +1337,12 @@ NetworkMonitor.prototype = { harTimings.connect = -1; } - if (timings.STATUS_SENDING_TO) { - harTimings.send = timings.STATUS_SENDING_TO.last - timings.STATUS_SENDING_TO.first; - } else if (timings.REQUEST_HEADER && timings.REQUEST_BODY_SENT) { - harTimings.send = timings.REQUEST_BODY_SENT.last - timings.REQUEST_HEADER.first; + if ((timings.STATUS_WAITING_FOR || timings.STATUS_RECEIVING_FROM) && + (timings.STATUS_CONNECTED_TO || timings.STATUS_SENDING_TO)) { + harTimings.send = (timings.STATUS_WAITING_FOR || + timings.STATUS_RECEIVING_FROM).first - + (timings.STATUS_CONNECTED_TO || + timings.STATUS_SENDING_TO).last; } else { harTimings.send = -1; } @@ -1393,8 +1388,6 @@ NetworkMonitor.prototype = { "http-on-examine-response"); Services.obs.removeObserver(this._httpResponseExaminer, "http-on-examine-cached-response"); - Services.obs.removeObserver(this._httpModifyExaminer, - "http-on-modify-request", false); } Services.obs.removeObserver(this._serviceWorkerRequest, @@ -1405,7 +1398,6 @@ NetworkMonitor.prototype = { this.openResponses = {}; this.owner = null; this.filters = null; - this._throttler = null; }, }; @@ -1449,7 +1441,6 @@ NetworkMonitorChild.prototype = { owner: null, _netEvents: null, _saveRequestAndResponseBodies: true, - _throttleData: null, get saveRequestAndResponseBodies() { return this._saveRequestAndResponseBodies; @@ -1466,22 +1457,6 @@ NetworkMonitorChild.prototype = { }); }, - get throttleData() { - return this._throttleData; - }, - - set throttleData(val) { - this._throttleData = val; - - this._messageManager.sendAsyncMessage("debug:netmonitor:" + this.connID, { - appId: this.appId, - action: "setPreferences", - preferences: { - throttleData: this._throttleData, - }, - }); - }, - init: function () { let mm = this._messageManager; mm.addMessageListener("debug:netmonitor:" + this.connID + ":newEvent", @@ -1666,9 +1641,8 @@ NetworkMonitorManager.prototype = { case "setPreferences": { let {preferences} = msg.json; for (let key of Object.keys(preferences)) { - if ((key == "saveRequestAndResponseBodies" || - key == "throttleData") && this.netMonitor) { - this.netMonitor[key] = preferences[key]; + if (key == "saveRequestAndResponseBodies" && this.netMonitor) { + this.netMonitor.saveRequestAndResponseBodies = preferences[key]; } } break; diff --git a/devtools/shared/webconsole/test/unit/test_throttle.js b/devtools/shared/webconsole/test/unit/test_throttle.js deleted file mode 100644 index fa8b26b6189f..000000000000 --- a/devtools/shared/webconsole/test/unit/test_throttle.js +++ /dev/null @@ -1,140 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -const Cu = Components.utils; -const Cc = Components.classes; -const Ci = Components.interfaces; -const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); -const promise = require("promise"); -const { NetworkThrottleManager } = - require("devtools/shared/webconsole/throttle"); -const nsIScriptableInputStream = Ci.nsIScriptableInputStream; - -function TestStreamListener() { - this.state = "initial"; -} -TestStreamListener.prototype = { - onStartRequest: function() { - this.setState("start"); - }, - - onStopRequest: function() { - this.setState("stop"); - }, - - onDataAvailable: function(request, context, inputStream, offset, count) { - const sin = Components.classes["@mozilla.org/scriptableinputstream;1"] - .createInstance(nsIScriptableInputStream); - sin.init(inputStream); - this.data = sin.read(count); - this.setState("data"); - }, - - setState: function(state) { - this.state = state; - if (this._deferred) { - this._deferred.resolve(state); - this._deferred = null; - } - }, - - onStateChanged: function() { - if (!this._deferred) { - this._deferred = promise.defer(); - } - return this._deferred.promise; - } -}; - -function TestChannel() { - this.state = "initial"; - this.testListener = new TestStreamListener(); - this._throttleQueue = null; -} -TestChannel.prototype = { - QueryInterface: function() { - return this; - }, - - get throttleQueue() { - return this._throttleQueue; - }, - - set throttleQueue(q) { - this._throttleQueue = q; - this.state = "throttled"; - }, - - setNewListener: function(listener) { - this.listener = listener; - this.state = "listener"; - return this.testListener; - }, -}; - -add_task(function*() { - let throttler = new NetworkThrottleManager({ - roundTripTimeMean: 1, - roundTripTimeMax: 1, - downloadBPSMean: 500, - downloadBPSMax: 500, - uploadBPSMean: 500, - uploadBPSMax: 500, - }); - - let uploadChannel = new TestChannel(); - throttler.manageUpload(uploadChannel); - equal(uploadChannel.state, "throttled", - "NetworkThrottleManager set throttleQueue"); - - let downloadChannel = new TestChannel(); - let testListener = downloadChannel.testListener; - - let listener = throttler.manage(downloadChannel); - equal(downloadChannel.state, "listener", - "NetworkThrottleManager called setNewListener"); - - equal(testListener.state, "initial", "test listener in initial state"); - - // This method must be passed through immediately. - listener.onStartRequest(null, null); - equal(testListener.state, "start", "test listener started"); - - const TEST_INPUT = "hi bob"; - - let testStream = Cc["@mozilla.org/storagestream;1"] - .createInstance(Ci.nsIStorageStream); - testStream.init(512, 512); - let out = testStream.getOutputStream(0); - out.write(TEST_INPUT, TEST_INPUT.length); - out.close(); - let testInputStream = testStream.newInputStream(0); - - let activityDistributor = - Cc["@mozilla.org/network/http-activity-distributor;1"] - .getService(Ci.nsIHttpActivityDistributor); - let activitySeen = false; - listener.addActivityCallback(() => activitySeen = true, null, null, null, - activityDistributor - .ACTIVITY_SUBTYPE_RESPONSE_COMPLETE, - null, TEST_INPUT.length, null); - - // onDataAvailable is required to immediately read the data. - listener.onDataAvailable(null, null, testInputStream, 0, 6); - equal(testInputStream.available(), 0, "no more data should be available"); - equal(testListener.state, "start", - "test listener should not have received data"); - equal(activitySeen, false, "activity not distributed yet"); - - let newState = yield testListener.onStateChanged(); - equal(newState, "data", "test listener received data"); - equal(testListener.data, TEST_INPUT, "test listener received all the data"); - equal(activitySeen, true, "activity has been distributed"); - - let onChange = testListener.onStateChanged(); - listener.onStopRequest(null, null, null); - newState = yield onChange; - equal(newState, "stop", "onStateChanged reported"); -}); diff --git a/devtools/shared/webconsole/test/unit/xpcshell.ini b/devtools/shared/webconsole/test/unit/xpcshell.ini index 5aeb21f15596..a0534ee7c4fa 100644 --- a/devtools/shared/webconsole/test/unit/xpcshell.ini +++ b/devtools/shared/webconsole/test/unit/xpcshell.ini @@ -14,4 +14,3 @@ support-files = [test_security-info-state.js] [test_security-info-static-hpkp.js] [test_security-info-weakness-reasons.js] -[test_throttle.js] diff --git a/devtools/shared/webconsole/throttle.js b/devtools/shared/webconsole/throttle.js deleted file mode 100644 index 379821cd9ab4..000000000000 --- a/devtools/shared/webconsole/throttle.js +++ /dev/null @@ -1,400 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft= javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {CC, Ci, Cu, Cc} = require("chrome"); - -const ArrayBufferInputStream = CC("@mozilla.org/io/arraybuffer-input-stream;1", - "nsIArrayBufferInputStream"); -const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", - "nsIBinaryInputStream", "setInputStream"); - -loader.lazyServiceGetter(this, "gActivityDistributor", - "@mozilla.org/network/http-activity-distributor;1", - "nsIHttpActivityDistributor"); - -const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm"); -const {setTimeout} = Cu.import("resource://gre/modules/Timer.jsm", {}); - -/** - * Construct a new nsIStreamListener that buffers data and provides a - * method to notify another listener when data is available. This is - * used to throttle network data on a per-channel basis. - * - * After construction, @see setOriginalListener must be called on the - * new object. - * - * @param {NetworkThrottleQueue} queue the NetworkThrottleQueue to - * which status changes should be reported - */ -function NetworkThrottleListener(queue) { - this.queue = queue; - this.pendingData = []; - this.pendingException = null; - this.offset = 0; - this.responseStarted = false; - this.activities = {}; -} - -NetworkThrottleListener.prototype = { - QueryInterface: - XPCOMUtils.generateQI([Ci.nsIStreamListener, Ci.nsIInterfaceRequestor, - Ci.nsISupports]), - - /** - * Set the original listener for this object. The original listener - * will receive requests from this object when the queue allows data - * through. - * - * @param {nsIStreamListener} originalListener the original listener - * for the channel, to which all requests will be sent - */ - setOriginalListener: function (originalListener) { - this.originalListener = originalListener; - }, - - /** - * @see nsIStreamListener.onStartRequest. - */ - onStartRequest: function (request, context) { - this.originalListener.onStartRequest(request, context); - this.queue.start(this); - }, - - /** - * @see nsIStreamListener.onStopRequest. - */ - onStopRequest: function (request, context, statusCode) { - this.pendingData.push({request, context, statusCode}); - this.queue.dataAvailable(this); - }, - - /** - * @see nsIStreamListener.onDataAvailable. - */ - onDataAvailable: function (request, context, inputStream, offset, count) { - if (this.pendingException) { - throw this.pendingException; - } - - const bin = new BinaryInputStream(inputStream); - const bytes = new ArrayBuffer(count); - bin.readArrayBuffer(count, bytes); - - const stream = new ArrayBufferInputStream(); - stream.setData(bytes, 0, count); - - this.pendingData.push({request, context, stream, count}); - this.queue.dataAvailable(this); - }, - - /** - * Allow some buffered data from this object to be forwarded to this - * object's originalListener. - * - * @param {Number} bytesPermitted The maximum number of bytes - * permitted to be sent. - * @return {Object} an object of the form {length, done}, where - * |length| is the number of bytes actually forwarded, and - * |done| is a boolean indicating whether this particular - * request has been completed. (A NetworkThrottleListener - * may be queued multiple times, so this does not mean that - * all available data has been sent.) - */ - sendSomeData: function (bytesPermitted) { - if (this.pendingData.length === 0) { - // Shouldn't happen. - return {length: 0, done: true}; - } - - const {request, context, stream, count, statusCode} = this.pendingData[0]; - - if (statusCode !== undefined) { - this.pendingData.shift(); - this.originalListener.onStopRequest(request, context, statusCode); - return {length: 0, done: true}; - } - - if (bytesPermitted > count) { - bytesPermitted = count; - } - - try { - this.originalListener.onDataAvailable(request, context, stream, - this.offset, bytesPermitted); - } catch (e) { - this.pendingException = e; - } - - let done = false; - if (bytesPermitted === count) { - this.pendingData.shift(); - done = true; - } else { - this.pendingData[0].count -= bytesPermitted; - } - - this.offset += bytesPermitted; - // Maybe our state has changed enough to emit an event. - this.maybeEmitEvents(); - - return {length: bytesPermitted, done}; - }, - - /** - * Return the number of pending data requests available for this - * listener. - */ - pendingCount: function () { - return this.pendingData.length; - }, - - /** - * This is called when an http activity event is delivered. This - * object delays the event until the appropriate moment. - */ - addActivityCallback: function (callback, httpActivity, channel, activityType, - activitySubtype, timestamp, extraSizeData, - extraStringData) { - let datum = {callback, httpActivity, channel, activityType, - activitySubtype, extraSizeData, - extraStringData}; - this.activities[activitySubtype] = datum; - - if (activitySubtype === - gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_COMPLETE) { - this.totalSize = extraSizeData; - } - - this.maybeEmitEvents(); - }, - - /** - * This is called for a download throttler when the latency timeout - * has ended. - */ - responseStart: function () { - this.responseStarted = true; - this.maybeEmitEvents(); - }, - - /** - * Check our internal state and emit any http activity events as - * needed. Note that we wait until both our internal state has - * changed and we've received the real http activity event from - * platform. This approach ensures we can both pass on the correct - * data from the original event, and update the reported time to be - * consistent with the delay we're introducing. - */ - maybeEmitEvents: function () { - if (this.responseStarted) { - this.maybeEmit(gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_START); - this.maybeEmit(gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_HEADER); - } - - if (this.totalSize !== undefined && this.offset >= this.totalSize) { - this.maybeEmit(gActivityDistributor.ACTIVITY_SUBTYPE_RESPONSE_COMPLETE); - this.maybeEmit(gActivityDistributor.ACTIVITY_SUBTYPE_TRANSACTION_CLOSE); - } - }, - - /** - * Emit an event for |code|, if the appropriate entry in - * |activities| is defined. - */ - maybeEmit: function (code) { - if (this.activities[code] !== undefined) { - let {callback, httpActivity, channel, activityType, - activitySubtype, extraSizeData, - extraStringData} = this.activities[code]; - let now = Date.now() * 1000; - callback(httpActivity, channel, activityType, activitySubtype, - now, extraSizeData, extraStringData); - this.activities[code] = undefined; - } - }, -}; - -/** - * Construct a new queue that can be used to throttle the network for - * a group of related network requests. - * - * meanBPS {Number} Mean bytes per second. - * maxBPS {Number} Maximum bytes per second. - * roundTripTimeMean {Number} Mean round trip time in milliseconds. - * roundTripTimeMax {Number} Maximum round trip time in milliseconds. - */ -function NetworkThrottleQueue(meanBPS, maxBPS, - roundTripTimeMean, roundTripTimeMax) { - this.meanBPS = meanBPS; - this.maxBPS = maxBPS; - this.roundTripTimeMean = roundTripTimeMean; - this.roundTripTimeMax = roundTripTimeMax; - - this.pendingRequests = new Set(); - this.downloadQueue = []; - this.previousReads = []; - - this.pumping = false; -} - -NetworkThrottleQueue.prototype = { - /** - * A helper function that, given a mean and a maximum, returns a - * random integer between (mean - (max - mean)) and max. - */ - random: function (mean, max) { - return mean - (max - mean) + Math.floor(2 * (max - mean) * Math.random()); - }, - - /** - * A helper function that lets the indicating listener start sending - * data. This is called after the initial round trip time for the - * listener has elapsed. - */ - allowDataFrom: function (throttleListener) { - throttleListener.responseStart(); - this.pendingRequests.delete(throttleListener); - const count = throttleListener.pendingCount(); - for (let i = 0; i < count; ++i) { - this.downloadQueue.push(throttleListener); - } - this.pump(); - }, - - /** - * Notice a new listener object. This is called by the - * NetworkThrottleListener when the request has started. Initially - * a new listener object is put into a "pending" state, until the - * round-trip time has elapsed. This is used to simulate latency. - * - * @param {NetworkThrottleListener} throttleListener the new listener - */ - start: function (throttleListener) { - this.pendingRequests.add(throttleListener); - let delay = this.random(this.roundTripTimeMean, this.roundTripTimeMax); - if (delay > 0) { - setTimeout(() => this.allowDataFrom(throttleListener), delay); - } else { - this.allowDataFrom(throttleListener); - } - }, - - /** - * Note that new data is available for a given listener. Each time - * data is available, the listener will be re-queued. - * - * @param {NetworkThrottleListener} throttleListener the listener - * which has data available. - */ - dataAvailable: function (throttleListener) { - if (!this.pendingRequests.has(throttleListener)) { - this.downloadQueue.push(throttleListener); - this.pump(); - } - }, - - /** - * An internal function that permits individual listeners to send - * data. - */ - pump: function () { - // A redirect will cause two NetworkThrottleListeners to be on a - // listener chain. In this case, we might recursively call into - // this method. Avoid infinite recursion here. - if (this.pumping) { - return; - } - this.pumping = true; - - const now = Date.now(); - const oneSecondAgo = now - 1000; - - while (this.previousReads.length && - this.previousReads[0].when < oneSecondAgo) { - this.previousReads.shift(); - } - - const totalBytes = this.previousReads.reduce((sum, elt) => { - return sum + elt.numBytes; - }, 0); - - let thisSliceBytes = this.random(this.meanBPS, this.maxBPS); - if (totalBytes < thisSliceBytes) { - thisSliceBytes -= totalBytes; - let readThisTime = 0; - while (thisSliceBytes > 0 && this.downloadQueue.length) { - let {length, done} = this.downloadQueue[0].sendSomeData(thisSliceBytes); - thisSliceBytes -= length; - readThisTime += length; - if (done) { - this.downloadQueue.shift(); - } - } - this.previousReads.push({when: now, numBytes: readThisTime}); - } - - // If there is more data to download, then schedule ourselves for - // one second after the oldest previous read. - if (this.downloadQueue.length) { - const when = this.previousReads[0].when + 1000; - setTimeout(this.pump.bind(this), when - now); - } - - this.pumping = false; - }, -}; - -/** - * Construct a new object that can be used to throttle the network for - * a group of related network requests. - * - * @param {Object} An object with the following attributes: - * roundTripTimeMean {Number} Mean round trip time in milliseconds. - * roundTripTimeMax {Number} Maximum round trip time in milliseconds. - * downloadBPSMean {Number} Mean bytes per second for downloads. - * downloadBPSMax {Number} Maximum bytes per second for downloads. - * uploadBPSMean {Number} Mean bytes per second for uploads. - * uploadBPSMax {Number} Maximum bytes per second for uploads. - */ -function NetworkThrottleManager({roundTripTimeMean, roundTripTimeMax, - downloadBPSMean, downloadBPSMax, - uploadBPSMean, uploadBPSMax}) { - this.downloadQueue = - new NetworkThrottleQueue(downloadBPSMean, downloadBPSMax, - roundTripTimeMean, roundTripTimeMax); - this.uploadQueue = Cc["@mozilla.org/network/throttlequeue;1"] - .createInstance(Ci.nsIInputChannelThrottleQueue); - this.uploadQueue.init(uploadBPSMean, uploadBPSMax); -} -exports.NetworkThrottleManager = NetworkThrottleManager; - -NetworkThrottleManager.prototype = { - /** - * Create a new NetworkThrottleListener for a given channel and - * install it using |setNewListener|. - * - * @param {nsITraceableChannel} channel the channel to manage - * @return {NetworkThrottleListener} the new listener - */ - manage: function (channel) { - let listener = new NetworkThrottleListener(this.downloadQueue); - let originalListener = channel.setNewListener(listener); - listener.setOriginalListener(originalListener); - return listener; - }, - - /** - * Throttle uploads taking place on the given channel. - * - * @param {nsITraceableChannel} channel the channel to manage - */ - manageUpload: function (channel) { - channel = channel.QueryInterface(Ci.nsIThrottledInputChannel); - channel.throttleQueue = this.uploadQueue; - }, -}; diff --git a/netwerk/base/ThrottleQueue.cpp b/netwerk/base/ThrottleQueue.cpp deleted file mode 100644 index d5b8a41df851..000000000000 --- a/netwerk/base/ThrottleQueue.cpp +++ /dev/null @@ -1,392 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ThrottleQueue.h" -#include "nsISeekableStream.h" -#include "nsIAsyncInputStream.h" -#include "nsStreamUtils.h" -#include "nsNetUtil.h" - -namespace mozilla { -namespace net { - -//----------------------------------------------------------------------------- - -class ThrottleInputStream final - : public nsIAsyncInputStream - , public nsISeekableStream -{ -public: - - ThrottleInputStream(nsIInputStream* aStream, ThrottleQueue* aQueue); - - NS_DECL_THREADSAFE_ISUPPORTS - NS_DECL_NSIINPUTSTREAM - NS_DECL_NSISEEKABLESTREAM - NS_DECL_NSIASYNCINPUTSTREAM - - void AllowInput(); - -private: - - ~ThrottleInputStream(); - - nsCOMPtr mStream; - RefPtr mQueue; - nsresult mClosedStatus; - - nsCOMPtr mCallback; - nsCOMPtr mEventTarget; -}; - -NS_IMPL_ISUPPORTS(ThrottleInputStream, nsIAsyncInputStream, nsIInputStream, nsISeekableStream) - -ThrottleInputStream::ThrottleInputStream(nsIInputStream *aStream, ThrottleQueue* aQueue) - : mStream(aStream) - , mQueue(aQueue) - , mClosedStatus(NS_OK) -{ - MOZ_ASSERT(aQueue != nullptr); -} - -ThrottleInputStream::~ThrottleInputStream() -{ - Close(); -} - -NS_IMETHODIMP -ThrottleInputStream::Close() -{ - if (NS_FAILED(mClosedStatus)) { - return mClosedStatus; - } - - if (mQueue) { - mQueue->DequeueStream(this); - mQueue = nullptr; - mClosedStatus = NS_BASE_STREAM_CLOSED; - } - return mStream->Close(); -} - -NS_IMETHODIMP -ThrottleInputStream::Available(uint64_t* aResult) -{ - if (NS_FAILED(mClosedStatus)) { - return mClosedStatus; - } - - return mStream->Available(aResult); -} - -NS_IMETHODIMP -ThrottleInputStream::Read(char* aBuf, uint32_t aCount, uint32_t* aResult) -{ - if (NS_FAILED(mClosedStatus)) { - return mClosedStatus; - } - - uint32_t realCount; - nsresult rv = mQueue->Available(aCount, &realCount); - if (NS_FAILED(rv)) { - return rv; - } - - if (realCount == 0) { - return NS_BASE_STREAM_WOULD_BLOCK; - } - - rv = mStream->Read(aBuf, realCount, aResult); - if (NS_SUCCEEDED(rv) && *aResult > 0) { - mQueue->RecordRead(*aResult); - } - return rv; -} - -NS_IMETHODIMP -ThrottleInputStream::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure, - uint32_t aCount, uint32_t* aResult) -{ - if (NS_FAILED(mClosedStatus)) { - return mClosedStatus; - } - - uint32_t realCount; - nsresult rv = mQueue->Available(aCount, &realCount); - if (NS_FAILED(rv)) { - return rv; - } - - if (realCount == 0) { - return NS_BASE_STREAM_WOULD_BLOCK; - } - - rv = mStream->ReadSegments(aWriter, aClosure, realCount, aResult); - if (NS_SUCCEEDED(rv) && *aResult > 0) { - mQueue->RecordRead(*aResult); - } - return rv; -} - -NS_IMETHODIMP -ThrottleInputStream::IsNonBlocking(bool* aNonBlocking) -{ - *aNonBlocking = true; - return NS_OK; -} - -NS_IMETHODIMP -ThrottleInputStream::Seek(int32_t aWhence, int64_t aOffset) -{ - if (NS_FAILED(mClosedStatus)) { - return mClosedStatus; - } - - nsCOMPtr sstream = do_QueryInterface(mStream); - if (!sstream) { - return NS_ERROR_FAILURE; - } - - return sstream->Seek(aWhence, aOffset); -} - -NS_IMETHODIMP -ThrottleInputStream::Tell(int64_t* aResult) -{ - if (NS_FAILED(mClosedStatus)) { - return mClosedStatus; - } - - nsCOMPtr sstream = do_QueryInterface(mStream); - if (!sstream) { - return NS_ERROR_FAILURE; - } - - return sstream->Tell(aResult); -} - -NS_IMETHODIMP -ThrottleInputStream::SetEOF() -{ - if (NS_FAILED(mClosedStatus)) { - return mClosedStatus; - } - - nsCOMPtr sstream = do_QueryInterface(mStream); - if (!sstream) { - return NS_ERROR_FAILURE; - } - - return sstream->SetEOF(); -} - -NS_IMETHODIMP -ThrottleInputStream::CloseWithStatus(nsresult aStatus) -{ - if (NS_FAILED(mClosedStatus)) { - // Already closed, ignore. - return NS_OK; - } - if (NS_SUCCEEDED(aStatus)) { - aStatus = NS_BASE_STREAM_CLOSED; - } - - mClosedStatus = Close(); - if (NS_SUCCEEDED(mClosedStatus)) { - mClosedStatus = aStatus; - } - return NS_OK; -} - -NS_IMETHODIMP -ThrottleInputStream::AsyncWait(nsIInputStreamCallback *aCallback, - uint32_t aFlags, - uint32_t aRequestedCount, - nsIEventTarget *aEventTarget) -{ - if (aFlags != 0) { - return NS_ERROR_ILLEGAL_VALUE; - } - - mCallback = aCallback; - mEventTarget = aEventTarget; - if (mCallback) { - mQueue->QueueStream(this); - } else { - mQueue->DequeueStream(this); - } - return NS_OK; -} - -void -ThrottleInputStream::AllowInput() -{ - MOZ_ASSERT(mCallback); - nsCOMPtr callbackEvent = - NS_NewInputStreamReadyEvent(mCallback, mEventTarget); - mCallback = nullptr; - mEventTarget = nullptr; - callbackEvent->OnInputStreamReady(this); -} - -//----------------------------------------------------------------------------- - -NS_IMPL_ISUPPORTS(ThrottleQueue, nsIInputChannelThrottleQueue, nsITimerCallback) - -ThrottleQueue::ThrottleQueue() - : mMeanBytesPerSecond(0) - , mMaxBytesPerSecond(0) - , mBytesProcessed(0) - , mTimerArmed(false) -{ - nsresult rv; - nsCOMPtr sts; - nsCOMPtr ioService = do_GetIOService(&rv); - if (NS_SUCCEEDED(rv)) - sts = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); - if (NS_SUCCEEDED(rv)) - mTimer = do_CreateInstance("@mozilla.org/timer;1"); - if (mTimer) - mTimer->SetTarget(sts); -} - -ThrottleQueue::~ThrottleQueue() -{ - if (mTimer && mTimerArmed) { - mTimer->Cancel(); - } - mTimer = nullptr; -} - -NS_IMETHODIMP -ThrottleQueue::RecordRead(uint32_t aBytesRead) -{ - MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); - ThrottleEntry entry; - entry.mTime = TimeStamp::Now(); - entry.mBytesRead = aBytesRead; - mReadEvents.AppendElement(entry); - mBytesProcessed += aBytesRead; - return NS_OK; -} - -NS_IMETHODIMP -ThrottleQueue::Available(uint32_t aRemaining, uint32_t* aAvailable) -{ - MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); - TimeStamp now = TimeStamp::Now(); - TimeStamp oneSecondAgo = now - TimeDuration::FromSeconds(1); - size_t i; - - // Remove all stale events. - for (i = 0; i < mReadEvents.Length(); ++i) { - if (mReadEvents[i].mTime >= oneSecondAgo) { - break; - } - } - mReadEvents.RemoveElementsAt(0, i); - - uint32_t totalBytes = 0; - for (i = 0; i < mReadEvents.Length(); ++i) { - totalBytes += mReadEvents[i].mBytesRead; - } - - uint32_t spread = mMaxBytesPerSecond - mMeanBytesPerSecond; - double prob = static_cast(rand()) / RAND_MAX; - uint32_t thisSliceBytes = mMeanBytesPerSecond - spread + - static_cast(2 * spread * prob); - - if (totalBytes >= thisSliceBytes) { - *aAvailable = 0; - } else { - *aAvailable = thisSliceBytes; - } - return NS_OK; -} - -NS_IMETHODIMP -ThrottleQueue::Init(uint32_t aMeanBytesPerSecond, uint32_t aMaxBytesPerSecond) -{ - // Can be called on any thread. - if (aMeanBytesPerSecond == 0 || aMaxBytesPerSecond == 0 || aMaxBytesPerSecond < aMeanBytesPerSecond) { - return NS_ERROR_ILLEGAL_VALUE; - } - - mMeanBytesPerSecond = aMeanBytesPerSecond; - mMaxBytesPerSecond = aMaxBytesPerSecond; - return NS_OK; -} - -NS_IMETHODIMP -ThrottleQueue::BytesProcessed(uint64_t* aResult) -{ - *aResult = mBytesProcessed; - return NS_OK; -} - -NS_IMETHODIMP -ThrottleQueue::WrapStream(nsIInputStream* aInputStream, nsIAsyncInputStream** aResult) -{ - nsCOMPtr result = new ThrottleInputStream(aInputStream, this); - result.forget(aResult); - return NS_OK; -} - -NS_IMETHODIMP -ThrottleQueue::Notify(nsITimer* aTimer) -{ - MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); - // A notified reader may need to push itself back on the queue. - // Swap out the list of readers so that this works properly. - nsTArray> events; - events.SwapElements(mAsyncEvents); - - // Optimistically notify all the waiting readers, and then let them - // requeue if there isn't enough bandwidth. - for (size_t i = 0; i < events.Length(); ++i) { - events[i]->AllowInput(); - } - - mTimerArmed = false; - return NS_OK; -} - -void -ThrottleQueue::QueueStream(ThrottleInputStream* aStream) -{ - MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); - if (mAsyncEvents.IndexOf(aStream) == mAsyncEvents.NoIndex) { - mAsyncEvents.AppendElement(aStream); - - if (!mTimerArmed) { - uint32_t ms = 1000; - if (mReadEvents.Length() > 0) { - TimeStamp t = mReadEvents[0].mTime + TimeDuration::FromSeconds(1); - TimeStamp now = TimeStamp::Now(); - - if (t > now) { - ms = static_cast((t - now).ToMilliseconds()); - } else { - ms = 1; - } - } - - if (NS_SUCCEEDED(mTimer->InitWithCallback(this, ms, nsITimer::TYPE_ONE_SHOT))) { - mTimerArmed = true; - } - } - } -} - -void -ThrottleQueue::DequeueStream(ThrottleInputStream* aStream) -{ - MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); - mAsyncEvents.RemoveElement(aStream); -} - -} -} diff --git a/netwerk/base/ThrottleQueue.h b/netwerk/base/ThrottleQueue.h deleted file mode 100644 index 5e16c8ef607e..000000000000 --- a/netwerk/base/ThrottleQueue.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_net_ThrottleQueue_h -#define mozilla_net_ThrottleQueue_h - -#include "mozilla/TimeStamp.h" -#include "nsIThrottledInputChannel.h" -#include "nsITimer.h" - -namespace mozilla { -namespace net { - -class ThrottleInputStream; - -/** - * An implementation of nsIInputChannelThrottleQueue that can be used - * to throttle uploads. This class is not thread-safe. - * Initialization and calls to WrapStream may be done on any thread; - * but otherwise, after creation, it can only be used on the socket - * thread. It currently throttles with a one second granularity, so - * may be a bit choppy. - */ - -class ThrottleQueue final - : public nsIInputChannelThrottleQueue - , public nsITimerCallback -{ -public: - - ThrottleQueue(); - - NS_DECL_THREADSAFE_ISUPPORTS - NS_DECL_NSIINPUTCHANNELTHROTTLEQUEUE - NS_DECL_NSITIMERCALLBACK - - void QueueStream(ThrottleInputStream* aStream); - void DequeueStream(ThrottleInputStream* aStream); - -private: - - ~ThrottleQueue(); - - struct ThrottleEntry { - TimeStamp mTime; - uint32_t mBytesRead; - }; - - nsTArray mReadEvents; - uint32_t mMeanBytesPerSecond; - uint32_t mMaxBytesPerSecond; - uint64_t mBytesProcessed; - - nsTArray> mAsyncEvents; - nsCOMPtr mTimer; - bool mTimerArmed; -}; - -} -} - -#endif // mozilla_net_ThrottleQueue_h diff --git a/netwerk/base/moz.build b/netwerk/base/moz.build index 6c0ea8dab813..f27adba91fe7 100644 --- a/netwerk/base/moz.build +++ b/netwerk/base/moz.build @@ -125,7 +125,6 @@ XPIDL_SOURCES += [ 'nsISystemProxySettings.idl', 'nsIThreadRetargetableRequest.idl', 'nsIThreadRetargetableStreamListener.idl', - 'nsIThrottledInputChannel.idl', 'nsITimedChannel.idl', 'nsITLSServerSocket.idl', 'nsITraceableChannel.idl', @@ -261,7 +260,6 @@ UNIFIED_SOURCES += [ 'RequestContextService.cpp', 'SimpleBuffer.cpp', 'StreamingProtocolService.cpp', - 'ThrottleQueue.cpp', 'Tickler.cpp', 'TLSServerSocket.cpp', ] diff --git a/netwerk/base/nsIThrottledInputChannel.idl b/netwerk/base/nsIThrottledInputChannel.idl deleted file mode 100644 index 76b8cc2a5b50..000000000000 --- a/netwerk/base/nsIThrottledInputChannel.idl +++ /dev/null @@ -1,80 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIInputStream; -interface nsIAsyncInputStream; - -/** - * An instance of this interface can be used to throttle the uploads - * of a group of associated channels. - */ -[scriptable, uuid(6b4b96fe-3c67-4587-af7b-58b6b17da411)] -interface nsIInputChannelThrottleQueue : nsISupports -{ - /** - * Initialize this object with the mean and maximum bytes per - * second that will be allowed. Neither value may be zero, and - * the maximum must not be less than the mean. - * - * @param aMeanBytesPerSecond - * Mean number of bytes per second. - * @param aMaxBytesPerSecond - * Maximum number of bytes per second. - */ - void init(in unsigned long aMeanBytesPerSecond, in unsigned long aMaxBytesPerSecond); - - /** - * Return the number of bytes that are available to the caller in - * this time slice. - * - * @param aRemaining - * The number of bytes available to be processed - * @return the number of bytes allowed to be processed during this - * time slice; this will never be greater than aRemaining. - */ - unsigned long available(in unsigned long aRemaining); - - /** - * Record a successful read. - * - * @param aBytesRead - * The number of bytes actually read. - */ - void recordRead(in unsigned long aBytesRead); - - /** - * Return the number of bytes allowed through this queue. This is - * the sum of all the values passed to recordRead. This method is - * primarily useful for testing. - */ - unsigned long long bytesProcessed(); - - /** - * Wrap the given input stream in a new input stream which - * throttles the incoming data. - * - * @param aInputStream the input stream to wrap - * @return a new input stream that throttles the data. - */ - nsIAsyncInputStream wrapStream(in nsIInputStream aInputStream); -}; - -/** - * A throttled input channel can be managed by an - * nsIInputChannelThrottleQueue to limit how much data is sent during - * a given time slice. - */ -[scriptable, uuid(0a32a100-c031-45b6-9e8b-0444c7d4a143)] -interface nsIThrottledInputChannel : nsISupports -{ - /** - * The queue that manages this channel. Multiple channels can - * share a single queue. A null value means that no throttling - * will be done. - */ - attribute nsIInputChannelThrottleQueue throttleQueue; -}; diff --git a/netwerk/build/nsNetCID.h b/netwerk/build/nsNetCID.h index efc327a6459a..9554a8d5155d 100644 --- a/netwerk/build/nsNetCID.h +++ b/netwerk/build/nsNetCID.h @@ -625,16 +625,6 @@ {0x96, 0x1f, 0x65, 0x53, 0xcd, 0x60, 0xb1, 0xa2} \ } -#define NS_THROTTLEQUEUE_CONTRACTID \ - "@mozilla.org/network/throttlequeue;1" -#define NS_THROTTLEQUEUE_CID \ -{ /* 4c39159c-cd90-4dd3-97a7-06af5e6d84c4 */ \ - 0x4c39159c, \ - 0xcd90, \ - 0x4dd3, \ - {0x97, 0xa7, 0x06, 0xaf, 0x5e, 0x6d, 0x84, 0xc4} \ -} - /****************************************************************************** * netwerk/protocol/ftp/ classes */ diff --git a/netwerk/build/nsNetModule.cpp b/netwerk/build/nsNetModule.cpp index 8d477ab8a05e..f3ba09604c82 100644 --- a/netwerk/build/nsNetModule.cpp +++ b/netwerk/build/nsNetModule.cpp @@ -269,7 +269,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFtpProtocolHandler, Init) #include "nsHttpDigestAuth.h" #include "nsHttpNTLMAuth.h" #include "nsHttpActivityDistributor.h" -#include "ThrottleQueue.h" #undef LOG #undef LOG_ENABLED namespace mozilla { @@ -282,7 +281,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpChannelAuthProvider) NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpActivityDistributor) NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpBasicAuth) NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpDigestAuth) -NS_GENERIC_FACTORY_CONSTRUCTOR(ThrottleQueue) } // namespace net } // namespace mozilla #endif // !NECKO_PROTOCOL_http @@ -796,7 +794,6 @@ NS_DEFINE_NAMED_CID(NS_HTTPNTLMAUTH_CID); NS_DEFINE_NAMED_CID(NS_HTTPAUTHMANAGER_CID); NS_DEFINE_NAMED_CID(NS_HTTPCHANNELAUTHPROVIDER_CID); NS_DEFINE_NAMED_CID(NS_HTTPACTIVITYDISTRIBUTOR_CID); -NS_DEFINE_NAMED_CID(NS_THROTTLEQUEUE_CID); #endif // !NECKO_PROTOCOL_http #ifdef NECKO_PROTOCOL_ftp NS_DEFINE_NAMED_CID(NS_FTPPROTOCOLHANDLER_CID); @@ -947,7 +944,6 @@ static const mozilla::Module::CIDEntry kNeckoCIDs[] = { { &kNS_HTTPAUTHMANAGER_CID, false, nullptr, mozilla::net::nsHttpAuthManagerConstructor }, { &kNS_HTTPCHANNELAUTHPROVIDER_CID, false, nullptr, mozilla::net::nsHttpChannelAuthProviderConstructor }, { &kNS_HTTPACTIVITYDISTRIBUTOR_CID, false, nullptr, mozilla::net::nsHttpActivityDistributorConstructor }, - { &kNS_THROTTLEQUEUE_CID, false, nullptr, mozilla::net::ThrottleQueueConstructor }, #endif // !NECKO_PROTOCOL_http #ifdef NECKO_PROTOCOL_ftp { &kNS_FTPPROTOCOLHANDLER_CID, false, nullptr, nsFtpProtocolHandlerConstructor }, @@ -1109,7 +1105,6 @@ static const mozilla::Module::ContractIDEntry kNeckoContracts[] = { { NS_HTTPAUTHMANAGER_CONTRACTID, &kNS_HTTPAUTHMANAGER_CID }, { NS_HTTPCHANNELAUTHPROVIDER_CONTRACTID, &kNS_HTTPCHANNELAUTHPROVIDER_CID }, { NS_HTTPACTIVITYDISTRIBUTOR_CONTRACTID, &kNS_HTTPACTIVITYDISTRIBUTOR_CID }, - { NS_THROTTLEQUEUE_CONTRACTID, &kNS_THROTTLEQUEUE_CID }, #endif // !NECKO_PROTOCOL_http #ifdef NECKO_PROTOCOL_ftp { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "ftp", &kNS_FTPPROTOCOLHANDLER_CID }, diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index e4dff2a9e1dc..a7c3e9a58fb9 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -227,7 +227,6 @@ NS_INTERFACE_MAP_BEGIN(HttpBaseChannel) NS_INTERFACE_MAP_ENTRY(nsIPrivateBrowsingChannel) NS_INTERFACE_MAP_ENTRY(nsITimedChannel) NS_INTERFACE_MAP_ENTRY(nsIConsoleReportCollector) - NS_INTERFACE_MAP_ENTRY(nsIThrottledInputChannel) NS_INTERFACE_MAP_END_INHERITING(nsHashPropertyBag) //----------------------------------------------------------------------------- @@ -3442,28 +3441,6 @@ HttpBaseChannel::GetInnerDOMWindow() return innerWindow; } -//----------------------------------------------------------------------------- -// HttpBaseChannel::nsIThrottledInputChannel -//----------------------------------------------------------------------------- - -NS_IMETHODIMP -HttpBaseChannel::SetThrottleQueue(nsIInputChannelThrottleQueue* aQueue) -{ - if (!XRE_IsParentProcess()) { - return NS_ERROR_FAILURE; - } - - mThrottleQueue = aQueue; - return NS_OK; -} - -NS_IMETHODIMP -HttpBaseChannel::GetThrottleQueue(nsIInputChannelThrottleQueue** aQueue) -{ - *aQueue = mThrottleQueue; - return NS_OK; -} - //------------------------------------------------------------------------------ bool diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h index dc6d5e67c324..3d34a0608eba 100644 --- a/netwerk/protocol/http/HttpBaseChannel.h +++ b/netwerk/protocol/http/HttpBaseChannel.h @@ -43,7 +43,6 @@ #include "nsISecurityConsoleMessage.h" #include "nsCOMArray.h" #include "mozilla/net/ChannelEventQueue.h" -#include "nsIThrottledInputChannel.h" class nsISecurityConsoleMessage; class nsIPrincipal; @@ -80,7 +79,6 @@ class HttpBaseChannel : public nsHashPropertyBag , public nsITimedChannel , public nsIForcePendingChannel , public nsIConsoleReportCollector - , public nsIThrottledInputChannel { protected: virtual ~HttpBaseChannel(); @@ -92,7 +90,6 @@ public: NS_DECL_NSIUPLOADCHANNEL2 NS_DECL_NSITRACEABLECHANNEL NS_DECL_NSITIMEDCHANNEL - NS_DECL_NSITHROTTLEDINPUTCHANNEL HttpBaseChannel(); @@ -387,8 +384,6 @@ protected: nsCOMPtr mCompressListener; nsHttpRequestHead mRequestHead; - // Upload throttling. - nsCOMPtr mThrottleQueue; nsCOMPtr mUploadStream; nsCOMPtr mUploadCloneableCallback; nsAutoPtr mResponseHead; diff --git a/netwerk/protocol/http/nsHttpTransaction.cpp b/netwerk/protocol/http/nsHttpTransaction.cpp index d9a87ee9db07..45c14f66f18e 100644 --- a/netwerk/protocol/http/nsHttpTransaction.cpp +++ b/netwerk/protocol/http/nsHttpTransaction.cpp @@ -33,7 +33,6 @@ #include "nsIEventTarget.h" #include "nsIHttpChannelInternal.h" #include "nsIInputStream.h" -#include "nsIThrottledInputChannel.h" #include "nsITransport.h" #include "nsIOService.h" #include "nsIRequestContext.h" @@ -233,7 +232,6 @@ nsHttpTransaction::Init(uint32_t caps, MOZ_ASSERT(cinfo); MOZ_ASSERT(requestHead); MOZ_ASSERT(target); - MOZ_ASSERT(NS_IsMainThread()); mActivityDistributor = do_GetService(NS_HTTPACTIVITYDISTRIBUTOR_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; @@ -381,25 +379,6 @@ nsHttpTransaction::Init(uint32_t caps, else mRequestStream = headers; - nsCOMPtr throttled = do_QueryInterface(mChannel); - nsIInputChannelThrottleQueue* queue; - if (throttled) { - rv = throttled->GetThrottleQueue(&queue); - // In case of failure, just carry on without throttling. - if (NS_SUCCEEDED(rv) && queue) { - nsCOMPtr wrappedStream; - rv = queue->WrapStream(mRequestStream, getter_AddRefs(wrappedStream)); - // Failure to throttle isn't sufficient reason to fail - // initialization - if (NS_SUCCEEDED(rv)) { - MOZ_ASSERT(wrappedStream != nullptr); - LOG(("nsHttpTransaction::Init %p wrapping input stream using throttle queue %p\n", - this, queue)); - mRequestStream = do_QueryInterface(wrappedStream); - } - } - } - uint64_t size_u64; rv = mRequestStream->Available(&size_u64); if (NS_FAILED(rv)) { diff --git a/netwerk/test/unit/test_throttlechannel.js b/netwerk/test/unit/test_throttlechannel.js deleted file mode 100644 index 97c119b9942d..000000000000 --- a/netwerk/test/unit/test_throttlechannel.js +++ /dev/null @@ -1,41 +0,0 @@ -// Test nsIThrottledInputChannel interface. - -Cu.import("resource://testing-common/httpd.js"); -Cu.import("resource://gre/modules/NetUtil.jsm"); - -function test_handler(metadata, response) { - const originalBody = "the response"; - response.setHeader("Content-Type", "text/html", false); - response.setStatusLine(metadata.httpVersion, 200, "OK"); - response.bodyOutputStream.write(originalBody, originalBody.length); -} - -function make_channel(url) { - return NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true}) - .QueryInterface(Components.interfaces.nsIHttpChannel); -} - -function run_test() { - let httpserver = new HttpServer(); - httpserver.start(-1); - const PORT = httpserver.identity.primaryPort; - - httpserver.registerPathHandler("/testdir", test_handler); - - let channel = make_channel("http://localhost:" + PORT + "/testdir"); - - let tq = Cc["@mozilla.org/network/throttlequeue;1"] - .createInstance(Ci.nsIInputChannelThrottleQueue); - tq.init(1000, 1000); - - let tic = channel.QueryInterface(Ci.nsIThrottledInputChannel); - tic.throttleQueue = tq; - - channel.asyncOpen2(new ChannelListener(() => { - ok(tq.bytesProcessed() > 0, "throttled queue processed some bytes"); - - httpserver.stop(do_test_finished); - })); - - do_test_pending(); -} diff --git a/netwerk/test/unit/test_throttlequeue.js b/netwerk/test/unit/test_throttlequeue.js deleted file mode 100644 index fdfa80d1b0aa..000000000000 --- a/netwerk/test/unit/test_throttlequeue.js +++ /dev/null @@ -1,23 +0,0 @@ -// Test ThrottleQueue initialization. - -function init(tq, mean, max) { - let threw = false; - try { - tq.init(mean, max); - } catch (e) { - threw = true; - } - return !threw; -} - -function run_test() { - let tq = Cc["@mozilla.org/network/throttlequeue;1"] - .createInstance(Ci.nsIInputChannelThrottleQueue); - - ok(!init(tq, 0, 50), "mean bytes cannot be 0"); - ok(!init(tq, 50, 0), "max bytes cannot be 0"); - ok(!init(tq, 0, 0), "mean and max bytes cannot be 0"); - ok(!init(tq, 70, 20), "max cannot be less than mean"); - - ok(init(tq, 2, 2), "valid initialization"); -} diff --git a/netwerk/test/unit/test_throttling.js b/netwerk/test/unit/test_throttling.js deleted file mode 100644 index afb82789492e..000000000000 --- a/netwerk/test/unit/test_throttling.js +++ /dev/null @@ -1,57 +0,0 @@ -// Test nsIThrottledInputChannel interface. - -Cu.import("resource://testing-common/httpd.js"); -Cu.import("resource://gre/modules/NetUtil.jsm"); - -function test_handler(metadata, response) { - const originalBody = "the response"; - response.setHeader("Content-Type", "text/html", false); - response.setStatusLine(metadata.httpVersion, 200, "OK"); - response.bodyOutputStream.write(originalBody, originalBody.length); -} - -function make_channel(url) { - return NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true}) - .QueryInterface(Ci.nsIHttpChannel); -} - -function run_test() { - let httpserver = new HttpServer(); - httpserver.registerPathHandler("/testdir", test_handler); - httpserver.start(-1); - - const PORT = httpserver.identity.primaryPort; - const size = 4096; - - let sstream = Cc["@mozilla.org/io/string-input-stream;1"]. - createInstance(Ci.nsIStringInputStream); - sstream.data = 'x'.repeat(size); - - let mime = Cc["@mozilla.org/network/mime-input-stream;1"]. - createInstance(Ci.nsIMIMEInputStream); - mime.addHeader("Content-Type", "multipart/form-data; boundary=zzzzz"); - mime.setData(sstream); - mime.addContentLength = true; - - let tq = Cc["@mozilla.org/network/throttlequeue;1"] - .createInstance(Ci.nsIInputChannelThrottleQueue); - // Make sure the request takes more than one read. - tq.init(100 + size / 2, 100 + size / 2); - - let channel = make_channel("http://localhost:" + PORT + "/testdir"); - channel.QueryInterface(Ci.nsIUploadChannel) - .setUploadStream(mime, "", mime.available()); - channel.requestMethod = "POST"; - - let tic = channel.QueryInterface(Ci.nsIThrottledInputChannel); - tic.throttleQueue = tq; - - let startTime = Date.now(); - channel.asyncOpen2(new ChannelListener(() => { - ok(Date.now() - startTime > 1000, "request took more than one second"); - - httpserver.stop(do_test_finished); - })); - - do_test_pending(); -} diff --git a/netwerk/test/unit/xpcshell.ini b/netwerk/test/unit/xpcshell.ini index 7a18524f227c..0dbd5111b75e 100644 --- a/netwerk/test/unit/xpcshell.ini +++ b/netwerk/test/unit/xpcshell.ini @@ -359,6 +359,3 @@ skip-if = os == "android" [test_bug464591.js] [test_cache-control_request.js] [test_bug1279246.js] -[test_throttlequeue.js] -[test_throttlechannel.js] -[test_throttling.js]