fune/netwerk/test/unit/test_synthesized_response.js
Kris Maglione a259026c9d Bug 1456035: Part 4 - Convert callers of XPCOMUtils.generateQI to ChromeUtils.generateQI. r=mccr8
This also removes any redundant Ci.nsISupports elements in the interface
lists.

This was done using the following script:

acecb401b7/processors/chromeutils-generateQI.jsm

MozReview-Commit-ID: AIx10P8GpZY

--HG--
extra : rebase_source : a29c07530586dc18ba040f19215475ac20fcfb3b
2018-04-22 20:55:06 -07:00

260 lines
8.7 KiB
JavaScript

"use strict";
ChromeUtils.import("resource://testing-common/httpd.js");
ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
XPCOMUtils.defineLazyGetter(this, "URL", function() {
return "http://localhost:" + httpServer.identity.primaryPort;
});
var httpServer = null;
function make_uri(url) {
var ios = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
return ios.newURI(url);
}
function isParentProcess() {
let appInfo = Cc["@mozilla.org/xre/app-info;1"];
return (!appInfo || appInfo.getService(Ci.nsIXULRuntime).processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT);
}
if (isParentProcess()) {
// ensure the cache service is prepped when running the test
// We only do this in the main process, as the cache storage service leaks
// when instantiated in the content process.
Cc["@mozilla.org/netwerk/cache-storage-service;1"].getService(Ci.nsICacheStorageService);
}
var gotOnProgress;
var gotOnStatus;
function make_channel(url, body, cb) {
gotOnProgress = false;
gotOnStatus = false;
var chan = NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true})
.QueryInterface(Ci.nsIHttpChannel);
chan.notificationCallbacks = {
numChecks: 0,
QueryInterface: ChromeUtils.generateQI([Ci.nsINetworkInterceptController,
Ci.nsIInterfaceRequestor,
Ci.nsIProgressEventSink]),
getInterface: function(iid) {
return this.QueryInterface(iid);
},
onProgress: function(request, context, progress, progressMax) {
gotOnProgress = true;
},
onStatus: function(request, context, status, statusArg) {
gotOnStatus = true;
},
shouldPrepareForIntercept: function() {
Assert.equal(this.numChecks, 0);
this.numChecks++;
return true;
},
channelIntercepted: function(channel) {
channel.QueryInterface(Ci.nsIInterceptedChannel);
if (body) {
var synthesized = Cc["@mozilla.org/io/string-input-stream;1"]
.createInstance(Ci.nsIStringInputStream);
synthesized.data = body;
channel.startSynthesizedResponse(synthesized, null, null, '', false);
channel.finishSynthesizedResponse();
}
if (cb) {
cb(channel);
}
return {
dispatch: function() { }
};
},
};
return chan;
}
const REMOTE_BODY = "http handler body";
const NON_REMOTE_BODY = "synthesized body";
const NON_REMOTE_BODY_2 = "synthesized body #2";
function bodyHandler(metadata, response) {
response.setHeader('Content-Type', 'text/plain');
response.write(REMOTE_BODY);
}
function run_test() {
httpServer = new HttpServer();
httpServer.registerPathHandler('/body', bodyHandler);
httpServer.start(-1);
run_next_test();
}
function handle_synthesized_response(request, buffer) {
Assert.equal(buffer, NON_REMOTE_BODY);
Assert.ok(gotOnStatus);
Assert.ok(gotOnProgress);
run_next_test();
}
function handle_synthesized_response_2(request, buffer) {
Assert.equal(buffer, NON_REMOTE_BODY_2);
Assert.ok(gotOnStatus);
Assert.ok(gotOnProgress);
run_next_test();
}
function handle_remote_response(request, buffer) {
Assert.equal(buffer, REMOTE_BODY);
Assert.ok(gotOnStatus);
Assert.ok(gotOnProgress);
run_next_test();
}
// hit the network instead of synthesizing
add_test(function() {
var chan = make_channel(URL + '/body', null, function(chan) {
chan.resetInterception();
});
chan.asyncOpen2(new ChannelListener(handle_remote_response, null));
});
// synthesize a response
add_test(function() {
var chan = make_channel(URL + '/body', NON_REMOTE_BODY);
chan.asyncOpen2(new ChannelListener(handle_synthesized_response, null, CL_ALLOW_UNKNOWN_CL));
});
// hit the network instead of synthesizing, to test that no previous synthesized
// cache entry is used.
add_test(function() {
var chan = make_channel(URL + '/body', null, function(chan) {
chan.resetInterception();
});
chan.asyncOpen2(new ChannelListener(handle_remote_response, null));
});
// synthesize a different response to ensure no previous response is cached
add_test(function() {
var chan = make_channel(URL + '/body', NON_REMOTE_BODY_2);
chan.asyncOpen2(new ChannelListener(handle_synthesized_response_2, null, CL_ALLOW_UNKNOWN_CL));
});
// ensure that the channel waits for a decision and synthesizes headers correctly
add_test(function() {
var chan = make_channel(URL + '/body', null, function(channel) {
do_timeout(100, function() {
var synthesized = Cc["@mozilla.org/io/string-input-stream;1"]
.createInstance(Ci.nsIStringInputStream);
synthesized.data = NON_REMOTE_BODY;
channel.synthesizeHeader("Content-Length", NON_REMOTE_BODY.length);
channel.startSynthesizedResponse(synthesized, null, null, '', false);
channel.finishSynthesizedResponse();
});
});
chan.asyncOpen2(new ChannelListener(handle_synthesized_response, null));
});
// ensure that the channel waits for a decision
add_test(function() {
var chan = make_channel(URL + '/body', null, function(chan) {
do_timeout(100, function() {
chan.resetInterception();
});
});
chan.asyncOpen2(new ChannelListener(handle_remote_response, null));
});
// ensure that the intercepted channel supports suspend/resume
add_test(function() {
var chan = make_channel(URL + '/body', null, function(intercepted) {
var synthesized = Cc["@mozilla.org/io/string-input-stream;1"]
.createInstance(Ci.nsIStringInputStream);
synthesized.data = NON_REMOTE_BODY;
// set the content-type to ensure that the stream converter doesn't hold up notifications
// and cause the test to fail
intercepted.synthesizeHeader("Content-Type", "text/plain");
intercepted.startSynthesizedResponse(synthesized, null, null, '', false);
intercepted.finishSynthesizedResponse();
});
chan.asyncOpen2(new ChannelListener(handle_synthesized_response, null,
CL_ALLOW_UNKNOWN_CL | CL_SUSPEND | CL_EXPECT_3S_DELAY));
});
// ensure that the intercepted channel can be cancelled
add_test(function() {
var chan = make_channel(URL + '/body', null, function(intercepted) {
intercepted.cancelInterception(Cr.NS_BINDING_ABORTED);
});
chan.asyncOpen2(new ChannelListener(run_next_test, null, CL_EXPECT_FAILURE));
});
// ensure that the channel can't be cancelled via nsIInterceptedChannel after making a decision
add_test(function() {
var chan = make_channel(URL + '/body', null, function(chan) {
chan.resetInterception();
do_timeout(0, function() {
var gotexception = false;
try {
chan.cancelInterception();
} catch (x) {
gotexception = true;
}
Assert.ok(gotexception);
});
});
chan.asyncOpen2(new ChannelListener(handle_remote_response, null));
});
// ensure that the intercepted channel can be canceled during the response
add_test(function() {
var chan = make_channel(URL + '/body', null, function(intercepted) {
var synthesized = Cc["@mozilla.org/io/string-input-stream;1"]
.createInstance(Ci.nsIStringInputStream);
synthesized.data = NON_REMOTE_BODY;
let channel = intercepted.channel;
intercepted.startSynthesizedResponse(synthesized, null, null, '', false);
intercepted.finishSynthesizedResponse();
channel.cancel(Cr.NS_BINDING_ABORTED);
});
chan.asyncOpen2(new ChannelListener(run_next_test, null,
CL_EXPECT_FAILURE | CL_ALLOW_UNKNOWN_CL));
});
// ensure that the intercepted channel can be canceled before the response
add_test(function() {
var chan = make_channel(URL + '/body', null, function(intercepted) {
var synthesized = Cc["@mozilla.org/io/string-input-stream;1"]
.createInstance(Ci.nsIStringInputStream);
synthesized.data = NON_REMOTE_BODY;
intercepted.channel.cancel(Cr.NS_BINDING_ABORTED);
// This should not throw, but result in the channel firing callbacks
// with an error status.
intercepted.startSynthesizedResponse(synthesized, null, null, '', false);
intercepted.finishSynthesizedResponse();
});
chan.asyncOpen2(new ChannelListener(run_next_test, null,
CL_EXPECT_FAILURE | CL_ALLOW_UNKNOWN_CL));
});
// Ensure that nsIInterceptedChannel.channelIntercepted() can return an error.
// In this case we should automatically ResetInterception() and complete the
// network request.
add_test(function() {
var chan = make_channel(URL + '/body', null, function(chan) {
throw('boom');
});
chan.asyncOpen2(new ChannelListener(handle_remote_response, null));
});
add_test(function() {
httpServer.stop(run_next_test);
});