summaryrefslogtreecommitdiffstats
path: root/netwerk/test/unit/test_event_sink.js
diff options
context:
space:
mode:
Diffstat (limited to 'netwerk/test/unit/test_event_sink.js')
-rw-r--r--netwerk/test/unit/test_event_sink.js181
1 files changed, 181 insertions, 0 deletions
diff --git a/netwerk/test/unit/test_event_sink.js b/netwerk/test/unit/test_event_sink.js
new file mode 100644
index 0000000000..45cbf02f85
--- /dev/null
+++ b/netwerk/test/unit/test_event_sink.js
@@ -0,0 +1,181 @@
+// This file tests channel event sinks (bug 315598 et al)
+
+"use strict";
+
+const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
+
+XPCOMUtils.defineLazyGetter(this, "URL", function () {
+ return "http://localhost:" + httpserv.identity.primaryPort;
+});
+
+const sinkCID = Components.ID("{14aa4b81-e266-45cb-88f8-89595dece114}");
+const sinkContract = "@mozilla.org/network/unittest/channeleventsink;1";
+
+const categoryName = "net-channel-event-sinks";
+
+/**
+ * This object is both a factory and an nsIChannelEventSink implementation (so, it
+ * is de-facto a service). It's also an interface requestor that gives out
+ * itself when asked for nsIChannelEventSink.
+ */
+var eventsink = {
+ QueryInterface: ChromeUtils.generateQI(["nsIFactory", "nsIChannelEventSink"]),
+ createInstance: function eventsink_ci(iid) {
+ return this.QueryInterface(iid);
+ },
+
+ asyncOnChannelRedirect: function eventsink_onredir(
+ oldChan,
+ newChan,
+ flags,
+ callback
+ ) {
+ // veto
+ this.called = true;
+ throw Components.Exception("", Cr.NS_BINDING_ABORTED);
+ },
+
+ getInterface: function eventsink_gi(iid) {
+ if (iid.equals(Ci.nsIChannelEventSink)) {
+ return this;
+ }
+ throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE);
+ },
+
+ called: false,
+};
+
+var listener = {
+ expectSinkCall: true,
+
+ onStartRequest: function test_onStartR(request) {
+ try {
+ // Commenting out this check pending resolution of bug 255119
+ //if (Components.isSuccessCode(request.status))
+ // do_throw("Channel should have a failure code!");
+
+ // The current URI must be the original URI, as all redirects have been
+ // cancelled
+ if (
+ !(request instanceof Ci.nsIChannel) ||
+ !request.URI.equals(request.originalURI)
+ ) {
+ do_throw(
+ "Wrong URI: Is <" +
+ request.URI.spec +
+ ">, should be <" +
+ request.originalURI.spec +
+ ">"
+ );
+ }
+
+ if (request instanceof Ci.nsIHttpChannel) {
+ // As we expect a blocked redirect, verify that we have a 3xx status
+ Assert.equal(Math.floor(request.responseStatus / 100), 3);
+ Assert.equal(request.requestSucceeded, false);
+ }
+
+ Assert.equal(eventsink.called, this.expectSinkCall);
+ } catch (e) {
+ do_throw("Unexpected exception: " + e);
+ }
+
+ throw Components.Exception("", Cr.NS_ERROR_ABORT);
+ },
+
+ onDataAvailable: function test_ODA() {
+ do_throw("Should not get any data!");
+ },
+
+ onStopRequest: function test_onStopR(request, status) {
+ if (this._iteration <= 2) {
+ run_test_continued();
+ } else {
+ do_test_pending();
+ httpserv.stop(do_test_finished);
+ }
+ do_test_finished();
+ },
+
+ _iteration: 1,
+};
+
+function makeChan(url) {
+ return NetUtil.newChannel({ uri: url, loadUsingSystemPrincipal: true });
+}
+
+var httpserv = null;
+
+function run_test() {
+ httpserv = new HttpServer();
+ httpserv.registerPathHandler("/redirect", redirect);
+ httpserv.registerPathHandler("/redirectfile", redirectfile);
+ httpserv.start(-1);
+
+ Components.manager.nsIComponentRegistrar.registerFactory(
+ sinkCID,
+ "Unit test Event sink",
+ sinkContract,
+ eventsink
+ );
+
+ // Step 1: Set the callbacks on the listener itself
+ var chan = makeChan(URL + "/redirect");
+ chan.notificationCallbacks = eventsink;
+
+ chan.asyncOpen(listener);
+
+ do_test_pending();
+}
+
+function run_test_continued() {
+ eventsink.called = false;
+
+ var chan;
+ if (listener._iteration == 1) {
+ // Step 2: Category entry
+ Services.catMan.addCategoryEntry(
+ categoryName,
+ "unit test",
+ sinkContract,
+ false,
+ true
+ );
+ chan = makeChan(URL + "/redirect");
+ } else {
+ // Step 3: Global contract id
+ Services.catMan.deleteCategoryEntry(categoryName, "unit test", false);
+ listener.expectSinkCall = false;
+ chan = makeChan(URL + "/redirectfile");
+ }
+
+ listener._iteration++;
+ chan.asyncOpen(listener);
+
+ do_test_pending();
+}
+
+// PATHS
+
+// /redirect
+function redirect(metadata, response) {
+ response.setStatusLine(metadata.httpVersion, 301, "Moved Permanently");
+ response.setHeader(
+ "Location",
+ "http://localhost:" + metadata.port + "/",
+ false
+ );
+
+ var body = "Moved\n";
+ response.bodyOutputStream.write(body, body.length);
+}
+
+// /redirectfile
+function redirectfile(metadata, response) {
+ response.setStatusLine(metadata.httpVersion, 301, "Moved Permanently");
+ response.setHeader("Content-Type", "text/plain", false);
+ response.setHeader("Location", "file:///etc/", false);
+
+ var body = "Attempted to move to a file URI, but failed.\n";
+ response.bodyOutputStream.write(body, body.length);
+}