1 // This file tests channel event sinks (bug 315598 et al)
3 do_import_script("netwerk/test/httpserver/httpd.js");
5 const sinkCID = Components.ID("{14aa4b81-e266-45cb-88f8-89595dece114}");
6 const sinkContract = "@mozilla.org/network/unittest/channeleventsink;1";
8 const categoryName = "net-channel-event-sinks";
10 const NS_BINDING_ABORTED = 0x804b0002;
13 * This object is both a factory and an nsIChannelEventSink implementation (so, it
14 * is de-facto a service). It's also an interface requestor that gives out
15 * itself when asked for nsIChannelEventSink.
18 QueryInterface: function eventsink_qi(iid) {
19 if (iid.equals(Components.interfaces.nsISupports) ||
20 iid.equals(Components.interfaces.nsIFactory) ||
21 iid.equals(Components.interfaces.nsIChannelEventSink))
23 throw Components.results.NS_ERROR_NO_INTERFACE;
25 createInstance: function eventsink_ci(outer, iid) {
27 throw Components.results.NS_ERROR_NO_AGGREGATION;
28 return this.QueryInterface(iid);
30 lockFactory: function eventsink_lockf(lock) {
31 throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
34 onChannelRedirect: function eventsink_onredir(oldChan, newChan, flags) {
37 throw NS_BINDING_ABORTED;
40 getInterface: function eventsink_gi(iid) {
41 if (iid.equals(Components.interfaces.nsIChannelEventSink))
43 throw Components.results.NS_ERROR_NO_INTERFACE;
52 onStartRequest: function test_onStartR(request, ctx) {
54 // Commenting out this check pending resolution of bug 255119
55 //if (Components.isSuccessCode(request.status))
56 // do_throw("Channel should have a failure code!");
58 // The current URI must be the original URI, as all redirects have been
60 if (!(request instanceof Components.interfaces.nsIChannel) ||
61 !request.URI.equals(request.originalURI))
62 do_throw("Wrong URI: Is <" + request.URI.spec + ">, should be <" +
63 request.originalURI.spec + ">");
65 if (request instanceof Components.interfaces.nsIHttpChannel) {
66 // As we expect a blocked redirect, verify that we have a 3xx status
67 do_check_eq(Math.floor(request.responseStatus / 100), 3);
68 do_check_eq(request.requestSucceeded, false);
71 do_check_eq(eventsink.called, this.expectSinkCall);
73 do_throw("Unexpected exception: " + e);
76 throw Components.results.NS_ERROR_ABORT;
79 onDataAvailable: function test_ODA() {
80 do_throw("Should not get any data!");
83 onStopRequest: function test_onStopR(request, ctx, status) {
84 if (this._iteration <= 2)
94 function makeChan(url) {
95 var ios = Components.classes["@mozilla.org/network/io-service;1"]
96 .getService(Components.interfaces.nsIIOService);
97 var chan = ios.newChannel(url, null, null)
98 .QueryInterface(Components.interfaces.nsIHttpChannel);
105 function run_test() {
106 httpserv = new nsHttpServer();
107 httpserv.registerPathHandler("/redirect", redirect);
108 httpserv.registerPathHandler("/redirectfile", redirectfile);
109 httpserv.start(4444);
111 Components.manager.nsIComponentRegistrar.registerFactory(sinkCID,
112 "Unit test Event sink", sinkContract, eventsink);
114 // Step 1: Set the callbacks on the listener itself
115 var chan = makeChan("http://localhost:4444/redirect");
116 chan.notificationCallbacks = eventsink;
118 chan.asyncOpen(listener, null);
123 function run_test_continued() {
124 eventsink.called = false;
126 var catMan = Components.classes["@mozilla.org/categorymanager;1"]
127 .getService(Components.interfaces.nsICategoryManager);
130 if (listener._iteration == 1) {
131 // Step 2: Category entry
132 catMan.nsICategoryManager.addCategoryEntry(categoryName, "unit test",
133 sinkContract, false, true);
134 chan = makeChan("http://localhost:4444/redirect")
136 // Step 3: Global contract id
137 catMan.nsICategoryManager.deleteCategoryEntry(categoryName, "unit test",
139 listener.expectSinkCall = false;
140 chan = makeChan("http://localhost:4444/redirectfile");
143 listener._iteration++;
144 chan.asyncOpen(listener, null);
152 function redirect(metadata, response) {
153 response.setStatusLine(metadata.httpVersion, 301, "Moved Permanently");
154 response.setHeader("Location",
155 "http://localhost:" + metadata.port + "/",
158 var body = "Moved\n";
159 response.bodyOutputStream.write(body, body.length);
163 function redirectfile(metadata, response) {
164 response.setStatusLine(metadata.httpVersion, 301, "Moved Permanently");
165 response.setHeader("Content-Type", "text/plain", false);
166 response.setHeader("Location", "file:///etc/", false);
168 var body = "Attempted to move to a file URI, but failed.\n";
169 response.bodyOutputStream.write(body, body.length);