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.js170
1 files changed, 170 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 000000000..45c01683a
--- /dev/null
+++ b/netwerk/test/unit/test_event_sink.js
@@ -0,0 +1,170 @@
+// This file tests channel event sinks (bug 315598 et al)
+
+Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/NetUtil.jsm");
+
+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: function eventsink_qi(iid) {
+ if (iid.equals(Components.interfaces.nsISupports) ||
+ iid.equals(Components.interfaces.nsIFactory) ||
+ iid.equals(Components.interfaces.nsIChannelEventSink))
+ return this;
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ },
+ createInstance: function eventsink_ci(outer, iid) {
+ if (outer)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+ return this.QueryInterface(iid);
+ },
+ lockFactory: function eventsink_lockf(lock) {
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+ },
+
+ asyncOnChannelRedirect: function eventsink_onredir(oldChan, newChan, flags, callback) {
+ // veto
+ this.called = true;
+ throw Components.results.NS_BINDING_ABORTED;
+ },
+
+ getInterface: function eventsink_gi(iid) {
+ if (iid.equals(Components.interfaces.nsIChannelEventSink))
+ return this;
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ },
+
+ called: false
+};
+
+var listener = {
+ expectSinkCall: true,
+
+ onStartRequest: function test_onStartR(request, ctx) {
+ 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 Components.interfaces.nsIChannel) ||
+ !request.URI.equals(request.originalURI))
+ do_throw("Wrong URI: Is <" + request.URI.spec + ">, should be <" +
+ request.originalURI.spec + ">");
+
+ if (request instanceof Components.interfaces.nsIHttpChannel) {
+ // As we expect a blocked redirect, verify that we have a 3xx status
+ do_check_eq(Math.floor(request.responseStatus / 100), 3);
+ do_check_eq(request.requestSucceeded, false);
+ }
+
+ do_check_eq(eventsink.called, this.expectSinkCall);
+ } catch (e) {
+ do_throw("Unexpected exception: " + e);
+ }
+
+ throw Components.results.NS_ERROR_ABORT;
+ },
+
+ onDataAvailable: function test_ODA() {
+ do_throw("Should not get any data!");
+ },
+
+ onStopRequest: function test_onStopR(request, ctx, 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.asyncOpen2(listener);
+
+ do_test_pending();
+}
+
+function run_test_continued() {
+ eventsink.called = false;
+
+ var catMan = Components.classes["@mozilla.org/categorymanager;1"]
+ .getService(Components.interfaces.nsICategoryManager);
+
+ var chan;
+ if (listener._iteration == 1) {
+ // Step 2: Category entry
+ catMan.nsICategoryManager.addCategoryEntry(categoryName, "unit test",
+ sinkContract, false, true);
+ chan = makeChan(URL + "/redirect")
+ } else {
+ // Step 3: Global contract id
+ catMan.nsICategoryManager.deleteCategoryEntry(categoryName, "unit test",
+ false);
+ listener.expectSinkCall = false;
+ chan = makeChan(URL + "/redirectfile");
+ }
+
+ listener._iteration++;
+ chan.asyncOpen2(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);
+}