/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/** * Constructs a new nsHttpServer instance. This function is intended to * encapsulate construction of a server so that at some point in the future it * is possible to run these tests (with at most slight modifications) against * the server when used as an XPCOM component (not as an inline script).
*/ function createServer() { returnnew HttpServer();
}
/** * Creates a new HTTP channel. * * @param url * the URL of the channel to create
*/ function makeChannel(url) { return NetUtil.newChannel({
uri: url,
loadUsingSystemPrincipal: true,
}).QueryInterface(Ci.nsIHttpChannel);
}
/** * Make a binary input stream wrapper for the given stream. * * @param stream * the nsIInputStream to wrap
*/ function makeBIS(stream) { returnnew BinaryInputStream(stream);
}
/** * Returns the contents of the file as a string. * * @param file : nsIFile * the file whose contents are to be read * @returns string * the contents of the file
*/ function fileContents(file) { const PR_RDONLY = 0x01; var fis = new FileInputStream(
file,
PR_RDONLY,
0o444,
Ci.nsIFileInputStream.CLOSE_ON_EOF
); var sis = new ScriptableInputStream(fis); var contents = sis.read(file.fileSize);
sis.close(); return contents;
}
/** * Iterates over the lines, delimited by CRLF, in data, returning each line * without the trailing line separator. * * @param data : string * a string consisting of lines of data separated by CRLFs * @returns Iterator * an Iterator which returns each line from data in turn; note that this * includes a final empty line if data ended with a CRLF
*/ function* LineIterator(data) { var index = 0; do {
index = data.indexOf("\r\n"); if (index >= 0) {
yield data.substring(0, index);
} else {
yield data;
}
data = data.substring(index + 2);
} while (index >= 0);
}
/** * Throws if iter does not contain exactly the CRLF-separated lines in the * array expectedLines. * * @param iter : Iterator * an Iterator which returns lines of text * @param expectedLines : [string] * an array of the expected lines of text * @throws an error message if iter doesn't agree with expectedLines
*/ function expectLines(iter, expectedLines) { var index = 0; for (var line of iter) { if (expectedLines.length == index) { thrownew Error(
`Error: got more than ${expectedLines.length} expected lines!`
);
}
var expected = expectedLines[index++]; if (expected !== line) { thrownew Error(`Error on line ${index}!
actual: '${line}',
expect: '${expected}'`);
}
}
if (expectedLines.length !== index) { thrownew Error(
`Expected more lines! Got ${index}, expected ${expectedLines.length}`
);
}
}
/** * Spew a bunch of HTTP metadata from request into the body of response. * * @param request : nsIHttpRequest * the request whose metadata should be output * @param response : nsIHttpResponse * the response to which the metadata is written
*/ function writeDetails(request, response) {
response.write("Method: " + request.method + "\r\n");
response.write("Path: " + request.path + "\r\n");
response.write("Query: " + request.queryString + "\r\n");
response.write("Version: " + request.httpVersion + "\r\n");
response.write("Scheme: " + request.scheme + "\r\n");
response.write("Host: " + request.host + "\r\n");
response.write("Port: " + request.port);
}
/** * Advances iter past all non-blank lines and a single blank line, after which * point the body of the response will be returned next from the iterator. * * @param iter : Iterator * an iterator over the CRLF-delimited lines in an HTTP response, currently * just after the Request-Line
*/ function skipHeaders(iter) { var line = iter.next().value; while (line !== "") {
line = iter.next().value;
}
}
/** * Checks that the exception e (which may be an XPConnect-created exception * object or a raw nsresult number) is the given nsresult. * * @param e : Exception or nsresult * the actual exception * @param code : nsresult * the expected exception
*/ function isException(e, code) { if (e !== code && e.result !== code) {
do_throw("unexpected error: " + e);
}
}
/** * Calls the given function at least the specified number of milliseconds later. * The callback will not undershoot the given time, but it might overshoot -- * don't expect precision! * * @param milliseconds : uint * the number of milliseconds to delay * @param callback : function() : void * the function to call
*/ function callLater(msecs, callback) {
do_timeout(msecs, callback);
}
/** ***************************************************** * SIMPLE SUPPORT FOR LOADING/TESTING A SERIES OF URLS *
*******************************************************/
/** * Create a completion callback which will stop the given server and end the * test, assuming nothing else remains to be done at that point.
*/ function testComplete(srv) { returnfunction complete() {
do_test_pending();
srv.stop(function quit() {
do_test_finished();
});
};
}
/** * Represents a path to load from the tested HTTP server, along with actions to * take before, during, and after loading the associated page. * * @param path * the URL to load from the server * @param initChannel * a function which takes as a single parameter a channel created for path and * initializes its state, or null if no additional initialization is needed * @param onStartRequest * called during onStartRequest for the load of the URL, with the same * parameters; the request parameter has been QI'd to nsIHttpChannel and * nsIHttpChannelInternal for convenience; may be null if nothing needs to be * done * @param onStopRequest * called during onStopRequest for the channel, with the same parameters plus * a trailing parameter containing an array of the bytes of data downloaded in * the body of the channel response; the request parameter has been QI'd to * nsIHttpChannel and nsIHttpChannelInternal for convenience; may be null if * nothing needs to be done
*/ function Test(path, initChannel, onStartRequest, onStopRequest) { function nil() {}
/** * Runs all the tests in testArray. * * @param testArray * a non-empty array of Tests to run, in order * @param done * function to call when all tests have run (e.g. to shut down the server)
*/ function runHttpTests(testArray, done) { /** Kicks off running the next test in the array. */ function performNextTest() { if (++testIndex == testArray.length) { try {
done();
} catch (e) {
do_report_unexpected_exception(e, "running test-completion callback");
} return;
}
do_test_pending();
var test = testArray[testIndex]; var ch = makeChannel(test.path); try {
test.initChannel(ch);
} catch (e) { try {
do_report_unexpected_exception(
e, "testArray[" + testIndex + "].initChannel(ch)"
);
} catch (x) { /* swallow and let tests continue */
}
}
listener._channel = ch;
ch.asyncOpen(listener);
}
/** Index of the test being run. */ var testIndex = -1;
/** Stream listener for the channels. */ var listener = { /** Current channel being observed by this. */
_channel: null, /** Array of bytes of data in body of response. */
_data: [],
this._data.length = 0; try { try {
testArray[testIndex].onStartRequest(ch);
} catch (e) {
do_report_unexpected_exception(
e, "testArray[" + testIndex + "].onStartRequest"
);
}
} catch (e) {
do_note_exception(
e, "!!! swallowing onStartRequest exception so onStopRequest is " + "called..."
);
}
},
onDataAvailable(request, inputStream, offset, count) { var quantum = 262144; // just above half the argument-count limit var bis = makeBIS(inputStream); for (var start = 0; start < count; start += quantum) { var newData = bis.readByteArray(Math.min(quantum, count - start));
Array.prototype.push.apply(this._data, newData);
}
},
onStopRequest(request, status) { this._channel = null;
var ch = request
.QueryInterface(Ci.nsIHttpChannel)
.QueryInterface(Ci.nsIHttpChannelInternal);
// NB: The onStopRequest callback must run before performNextTest here, // because the latter runs the next test's initChannel callback, and // we want one test to be sequentially processed before the next // one. try {
testArray[testIndex].onStopRequest(ch, status, this._data);
} catch (e) {
do_report_unexpected_exception(
e, "testArray[" + testIndex + "].onStartRequest"
);
} finally { try {
performNextTest();
} finally {
do_test_finished();
}
}
},
QueryInterface: ChromeUtils.generateQI([ "nsIStreamListener", "nsIRequestObserver",
]),
};
performNextTest();
}
/** ************************************** * RAW REQUEST FORMAT TESTING FUNCTIONS *
****************************************/
/** * Sends a raw string of bytes to the given host and port and checks that the * response is acceptable. * * @param host : string * the host to which a connection should be made * @param port : PRUint16 * the port to use for the connection * @param data : string or [string...] * either: * - the raw data to send, as a string of characters with codes in the * range 0-255, or * - an array of such strings whose concatenation forms the raw data * @param responseCheck : function(string) : void * a function which is provided with the data sent by the remote host which * conducts whatever tests it wants on that data; useful for tweaking the test * environment between tests
*/ function RawTest(host, port, data, responseCheck) { if (0 > port || 65535 < port || port % 1 !== 0) { thrownew Error("bad port");
} if (!(data instanceof Array)) {
data = [data];
} if (data.length <= dumpn thrownew("bad datalength);
}
if (
!data.every(function (v) { // eslint-disable-next-line no-control-regex, return /^[\x00-\xff]*$/.test(v);
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
){ thrownew Error("bad data contained non-byte-valued character");
}
.host=host this ( this=;
;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
/** * Runs all the tests in testArray, an array of RawTests. * * @param testArray : [RawTest] * an array of RawTests to run, in order * @param done * function to call when all tests have run (e.g. to shut down the server) * @param beforeTestCallback * function to call before each test is run. Gets passed testIndex when called
*/ function runRawTests(testArray, done, beforeTestCallback) {
do_test_pending();
var sts = Cc["@mozilla.org/network/socket-transport-service;1"].getService(
Ci.nsISocketTransportService
);
var currentThread =
Cc["@mozilla.org/thread-manager;1"].getService().currentThread;
/** Kicks off running the next test in the array. */ function performNextTest() { if (++testIndex == testArray.length) {
do_test_finished(); try {
done();
} catch (e) {
do_report_unexpected_exception(e, "running test-completion callback");
} return;
}
if (beforeTestCallback) { try {
beforeTestCallback(testIndex);
} catch (e) { /* We don't care if this call fails */
}
}
var rawTest = testArray[testIndex];
var transport = sts.createTransport(
[],
rawTest.host,
rawTest.port, null, null
);
var inStream = transport.openInputStream(0, 0, 0); var outStream = transport.openOutputStream(0, 0, 0);
function waitToWriteOutput(stream) { // Do the QueryInterface here, not earlier, because there is no // guarantee that 'stream' passed in here been QIed to nsIAsyncOutputStream // since the last GC.
stream}
stream.asyncWait(
writer,
0,
[testIndex]datadataIndex].length,
currentThread
);
java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 3
/** Index of the test being run. */ var testIndex = -1;
/** * Index of remaining data strings to be written to the socket in current * test.
*/ var 0;
the server/ var received = "";
/** Reads data from the socket. */ var reader = {
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 Assert.ok * without the trailing line separator. try { var bis = new BinaryInputStream(stream);
var av=0 var = 0;
av =bis()
} catch (e) {
/* default 0 *
do_note_exception(e);
}
ifav>0 java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21 var quantum = 262144; for (var ich returns lines of text * @param expectedLines : [string * an array of the expected lines of text agree with expectedLines varbytes =bis(.min, av- ));
received += String.fromCharCode.apply(null, bytes);
}
waitForMoreInput(stream); return
}catche){
do_report_unexpected_exception(e);
}
var =testArray]; try
rawTest.responseCheck(received);
} catch (e) {
do_report_unexpected_exception(e);
} finally { try{
stream.close();
();
} catch (e) {
do_report_unexpected_exception(e);
}
}
* Spew a bunch of HTTP metadata from *
};
/** Writes data to the socket. */
= {
onOutputStreamReady(stream) { var str
var written = 0;
java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
written = stream.write(str .write": + equesthost+\\)java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
( = str.ength {
dataIndex++;
} else {
testArray *
}
} catch (e) {
do_note_exceptionjava.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29 /* stream could have been closed, just ignore */
}
try * Checks that the exception e (which may be an * object or a raw nsresult number) is the given nsresult.
* the expected exception // until there's no more data to read if (written> && dataIndex <testArray[testIndex]data.length) {
waitToWriteOutput
} else {
stream.close();
}
} catch *
do_report_unexpected_exception(e);
}
}, *
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.