Skip to content

Commit

Permalink
DevTools: improve UX for hosted mode + fix bug
Browse files Browse the repository at this point in the history
This CL includes several quick improvements for hosted mode:
- Properly serves InspectorBackendCommands.js. It turns out the metadata from
the file is necessary for certain operations (e.g. $0 in the console).
- Can now customize remote debugging port in addition to server port
(e.g. REMOTE_DEBUGGING_PORT=9333 PORT=1234 npm run server)
- Provides helpful info if you go to server root path: (e.g. http://localhost:8090/).
As Paul pointed out, users may go here to check if the server is working.
“Please go to http://localhost:9222#http://localhost:8090/front_end/inspector.html?experiments=true”
(Note: it accounts for custom ports passed in)
- Add chrome favicon (same favicon as https://developer.chrome.com/devtools)

I'll update the docs with the RDP info once this CL has landed.

BUG=629914

Review-Url: https://codereview.chromium.org/2195113002
Cr-Commit-Position: refs/heads/master@{#409878}
  • Loading branch information
wwwillchen authored and Commit bot committed Aug 4, 2016
1 parent 180e6a4 commit 8974da1
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 39 deletions.
11 changes: 1 addition & 10 deletions front_end/inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,4 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Preload protocol resources for hosted mode.
if (!/** @type {?Object} */(window.InspectorFrontendHost)) {
Promise.all([
Runtime.loadResourceIntoCache("./sdk/protocol/browser_protocol.json", false /* appendSourceURL */),
Runtime.loadResourceIntoCache("./sdk/protocol/js_protocol.json", false /* appendSourceURL */)
]).then(() => Runtime.startApplication("inspector"));
} else {
Runtime.startApplication("inspector");
}

Runtime.startApplication("inspector");
50 changes: 21 additions & 29 deletions scripts/hosted_mode/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,20 @@ var http = require("http");
var https = require("https");
var path = require("path");
var parseURL = require("url").parse;
var Stream = require("stream").Transform;

var port = parseInt(process.env.PORT, 10) || 8090;
var remoteDebuggingPort = parseInt(process.env.REMOTE_DEBUGGING_PORT, 10) || 9222;
var serverPort = parseInt(process.env.PORT, 10) || 8090;

http.createServer(requestHandler).listen(port);
console.log("Started hosted mode server at http://localhost:" + port);
http.createServer(requestHandler).listen(serverPort);
console.log("Started hosted mode server at http://localhost:" + serverPort);

function requestHandler(request, response)
{
var filePath = parseURL(request.url).pathname;
if (filePath === "/front_end/InspectorBackendCommands.js") {
sendResponse(200, " ");
if (filePath === "/") {
sendResponse(200, `<html>Please go to <a href="http://localhost:${remoteDebuggingPort}#http://localhost:${serverPort}/front_end/inspector.html?experiments=true">
http://localhost:${remoteDebuggingPort}#http://localhost:${serverPort}/front_end/inspector.html?experiments=true</a></html>`);
return;
}

Expand All @@ -32,6 +35,7 @@ function requestHandler(request, response)
function handleProxyError(err)
{
console.log(`Error fetching over the internet file ${filePath}:`, err);
console.log(`Make sure you opened Chrome with the flag "--remote-debugging-port=${remoteDebuggingPort}"`);
sendResponse(500, "500 - Internal Server Error");
}

Expand Down Expand Up @@ -67,25 +71,14 @@ function requestHandler(request, response)
}

var proxyFilePathToURL = {
"/front_end/sdk/protocol/js_protocol.json": getWebKitURL.bind(null, "platform/v8_inspector/js_protocol.json"),
"/front_end/sdk/protocol/browser_protocol.json": getWebKitURL.bind(null, "core/inspector/browser_protocol.json"),
"/front_end/SupportedCSSProperties.js": getFrontendURL.bind(null, "SupportedCSSProperties.js")
"/front_end/SupportedCSSProperties.js": cloudURL.bind(null, "SupportedCSSProperties.js"),
"/front_end/InspectorBackendCommands.js": cloudURL.bind(null, "InspectorBackendCommands.js"),
"/favicon.ico": () => "https://chrome-devtools-frontend.appspot.com/favicon.ico"
};

function getWebKitURL(path, commitHash)
function cloudURL(path, commitHash)
{
return {
url: `https://chromium.googlesource.com/chromium/src/+/${commitHash}/third_party/WebKit/Source/${path}?format=TEXT`,
isBase64: true
}
}

function getFrontendURL(path, commitHash)
{
return {
url: `https://chrome-devtools-frontend.appspot.com/serve_file/@${commitHash}/${path}`,
isBase64: false
}
return `https://chrome-devtools-frontend.appspot.com/serve_file/@${commitHash}/${path}`;
}

var proxyFileCache = new Map();
Expand All @@ -94,20 +87,18 @@ function proxy(filePath)
{
if (!(filePath in proxyFilePathToURL))
return null;
return fetch("http://localhost:9222/json/version")
return fetch(`http://localhost:${remoteDebuggingPort}/json/version`)
.then(onBrowserMetadata);

function onBrowserMetadata(metadata)
{
var metadataObject = JSON.parse(metadata);
var match = metadataObject["WebKit-Version"].match(/\s\(@(\b[0-9a-f]{5,40}\b)/);
var commitHash = match[1];
var proxyFile = proxyFilePathToURL[filePath](commitHash);
var proxyFileURL = proxyFile.url;
var proxyFileURL = proxyFilePathToURL[filePath](commitHash);
if (proxyFileCache.has(proxyFileURL))
return proxyFileCache.get(proxyFileURL);
return fetch(proxyFileURL)
.then(text => proxyFile.isBase64 ? new Buffer(text, "base64").toString("binary") : text)
.then(cacheProxyFile.bind(null, proxyFileURL));
}

Expand All @@ -122,7 +113,8 @@ function fetch(url)
{
return new Promise(fetchPromise);

function fetchPromise(resolve, reject) {
function fetchPromise(resolve, reject)
{
var request;
var protocol = parseURL(url).protocol;
var handleResponse = getCallback.bind(null, resolve, reject);
Expand All @@ -143,9 +135,9 @@ function fetch(url)
reject(new Error(`Request error: + ${response.statusCode}`));
return;
}
var body = "";
response.on("data", chunk => body += chunk);
response.on("end", () => resolve(body));
var body = new Stream();
response.on("data", chunk => body.push(chunk));
response.on("end", () => resolve(body.read()));
}
}

5 comments on commit 8974da1

@darwin
Copy link
Member

@darwin darwin commented on 8974da1 Aug 4, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@willchen90 Just wondering if it would be possible for me to get InspectorBackendCommands.js and SupportedCSSProperties.js from embedded devtools somehow. I have Dirac Chrome Extension wrapping my DevTools fork, so I could probably use chrome extension APIs to fetch the files from embedded DevTools somehow.

@darwin
Copy link
Member

@darwin darwin commented on 8974da1 Aug 4, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recall @paulirish on IRC gave me once a chrome://... url to open embedded DevTools as a normal web app and that allowed me to tweak (experimental) DevTools's url params there. But I don't remember it anymore...

@paulirish
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@darwin wow good eye. :)

Here's that magic URL fwiw: chrome-devtools://devtools/bundled/inspector.html

getting the file locally

I'm not sure if you can access these files from an extension as they are in the frontend on chrome-devtools:// scheme, so i think you run into SOP problems.

inspectorbackendcommands are not in release builds of chrome, but you find them concat'd into `chrome-devtools://devtools/bundled/inspector.js':
image

So if you manage to pull that file, you can parse that. Sounds exciting.

getting the file from appspot

The file that we're using in this case is located here: https://chrome-devtools-frontend.appspot.com/serve_file/@ec732aad75df3788dff99e857d86f4100a48d34a/InspectorBackendCommands.js

That git hash is the chromium git revision. It's not exposed to javascript, but https://omahaproxy.appspot.com/deps.json?version=54.0.2816.4 will allow you to map the chrome version (in the UA) into chromium rev. I would recommend the chromium_base_commit.

We don't really maintain this as an API server so please don't hit it all the time. :)

gluck

@darwin
Copy link
Member

@darwin darwin commented on 8974da1 Aug 5, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a million! @paulirish.

@darwin
Copy link
Member

@darwin darwin commented on 8974da1 Aug 5, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@paulirish yeah, CSP gets in the way, tried several dead ends today, but it turned out that it is possible to get my hands at it with pageCapture permission, in my background page I automate chrome to open a new tab and navigate to chrome-devtools://devtools/bundled/inspector.js, I cannot inject content scripts or do anything useful with that page, except for pageCapture which gives me mhtml back, which I can process further:

Now it is just a matter of parsing that MIME format and "regex-ing" important parts out.


As a side note: Maybe the devtools team could consider exposing those files somehow from Chrome. The hosted mode dev-server could use that instead hitting your api/serve servers. (Not sure about security implications)

Please sign in to comment.