зеркало из https://github.com/mozilla/gecko-dev.git
183 строки
5.7 KiB
JavaScript
183 строки
5.7 KiB
JavaScript
// This file tests channel event sinks (bug 315598 et al)
|
|
|
|
Cu.import("resource://testing-common/httpd.js");
|
|
Cu.import("resource://gre/modules/Services.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) {
|
|
var ios = Components.classes["@mozilla.org/network/io-service;1"]
|
|
.getService(Components.interfaces.nsIIOService);
|
|
var chan = ios.newChannel2(url,
|
|
null,
|
|
null,
|
|
null, // aLoadingNode
|
|
Services.scriptSecurityManager.getSystemPrincipal(),
|
|
null, // aTriggeringPrincipal
|
|
Ci.nsILoadInfo.SEC_NORMAL,
|
|
Ci.nsIContentPolicy.TYPE_OTHER)
|
|
.QueryInterface(Components.interfaces.nsIHttpChannel);
|
|
|
|
return chan;
|
|
}
|
|
|
|
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, null);
|
|
|
|
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.asyncOpen(listener, null);
|
|
|
|
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);
|
|
}
|