// Check that creating a Unix domain socket fails gracefully on Windows. function test_not_supported() {
let socketName = do_get_tempdir();
socketName.append("socket");
info("creating socket: " + socketName.path);
do_check_throws_nsIException(
() => new UnixServerSocket(socketName, allPermissions, -1), "NS_ERROR_SOCKET_ADDRESS_NOT_SUPPORTED"
);
// Actually exchange data with Unix domain sockets. function test_echo() {
let log = "";
let socketName = do_get_tempdir();
socketName.append("socket");
// Create a server socket, listening for connections.
info("creating socket: " + socketName.path);
let server = new UnixServerSocket(socketName, allPermissions, -1);
server.asyncListen({
onSocketAccepted(aServ, aTransport) {
info("called test_echo's onSocketAccepted");
log += "a";
Assert.equal(aServ, server);
let connection = aTransport;
// Check the server socket's self address.
let connectionSelfAddr = connection.getScriptableSelfAddr(); Assert.equal(connectionSelfAddr.family, Ci.nsINetAddr.FAMILY_LOCAL); Assert.equal(connectionSelfAddr.address, socketName.path);
// The client socket is anonymous, so the server transport should // have an empty peer address. Assert.equal(connection.host, ""); Assert.equal(connection.port, 0);
let connectionPeerAddr = connection.getScriptablePeerAddr(); Assert.equal(connectionPeerAddr.family, Ci.nsINetAddr.FAMILY_LOCAL); Assert.equal(connectionPeerAddr.address, "");
let serverAsyncInput = connection
.openInputStream(0, 0, 0)
.QueryInterface(Ci.nsIAsyncInputStream);
let serverOutput = connection.openOutputStream(0, 0, 0);
serverAsyncInput.asyncWait( function (aStream) {
info("called test_echo's server's onInputStreamReady");
let serverScriptableInput = new ScriptableInputStream(aStream);
// Receive data from the client, and send back a response. Assert.equal(
serverScriptableInput.readBytes(17), "Mervyn Murgatroyd"
);
info("server has read message from client");
serverOutput.write("Ruthven Murgatroyd", 18);
info("server has written to client");
},
0,
0,
threadManager.currentThread
);
},
// Create a client socket, and connect to the server.
let client = socketTransportService.createUnixDomainTransport(socketName); Assert.equal(client.host, socketName.path); Assert.equal(client.port, 0);
let clientAsyncInput = client
.openInputStream(0, 0, 0)
.QueryInterface(Ci.nsIAsyncInputStream);
let clientInput = new ScriptableInputStream(clientAsyncInput);
let clientOutput = client.openOutputStream(0, 0, 0);
clientOutput.write("Mervyn Murgatroyd", 17);
info("client has written to server");
// Now that the connection has been established, we can check the // transport's self and peer addresses.
let clientSelfAddr = client.getScriptableSelfAddr(); Assert.equal(clientSelfAddr.family, Ci.nsINetAddr.FAMILY_LOCAL); Assert.equal(clientSelfAddr.address, "");
Assert.equal(client.host, socketName.path); // re-check, but hey
let clientPeerAddr = client.getScriptablePeerAddr(); Assert.equal(clientPeerAddr.family, Ci.nsINetAddr.FAMILY_LOCAL); Assert.equal(clientPeerAddr.address, socketName.path);
Assert.equal(clientInput.readBytes(18), "Ruthven Murgatroyd");
info("client has read message from server");
// Create client and server sockets using a path that's too long. function test_name_too_long() {
let socketName = do_get_tempdir(); // The length limits on all the systems NSPR supports are a bit past 100.
socketName.append(new Array(1000).join("x"));
// The length must be checked before we ever make any system calls --- we // have to create the sockaddr first --- so it's unambiguous which error // we should get here.
do_check_throws_nsIException(
() => new UnixServerSocket(socketName, 0, -1), "NS_ERROR_FILE_NAME_TOO_LONG"
);
// Unlike most other client socket errors, this one gets reported // immediately, as we can't even initialize the sockaddr with the given // name.
do_check_throws_nsIException(
() => socketTransportService.createUnixDomainTransport(socketName), "NS_ERROR_FILE_NAME_TOO_LONG"
);
run_next_test();
}
// Try creating a socket in a directory that doesn't exist. function test_no_directory() {
let socketName = do_get_tempdir();
socketName.append("missing");
socketName.append("socket");
do_check_throws_nsIException(
() => new UnixServerSocket(socketName, 0, -1), "NS_ERROR_FILE_NOT_FOUND"
);
run_next_test();
}
// Try connecting to a server socket that isn't there. function test_no_such_socket() {
let socketName = do_get_tempdir();
socketName.append("nonexistent-socket");
let client = socketTransportService.createUnixDomainTransport(socketName);
let clientAsyncInput = client
.openInputStream(0, 0, 0)
.QueryInterface(Ci.nsIAsyncInputStream);
clientAsyncInput.asyncWait( function (aStream) {
info("called test_no_such_socket's onInputStreamReady");
Assert.equal(aStream, clientAsyncInput);
// nsISocketTransport puts off actually creating sockets as long as // possible, so the error in connecting doesn't actually show up until // this point.
do_check_throws_nsIException(
() => clientAsyncInput.available(), "NS_ERROR_FILE_NOT_FOUND"
);
// Creating a socket with a name that another socket is already using is an // error. function test_address_in_use() {
let socketName = do_get_tempdir();
socketName.append("socket-in-use");
// Create one server socket. new UnixServerSocket(socketName, allPermissions, -1);
// Now try to create another with the same name.
do_check_throws_nsIException(
() => new UnixServerSocket(socketName, allPermissions, -1), "NS_ERROR_SOCKET_ADDRESS_IN_USE"
);
run_next_test();
}
// Creating a socket with a name that is already a file is an error. function test_file_in_way() {
let socketName = do_get_tempdir();
socketName.append("file_in_way");
// Create a file with the given name.
socketName.create(Ci.nsIFile.NORMAL_FILE_TYPE, allPermissions);
// Try to create a socket with the same name.
do_check_throws_nsIException(
() => new UnixServerSocket(socketName, allPermissions, -1), "NS_ERROR_SOCKET_ADDRESS_IN_USE"
);
// Try to create a socket under a name that uses that as a parent directory.
socketName.append("socket");
do_check_throws_nsIException(
() => new UnixServerSocket(socketName, 0, -1), "NS_ERROR_FILE_NOT_DIRECTORY"
);
run_next_test();
}
// It is not permitted to create a socket in a directory which we are not // permitted to execute, or create files in. function test_create_permission() {
let dirName = do_get_tempdir();
dirName.append("unfriendly");
let socketName = dirName.clone();
socketName.append("socket");
// The test harness has difficulty cleaning things up if we don't make // everything writable before we're done. try { // Create a directory which we are not permitted to search.
dirName.create(Ci.nsIFile.DIRECTORY_TYPE, 0);
// Try to create a socket in that directory. Because Linux returns EACCES // when a 'connect' fails because of a local firewall rule, // nsIServerSocket returns NS_ERROR_CONNECTION_REFUSED in this case.
do_check_throws_nsIException(
() => new UnixServerSocket(socketName, allPermissions, -1), "NS_ERROR_CONNECTION_REFUSED"
);
// Grant read and execute permission, but not write permission on the directory.
dirName.permissions = parseInt("0555", 8);
// This should also fail; we need write permission.
do_check_throws_nsIException(
() => new UnixServerSocket(socketName, allPermissions, -1), "NS_ERROR_CONNECTION_REFUSED"
);
} finally { // Make the directory writable, so the test harness can clean it up.
dirName.permissions = allPermissions;
}
// This should succeed, since we now have all the permissions on the // directory we could want.
do_check_instanceof( new UnixServerSocket(socketName, allPermissions, -1),
Ci.nsIServerSocket
);
run_next_test();
}
// To connect to a Unix domain socket, we need search permission on the // directories containing it, and some kind of permission or other on the // socket itself. function test_connect_permission() { // This test involves a lot of callbacks, but they're written out so that // the actual control flow proceeds from top to bottom.
let log = "";
// Create a directory which we are permitted to search - at first.
let dirName = do_get_tempdir();
dirName.append("inhospitable");
dirName.create(Ci.nsIFile.DIRECTORY_TYPE, allPermissions);
let socketName = dirName.clone();
socketName.append("socket");
// Create a server socket in that directory, listening for connections, // and accessible.
let server = new UnixServerSocket(socketName, allPermissions, -1);
server.asyncListen({
onSocketAccepted: socketAccepted,
onStopListening: stopListening,
});
// Make the directory unsearchable.
dirName.permissions = 0;
let client3;
let client1 = socketTransportService.createUnixDomainTransport(socketName);
let client1AsyncInput = client1
.openInputStream(0, 0, 0)
.QueryInterface(Ci.nsIAsyncInputStream);
client1AsyncInput.asyncWait( function () {
info("called test_connect_permission's client1's onInputStreamReady");
log += "1";
// nsISocketTransport puts off actually creating sockets as long as // possible, so the error doesn't actually show up until this point.
do_check_throws_nsIException(
() => client1AsyncInput.available(), "NS_ERROR_CONNECTION_REFUSED"
);
// Receive data from the client, and send back a response.
let serverScriptableInput = new ScriptableInputStream(serverInput); Assert.equal(serverScriptableInput.readBytes(8), "Hanratty");
serverOutput.write("Ferlingatti", 11);
},
0,
0,
threadManager.currentThread
);
}
function client3InputStreamReady(aStream) {
info("called client3's onInputStreamReady");
log += "3";
let client3Input = new ScriptableInputStream(aStream);
function stopListening() {
info("called test_connect_permission's server's stopListening");
log += "s";
Assert.equal(log, "12ai3s");
run_next_test();
}
}
// Creating a socket with a long filename doesn't crash. function test_long_socket_name() {
let socketName = do_get_tempdir();
socketName.append(new Array(10000).join("long"));
// Try to create a server socket with the long name.
do_check_throws_nsIException(
() => new UnixServerSocket(socketName, allPermissions, -1), "NS_ERROR_FILE_NAME_TOO_LONG"
);
// Try to connect to a socket with the long name.
do_check_throws_nsIException(
() => socketTransportService.createUnixDomainTransport(socketName), "NS_ERROR_FILE_NAME_TOO_LONG"
);
run_next_test();
}
// Going offline should not shut down Unix domain sockets. function test_keep_when_offline() {
let log = "";
let socketName = do_get_tempdir();
socketName.append("keep-when-offline");
// Create a listening socket.
let listener = new UnixServerSocket(socketName, allPermissions, -1);
listener.asyncListen({ onSocketAccepted: onAccepted, onStopListening });
// Connect a client socket to the listening socket.
let client = socketTransportService.createUnixDomainTransport(socketName);
let clientOutput = client.openOutputStream(0, 0, 0);
let clientInput = client.openInputStream(0, 0, 0);
clientInput.asyncWait(clientReady, 0, 0, threadManager.currentThread);
let clientScriptableInput = new ScriptableInputStream(clientInput);
let server, serverInput, serverScriptableInput, serverOutput;
// How many times has the server invited the client to go first?
let count = 0;
// The server accepted connection callback. function onAccepted(aListener, aServer) {
info("test_keep_when_offline: onAccepted called");
log += "a"; Assert.equal(aListener, listener);
server = aServer;
// Prepare to receive messages from the client.
serverInput = server.openInputStream(0, 0, 0);
serverInput.asyncWait(serverReady, 0, 0, threadManager.currentThread);
serverScriptableInput = new ScriptableInputStream(serverInput);
// Start a conversation with the client.
serverOutput = server.openOutputStream(0, 0, 0);
serverOutput.write("After you, Alphonse!", 20);
count++;
}
// The client has seen its end of the socket close. function clientReady(aStream) {
log += "c";
info("test_keep_when_offline: clientReady called: " + log); Assert.equal(aStream, clientInput);
// If the connection has been closed, end the conversation and stop listening.
let available; try {
available = clientInput.available();
} catch (ex) {
do_check_instanceof(ex, Ci.nsIException); Assert.equal(ex.result, Cr.NS_BASE_STREAM_CLOSED);
info("client received end-of-stream; closing client output stream");
log += ")";
client.close(Cr.NS_OK);
// Now both output streams have been closed, and both input streams // have received the close notification. Stop listening for // connections.
listener.close();
}
if (available) { // Check the message from the server. Assert.equal(clientScriptableInput.readBytes(20), "After you, Alphonse!");
// Write our response to the server.
clientOutput.write("No, after you, Gaston!", 22);
// Ask to be called again, when more input arrives.
clientInput.asyncWait(clientReady, 0, 0, threadManager.currentThread);
}
}
// Check the message from the client. Assert.equal(serverScriptableInput.readBytes(22), "No, after you, Gaston!");
// This should not shut things down: Unix domain sockets should // remain open in offline mode. if (count == 5) {
Services.io.offline = true;
log += "o";
}
// As long as the input stream is open, always ask to be called again // when more input arrives.
serverInput.asyncWait(serverReady, 0, 0, threadManager.currentThread);
} elseif (count == 10) { // After sending ten times and receiving ten replies, we're not // going to send any more. Close the server's output stream; the // client's input stream should see this.
info("closing server transport");
server.close(Cr.NS_OK);
log += "(";
}
}
// We have stopped listening. function onStopListening(aServ, aStatus) {
info("test_keep_when_offline: onStopListening called");
log += "L"; Assert.equal(log, "acscscscscsocscscscscs(c)L");
// Receive data from the client, and send back a response.
let serverScriptableInput = new ScriptableInputStream(serverInput); Assert.equal(serverScriptableInput.readBytes(9), "ping ping");
serverOutput.write("pong", 4);
},
0,
0,
threadManager.currentThread
);
},
onStopListening: () => {},
});
let client =
socketTransportService.createUnixDomainAbstractAddressTransport(socketname); Assert.equal(client.host, socketname); Assert.equal(client.port, 0);
let clientInput = client
.openInputStream(0, 0, 0)
.QueryInterface(Ci.nsIAsyncInputStream);
let clientOutput = client.openOutputStream(0, 0, 0);
clientOutput.write("ping ping", 9);
clientInput.asyncWait(
() => {
let clientScriptInput = new ScriptableInputStream(clientInput);
let available = clientScriptInput.available(); if (available) { Assert.equal(clientScriptInput.readBytes(4), "pong");
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 und die Messung sind noch experimentell.