target-from-url.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. "use strict";
  5. const { Cu, Ci } = require("chrome");
  6. const { TargetFactory } = require("devtools/client/framework/target");
  7. const { DebuggerServer } = require("devtools/server/main");
  8. const { DebuggerClient } = require("devtools/shared/client/main");
  9. const { Task } = require("devtools/shared/task");
  10. /**
  11. * Construct a Target for a given URL object having various query parameters:
  12. *
  13. * host:
  14. * {String} The hostname or IP address to connect to.
  15. * port:
  16. * {Number} The TCP port to connect to, to use with `host` argument.
  17. * ws:
  18. * {Boolean} If true, connect via websocket instread of regular TCP connection.
  19. *
  20. * type: tab, process
  21. * {String} The type of target to connect to. Currently tabs and processes are supported types.
  22. *
  23. * If type="tab":
  24. * id:
  25. * {Number} the tab outerWindowID
  26. * chrome: Optional
  27. * {Boolean} Force the creation of a chrome target. Gives more privileges to the tab
  28. * actor. Allows chrome execution in the webconsole and see chrome files in
  29. * the debugger. (handy when contributing to firefox)
  30. *
  31. * If type="process":
  32. * id:
  33. * {Number} the process id to debug. Default to 0, which is the parent process.
  34. *
  35. * @param {URL} url
  36. * The url to fetch query params from.
  37. *
  38. * @return A target object
  39. */
  40. exports.targetFromURL = Task.async(function* (url) {
  41. let params = url.searchParams;
  42. let type = params.get("type");
  43. if (!type) {
  44. throw new Error("targetFromURL, missing type parameter");
  45. }
  46. let id = params.get("id");
  47. // Allows to spawn a chrome enabled target for any context
  48. // (handy to debug chrome stuff in a child process)
  49. let chrome = params.has("chrome");
  50. let client = yield createClient(params);
  51. yield client.connect();
  52. let form, isTabActor;
  53. if (type === "tab") {
  54. // Fetch target for a remote tab
  55. id = parseInt(id);
  56. if (isNaN(id)) {
  57. throw new Error("targetFromURL, wrong tab id:'" + id + "', should be a number");
  58. }
  59. try {
  60. let response = yield client.getTab({ outerWindowID: id });
  61. form = response.tab;
  62. } catch (ex) {
  63. if (ex.error == "noTab") {
  64. throw new Error("targetFromURL, tab with outerWindowID:'" + id + "' doesn't exist");
  65. }
  66. throw ex;
  67. }
  68. } else if (type == "process") {
  69. // Fetch target for a remote chrome actor
  70. DebuggerServer.allowChromeProcess = true;
  71. try {
  72. id = parseInt(id);
  73. if (isNaN(id)) {
  74. id = 0;
  75. }
  76. let response = yield client.getProcess(id);
  77. form = response.form;
  78. chrome = true;
  79. if (id != 0) {
  80. // Child process are not exposing tab actors and only support debugger+console
  81. isTabActor = false;
  82. }
  83. } catch (ex) {
  84. if (ex.error == "noProcess") {
  85. throw new Error("targetFromURL, process with id:'" + id + "' doesn't exist");
  86. }
  87. throw ex;
  88. }
  89. } else {
  90. throw new Error("targetFromURL, unsupported type='" + type + "' parameter");
  91. }
  92. return TargetFactory.forRemoteTab({ client, form, chrome, isTabActor });
  93. });
  94. function* createClient(params) {
  95. let host = params.get("host");
  96. let port = params.get("port");
  97. let webSocket = !!params.get("ws");
  98. let transport;
  99. if (port) {
  100. transport = yield DebuggerClient.socketConnect({ host, port, webSocket });
  101. } else {
  102. // Setup a server if we don't have one already running
  103. if (!DebuggerServer.initialized) {
  104. DebuggerServer.init();
  105. DebuggerServer.addBrowserActors();
  106. }
  107. transport = DebuggerServer.connectPipe()
  108. }
  109. return new DebuggerClient(transport);
  110. }