diff options
Diffstat (limited to 'netwerk/test/unit/test_event_sink.js')
-rw-r--r-- | netwerk/test/unit/test_event_sink.js | 170 |
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); +} |