Bug 1299503 - Support connecting to remote targets via about:devtools-toolbox query parameters. r=jryans

MozReview-Commit-ID: 7EFCxnKkO6r

--HG--
extra : rebase_source : 608d56b766741cbb2a881c1a5f82223e79e758a0
This commit is contained in:
Alexandre Poirot 2016-08-31 07:42:23 -07:00
Родитель cc08d3d97e
Коммит f936a9a24c
4 изменённых файлов: 116 добавлений и 20 удалений

Просмотреть файл

@ -14,6 +14,13 @@ const { Task } = require("devtools/shared/task");
/**
* Construct a Target for a given URL object having various query parameters:
*
* host:
* {String} The hostname or IP address to connect to.
* port:
* {Number} The TCP port to connect to, to use with `host` argument.
* ws:
* {Boolean} If true, connect via websocket instread of regular TCP connection.
*
* type: tab, process
* {String} The type of target to connect to. Currently tabs and processes are supported types.
*
@ -45,9 +52,7 @@ exports.targetFromURL = Task.async(function* (url) {
// (handy to debug chrome stuff in a child process)
let chrome = params.has("chrome");
// Once about:debugging start supporting remote targets and use this helper,
// client will also be defined by url params.
let client = createClient();
let client = yield createClient(params);
yield client.connect();
@ -95,12 +100,21 @@ exports.targetFromURL = Task.async(function* (url) {
return TargetFactory.forRemoteTab({ client, form, chrome, isTabActor });
});
function createClient() {
// Setup a server if we don't have one already running
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addBrowserActors();
}
function* createClient(params) {
let host = params.get("host");
let port = params.get("port");
let webSocket = !!params.get("ws");
return new DebuggerClient(DebuggerServer.connectPipe());
let transport;
if (port) {
transport = yield DebuggerClient.socketConnect({ host, port, webSocket });
} else {
// Setup a server if we don't have one already running
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addBrowserActors();
}
transport = DebuggerServer.connectPipe()
}
return new DebuggerClient(transport);
}

Просмотреть файл

@ -4,10 +4,19 @@
const TEST_URI = "data:text/html;charset=utf-8," +
"<p>browser_target-from-url.js</p>";
const { DevToolsLoader } = Cu.import("resource://devtools/shared/Loader.jsm", {});
const { targetFromURL } = require("devtools/client/framework/target-from-url");
function assertIsTabTarget(target, chrome = false) {
is(target.url, TEST_URI);
Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
Services.prefs.setBoolPref("devtools.debugger.prompt-connection", false);
SimpleTest.registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.debugger.remote-enabled");
Services.prefs.clearUserPref("devtools.debugger.prompt-connection");
});
function assertIsTabTarget(target, url, chrome = false) {
is(target.url, url);
is(target.isLocalTab, false);
is(target.chrome, chrome);
is(target.isTabActor, true);
@ -30,11 +39,11 @@ add_task(function* () {
info("Test tab");
let windowId = browser.outerWindowID;
target = yield targetFromURL(new URL("http://foo?type=tab&id=" + windowId));
assertIsTabTarget(target);
assertIsTabTarget(target, TEST_URI);
info("Test tab with chrome privileges");
target = yield targetFromURL(new URL("http://foo?type=tab&id=" + windowId + "&chrome"));
assertIsTabTarget(target, true);
assertIsTabTarget(target, TEST_URI, true);
info("Test invalid tab id");
try {
@ -47,12 +56,78 @@ add_task(function* () {
info("Test parent process");
target = yield targetFromURL(new URL("http://foo?type=process"));
let topWindow = Services.wm.getMostRecentWindow("navigator:browser");
is(target.url, topWindow.location.href);
is(target.isLocalTab, false);
is(target.chrome, true);
is(target.isTabActor, true);
is(target.isRemote, true);
assertIsTabTarget(target, topWindow.location.href, true);
yield testRemoteTCP();
yield testRemoteWebSocket();
yield target.client.close();
gBrowser.removeCurrentTab();
});
function* setupDebuggerServer(websocket) {
info("Create a separate loader instance for the DebuggerServer.");
let loader = new DevToolsLoader();
let { DebuggerServer } = loader.require("devtools/server/main");
DebuggerServer.init();
DebuggerServer.addBrowserActors();
DebuggerServer.allowChromeProcess = true;
let listener = DebuggerServer.createListener();
ok(listener, "Socket listener created");
// Pass -1 to automatically choose an available port
listener.portOrPath = -1;
listener.webSocket = websocket;
yield listener.open();
is(DebuggerServer.listeningSockets, 1, "1 listening socket");
return { DebuggerServer, listener };
}
function teardownDebuggerServer({ DebuggerServer, listener }) {
info("Close the listener socket");
listener.close();
is(DebuggerServer.listeningSockets, 0, "0 listening sockets");
info("Destroy the temporary debugger server");
DebuggerServer.destroy();
}
function* testRemoteTCP() {
info("Test remote process via TCP Connection");
let server = yield setupDebuggerServer(false);
let { port } = server.listener;
let target = yield targetFromURL(new URL("http://foo?type=process&host=127.0.0.1&port=" + port));
let topWindow = Services.wm.getMostRecentWindow("navigator:browser");
assertIsTabTarget(target, topWindow.location.href, true);
let settings = target.client._transport.connectionSettings;
is(settings.host, "127.0.0.1");
is(settings.port, port);
is(settings.webSocket, false);
yield target.client.close();
teardownDebuggerServer(server);
}
function* testRemoteWebSocket() {
info("Test remote process via WebSocket Connection");
let server = yield setupDebuggerServer(true);
let { port } = server.listener;
let target = yield targetFromURL(new URL("http://foo?type=process&host=127.0.0.1&port=" + port + "&ws=true"));
let topWindow = Services.wm.getMostRecentWindow("navigator:browser");
assertIsTabTarget(target, topWindow.location.href, true);
let settings = target.client._transport.connectionSettings;
is(settings.host, "127.0.0.1");
is(settings.port, port);
is(settings.webSocket, true);
yield target.client.close();
teardownDebuggerServer(server);
}

Просмотреть файл

@ -90,6 +90,7 @@ DebuggerSocket.connect = Task.async(function* (settings) {
cert,
transport
});
transport.connectionSettings = settings;
return transport;
});

Просмотреть файл

@ -45,6 +45,12 @@ function* test_socket_conn()
host: "127.0.0.1",
port: gPort
});
// Assert that connection settings are available on transport object
let settings = transport.connectionSettings;
do_check_eq(settings.host, "127.0.0.1");
do_check_eq(settings.port, gPort);
let closedDeferred = defer();
transport.hooks = {
onPacket: function (aPacket) {