| OLD | NEW |
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 var fs = require("fs"); | 5 var fs = require("fs"); |
| 6 var http = require("http"); | 6 var http = require("http"); |
| 7 var https = require("https"); | 7 var https = require("https"); |
| 8 var path = require("path"); | 8 var path = require("path"); |
| 9 var parseURL = require("url").parse; | 9 var parseURL = require("url").parse; |
| 10 var Stream = require("stream").Transform; |
| 10 | 11 |
| 11 var port = parseInt(process.env.PORT, 10) || 8090; | 12 var remoteDebuggingPort = parseInt(process.env.REMOTE_DEBUGGING_PORT, 10) || 922
2; |
| 13 var serverPort = parseInt(process.env.PORT, 10) || 8090; |
| 12 | 14 |
| 13 http.createServer(requestHandler).listen(port); | 15 http.createServer(requestHandler).listen(serverPort); |
| 14 console.log("Started hosted mode server at http://localhost:" + port); | 16 console.log("Started hosted mode server at http://localhost:" + serverPort); |
| 15 | 17 |
| 16 function requestHandler(request, response) | 18 function requestHandler(request, response) |
| 17 { | 19 { |
| 18 var filePath = parseURL(request.url).pathname; | 20 var filePath = parseURL(request.url).pathname; |
| 19 if (filePath === "/front_end/InspectorBackendCommands.js") { | 21 if (filePath === "/") { |
| 20 sendResponse(200, " "); | 22 sendResponse(200, `<html>Please go to <a href="http://localhost:${remote
DebuggingPort}#http://localhost:${serverPort}/front_end/inspector.html?experimen
ts=true"> |
| 23 http://localhost:${remoteDebuggingPort}#http://localhost:${serverPor
t}/front_end/inspector.html?experiments=true</a></html>`); |
| 21 return; | 24 return; |
| 22 } | 25 } |
| 23 | 26 |
| 24 var proxiedFile = proxy(filePath, sendResponse); | 27 var proxiedFile = proxy(filePath, sendResponse); |
| 25 if (proxiedFile) { | 28 if (proxiedFile) { |
| 26 proxiedFile | 29 proxiedFile |
| 27 .then(data => sendResponse(200, data)) | 30 .then(data => sendResponse(200, data)) |
| 28 .catch(handleProxyError); | 31 .catch(handleProxyError); |
| 29 return; | 32 return; |
| 30 } | 33 } |
| 31 | 34 |
| 32 function handleProxyError(err) | 35 function handleProxyError(err) |
| 33 { | 36 { |
| 34 console.log(`Error fetching over the internet file ${filePath}:`, err); | 37 console.log(`Error fetching over the internet file ${filePath}:`, err); |
| 38 console.log(`Make sure you opened Chrome with the flag "--remote-debuggi
ng-port=${remoteDebuggingPort}"`); |
| 35 sendResponse(500, "500 - Internal Server Error"); | 39 sendResponse(500, "500 - Internal Server Error"); |
| 36 } | 40 } |
| 37 | 41 |
| 38 var absoluteFilePath = path.join(process.cwd(), filePath); | 42 var absoluteFilePath = path.join(process.cwd(), filePath); |
| 39 fs.exists(absoluteFilePath, fsExistsCallback); | 43 fs.exists(absoluteFilePath, fsExistsCallback); |
| 40 | 44 |
| 41 function fsExistsCallback(fileExists) | 45 function fsExistsCallback(fileExists) |
| 42 { | 46 { |
| 43 if (!fileExists) { | 47 if (!fileExists) { |
| 44 console.log(`Cannot find file ${absoluteFilePath}`); | 48 console.log(`Cannot find file ${absoluteFilePath}`); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 60 | 64 |
| 61 function sendResponse(statusCode, data) | 65 function sendResponse(statusCode, data) |
| 62 { | 66 { |
| 63 response.writeHead(statusCode); | 67 response.writeHead(statusCode); |
| 64 response.write(data, "binary"); | 68 response.write(data, "binary"); |
| 65 response.end(); | 69 response.end(); |
| 66 } | 70 } |
| 67 } | 71 } |
| 68 | 72 |
| 69 var proxyFilePathToURL = { | 73 var proxyFilePathToURL = { |
| 70 "/front_end/sdk/protocol/js_protocol.json": getWebKitURL.bind(null, "platfor
m/v8_inspector/js_protocol.json"), | 74 "/front_end/SupportedCSSProperties.js": cloudURL.bind(null, "SupportedCSSPro
perties.js"), |
| 71 "/front_end/sdk/protocol/browser_protocol.json": getWebKitURL.bind(null, "co
re/inspector/browser_protocol.json"), | 75 "/front_end/InspectorBackendCommands.js": cloudURL.bind(null, "InspectorBack
endCommands.js"), |
| 72 "/front_end/SupportedCSSProperties.js": getFrontendURL.bind(null, "Supported
CSSProperties.js") | 76 "/favicon.ico": () => "https://chrome-devtools-frontend.appspot.com/favicon.
ico" |
| 73 }; | 77 }; |
| 74 | 78 |
| 75 function getWebKitURL(path, commitHash) | 79 function cloudURL(path, commitHash) |
| 76 { | 80 { |
| 77 return { | 81 return `https://chrome-devtools-frontend.appspot.com/serve_file/@${commitHas
h}/${path}`; |
| 78 url: `https://chromium.googlesource.com/chromium/src/+/${commitHash}/thi
rd_party/WebKit/Source/${path}?format=TEXT`, | |
| 79 isBase64: true | |
| 80 } | |
| 81 } | |
| 82 | |
| 83 function getFrontendURL(path, commitHash) | |
| 84 { | |
| 85 return { | |
| 86 url: `https://chrome-devtools-frontend.appspot.com/serve_file/@${commitH
ash}/${path}`, | |
| 87 isBase64: false | |
| 88 } | |
| 89 } | 82 } |
| 90 | 83 |
| 91 var proxyFileCache = new Map(); | 84 var proxyFileCache = new Map(); |
| 92 | 85 |
| 93 function proxy(filePath) | 86 function proxy(filePath) |
| 94 { | 87 { |
| 95 if (!(filePath in proxyFilePathToURL)) | 88 if (!(filePath in proxyFilePathToURL)) |
| 96 return null; | 89 return null; |
| 97 return fetch("http://localhost:9222/json/version") | 90 return fetch(`http://localhost:${remoteDebuggingPort}/json/version`) |
| 98 .then(onBrowserMetadata); | 91 .then(onBrowserMetadata); |
| 99 | 92 |
| 100 function onBrowserMetadata(metadata) | 93 function onBrowserMetadata(metadata) |
| 101 { | 94 { |
| 102 var metadataObject = JSON.parse(metadata); | 95 var metadataObject = JSON.parse(metadata); |
| 103 var match = metadataObject["WebKit-Version"].match(/\s\(@(\b[0-9a-f]{5,4
0}\b)/); | 96 var match = metadataObject["WebKit-Version"].match(/\s\(@(\b[0-9a-f]{5,4
0}\b)/); |
| 104 var commitHash = match[1]; | 97 var commitHash = match[1]; |
| 105 var proxyFile = proxyFilePathToURL[filePath](commitHash); | 98 var proxyFileURL = proxyFilePathToURL[filePath](commitHash); |
| 106 var proxyFileURL = proxyFile.url; | |
| 107 if (proxyFileCache.has(proxyFileURL)) | 99 if (proxyFileCache.has(proxyFileURL)) |
| 108 return proxyFileCache.get(proxyFileURL); | 100 return proxyFileCache.get(proxyFileURL); |
| 109 return fetch(proxyFileURL) | 101 return fetch(proxyFileURL) |
| 110 .then(text => proxyFile.isBase64 ? new Buffer(text, "base64").toStri
ng("binary") : text) | |
| 111 .then(cacheProxyFile.bind(null, proxyFileURL)); | 102 .then(cacheProxyFile.bind(null, proxyFileURL)); |
| 112 } | 103 } |
| 113 | 104 |
| 114 function cacheProxyFile(proxyFileURL, data) | 105 function cacheProxyFile(proxyFileURL, data) |
| 115 { | 106 { |
| 116 proxyFileCache.set(proxyFileURL, data); | 107 proxyFileCache.set(proxyFileURL, data); |
| 117 return data; | 108 return data; |
| 118 } | 109 } |
| 119 } | 110 } |
| 120 | 111 |
| 121 function fetch(url) | 112 function fetch(url) |
| 122 { | 113 { |
| 123 return new Promise(fetchPromise); | 114 return new Promise(fetchPromise); |
| 124 | 115 |
| 125 function fetchPromise(resolve, reject) { | 116 function fetchPromise(resolve, reject) |
| 117 { |
| 126 var request; | 118 var request; |
| 127 var protocol = parseURL(url).protocol; | 119 var protocol = parseURL(url).protocol; |
| 128 var handleResponse = getCallback.bind(null, resolve, reject); | 120 var handleResponse = getCallback.bind(null, resolve, reject); |
| 129 if (protocol === "https:") { | 121 if (protocol === "https:") { |
| 130 request = https.get(url, handleResponse); | 122 request = https.get(url, handleResponse); |
| 131 } else if (protocol === "http:") { | 123 } else if (protocol === "http:") { |
| 132 request = http.get(url, handleResponse); | 124 request = http.get(url, handleResponse); |
| 133 } else { | 125 } else { |
| 134 reject(new Error(`Invalid protocol for url: ${url}`)); | 126 reject(new Error(`Invalid protocol for url: ${url}`)); |
| 135 return; | 127 return; |
| 136 } | 128 } |
| 137 request.on("error", err => reject(err)); | 129 request.on("error", err => reject(err)); |
| 138 } | 130 } |
| 139 | 131 |
| 140 function getCallback(resolve, reject, response) | 132 function getCallback(resolve, reject, response) |
| 141 { | 133 { |
| 142 if (response.statusCode !== 200) { | 134 if (response.statusCode !== 200) { |
| 143 reject(new Error(`Request error: + ${response.statusCode}`)); | 135 reject(new Error(`Request error: + ${response.statusCode}`)); |
| 144 return; | 136 return; |
| 145 } | 137 } |
| 146 var body = ""; | 138 var body = new Stream(); |
| 147 response.on("data", chunk => body += chunk); | 139 response.on("data", chunk => body.push(chunk)); |
| 148 response.on("end", () => resolve(body)); | 140 response.on("end", () => resolve(body.read())); |
| 149 } | 141 } |
| 150 } | 142 } |
| 151 | 143 |
| OLD | NEW |