| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 7fbfb73 commit b3f8f89
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -20,6 +20,8 @@ | |||
| 20 | 20 | ||
| 21 | 21 | #include "libplatform/libplatform.h" | |
| 22 | 22 | ||
| 23 | + #include <map> | ||
| 24 | + #include <sstream> | ||
| 23 | 25 | #include <string.h> | |
| 24 | 26 | #include <utility> | |
| 25 | 27 | #include <vector> | |
@@ -53,6 +55,21 @@ void PrintDebuggerReadyMessage(int port, const std::string& id) { | |||
| 53 | 55 | fflush(stderr); | |
| 54 | 56 | } | |
| 55 | 57 | ||
| 58 | + std::string MapToString(const std::map<std::string, std::string> object) { | ||
| 59 | + std::ostringstream json; | ||
| 60 | + json << "[ {\n"; | ||
| 61 | + bool first = true; | ||
| 62 | + for (const auto& name_value : object) { | ||
| 63 | + if (!first) | ||
| 64 | + json << ",\n"; | ||
| 65 | + json << " \"" << name_value.first << "\": \""; | ||
| 66 | + json << name_value.second << "\""; | ||
| 67 | + first = false; | ||
| 68 | + } | ||
| 69 | + json << "\n} ]"; | ||
| 70 | + return json.str(); | ||
| 71 | + } | ||
| 72 | + | ||
| 56 | 73 | void Escape(std::string* string) { | |
| 57 | 74 | for (char& c : *string) { | |
| 58 | 75 | c = (c == '\"' || c == '\\') ? '_' : c; | |
@@ -74,33 +91,23 @@ void OnBufferAlloc(uv_handle_t* handle, size_t len, uv_buf_t* buf) { | |||
| 74 | 91 | buf->len = len; | |
| 75 | 92 | } | |
| 76 | 93 | ||
| 77 | - void SendHttpResponse(InspectorSocket* socket, const char* response, | ||
| 78 | - size_t len) { | ||
| 94 | + void SendHttpResponse(InspectorSocket* socket, const std::string& response) { | ||
| 79 | 95 | const char HEADERS[] = "HTTP/1.0 200 OK\r\n" | |
| 80 | 96 | "Content-Type: application/json; charset=UTF-8\r\n" | |
| 81 | 97 | "Cache-Control: no-cache\r\n" | |
| 82 | 98 | "Content-Length: %zu\r\n" | |
| 83 | 99 | "\r\n"; | |
| 84 | 100 | char header[sizeof(HEADERS) + 20]; | |
| 85 | - int header_len = snprintf(header, sizeof(header), HEADERS, len); | ||
| 101 | + int header_len = snprintf(header, sizeof(header), HEADERS, response.size()); | ||
| 86 | 102 | inspector_write(socket, header, header_len); | |
| 87 | - inspector_write(socket, response, len); | ||
| 103 | + inspector_write(socket, response.data(), response.size()); | ||
| 88 | 104 | } | |
| 89 | 105 | ||
| 90 | 106 | void SendVersionResponse(InspectorSocket* socket) { | |
| 91 | - const char VERSION_RESPONSE_TEMPLATE[] = | ||
| 92 | - "[ {" | ||
| 93 | - " \"Browser\": \"node.js/%s\"," | ||
| 94 | - " \"Protocol-Version\": \"1.1\"," | ||
| 95 | - " \"User-Agent\": \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" | ||
| 96 | - "(KHTML, like Gecko) Chrome/45.0.2446.0 Safari/537.36\"," | ||
| 97 | - " \"WebKit-Version\": \"537.36 (@198122)\"" | ||
| 98 | - "} ]"; | ||
| 99 | - char buffer[sizeof(VERSION_RESPONSE_TEMPLATE) + 128]; | ||
| 100 | - size_t len = snprintf(buffer, sizeof(buffer), VERSION_RESPONSE_TEMPLATE, | ||
| 101 | - NODE_VERSION); | ||
| 102 | - ASSERT_LT(len, sizeof(buffer)); | ||
| 103 | - SendHttpResponse(socket, buffer, len); | ||
| 107 | + std::map<std::string, std::string> response; | ||
| 108 | + response["Browser"] = "node.js/" NODE_VERSION; | ||
| 109 | + response["Protocol-Version"] = "1.1"; | ||
| 110 | + SendHttpResponse(socket, MapToString(response)); | ||
| 104 | 111 | } | |
| 105 | 112 | ||
| 106 | 113 | std::string GetProcessTitle() { | |
@@ -114,47 +121,6 @@ std::string GetProcessTitle() { | |||
| 114 | 121 | } | |
| 115 | 122 | } | |
| 116 | 123 | ||
| 117 | - void SendTargentsListResponse(InspectorSocket* socket, | ||
| 118 | - const std::string& script_name_, | ||
| 119 | - const std::string& script_path_, | ||
| 120 | - const std::string& id, | ||
| 121 | - const std::string& ws_url) { | ||
| 122 | - const char LIST_RESPONSE_TEMPLATE[] = | ||
| 123 | - "[ {" | ||
| 124 | - " \"description\": \"node.js instance\"," | ||
| 125 | - " \"devtoolsFrontendUrl\": " | ||
| 126 | - "\"https://chrome-devtools-frontend.appspot.com/serve_file/" | ||
| 127 | - "@" V8_INSPECTOR_REVISION | ||
| 128 | - "/inspector.html?experiments=true&v8only=true" | ||
| 129 | - "&ws=%s\"," | ||
| 130 | - " \"faviconUrl\": \"https://nodejs.org/static/favicon.ico\"," | ||
| 131 | - " \"id\": \"%s\"," | ||
| 132 | - " \"title\": \"%s\"," | ||
| 133 | - " \"type\": \"node\"," | ||
| 134 | - " \"url\": \"%s\"," | ||
| 135 | - " \"webSocketDebuggerUrl\": \"ws://%s\"" | ||
| 136 | - "} ]"; | ||
| 137 | - std::string title = script_name_.empty() ? GetProcessTitle() : script_name_; | ||
| 138 | - | ||
| 139 | - // This attribute value is a "best effort" URL that is passed as a JSON | ||
| 140 | - // string. It is not guaranteed to resolve to a valid resource. | ||
| 141 | - std::string url = "file://" + script_path_; | ||
| 142 | - | ||
| 143 | - Escape(&title); | ||
| 144 | - Escape(&url); | ||
| 145 | - | ||
| 146 | - int buf_len = sizeof(LIST_RESPONSE_TEMPLATE) + ws_url.length() * 2 + | ||
| 147 | - id.length() + title.length() + url.length(); | ||
| 148 | - std::string buffer(buf_len, '\0'); | ||
| 149 | - | ||
| 150 | - int len = snprintf(&buffer[0], buf_len, LIST_RESPONSE_TEMPLATE, | ||
| 151 | - ws_url.c_str(), id.c_str(), title.c_str(), url.c_str(), | ||
| 152 | - ws_url.c_str()); | ||
| 153 | - buffer.resize(len); | ||
| 154 | - ASSERT_LT(len, buf_len); // Buffer should be big enough! | ||
| 155 | - SendHttpResponse(socket, buffer.data(), len); | ||
| 156 | - } | ||
| 157 | - | ||
| 158 | 124 | void SendProtocolJson(InspectorSocket* socket) { | |
| 159 | 125 | z_stream strm; | |
| 160 | 126 | strm.zalloc = Z_NULL; | |
@@ -167,13 +133,13 @@ void SendProtocolJson(InspectorSocket* socket) { | |||
| 167 | 133 | PROTOCOL_JSON[2]; | |
| 168 | 134 | strm.next_in = const_cast<uint8_t*>(PROTOCOL_JSON + 3); | |
| 169 | 135 | strm.avail_in = sizeof(PROTOCOL_JSON) - 3; | |
| 170 | - std::vector<char> data(kDecompressedSize); | ||
| 136 | + std::string data(kDecompressedSize, '\0'); | ||
| 171 | 137 | strm.next_out = reinterpret_cast<Byte*>(&data[0]); | |
| 172 | 138 | strm.avail_out = data.size(); | |
| 173 | 139 | CHECK_EQ(Z_STREAM_END, inflate(&strm, Z_FINISH)); | |
| 174 | 140 | CHECK_EQ(0, strm.avail_out); | |
| 175 | 141 | CHECK_EQ(Z_OK, inflateEnd(&strm)); | |
| 176 | - SendHttpResponse(socket, &data[0], data.size()); | ||
| 142 | + SendHttpResponse(socket, data); | ||
| 177 | 143 | } | |
| 178 | 144 | ||
| 179 | 145 | const char* match_path_segment(const char* path, const char* expected) { | |
@@ -205,6 +171,12 @@ std::string GenerateID() { | |||
| 205 | 171 | return uuid; | |
| 206 | 172 | } | |
| 207 | 173 | ||
| 174 | + // std::to_string is not available on Smart OS and ARM flavours | ||
| 175 | + const std::string to_string(uint64_t number) { | ||
| 176 | + std::ostringstream result; | ||
| 177 | + result << number; | ||
| 178 | + return result.str(); | ||
| 179 | + } | ||
| 208 | 180 | } // namespace | |
| 209 | 181 | ||
| 210 | 182 | ||
@@ -253,8 +225,9 @@ class AgentImpl { | |||
| 253 | 225 | void PostIncomingMessage(const String16& message); | |
| 254 | 226 | void WaitForFrontendMessage(); | |
| 255 | 227 | void NotifyMessageReceived(); | |
| 256 | - bool RespondToGet(InspectorSocket* socket, const std::string& path); | ||
| 257 | 228 | State ToState(State state); | |
| 229 | + void SendTargentsListResponse(InspectorSocket* socket); | ||
| 230 | + bool RespondToGet(InspectorSocket* socket, const std::string& path); | ||
| 258 | 231 | ||
| 259 | 232 | uv_sem_t start_sem_; | |
| 260 | 233 | ConditionVariable incoming_message_cond_; | |
@@ -673,14 +646,41 @@ void AgentImpl::OnRemoteDataIO(InspectorSocket* socket, | |||
| 673 | 646 | } | |
| 674 | 647 | } | |
| 675 | 648 | ||
| 649 | + void AgentImpl::SendTargentsListResponse(InspectorSocket* socket) { | ||
| 650 | + std::map<std::string, std::string> response; | ||
| 651 | + response["description"] = "node.js instance"; | ||
| 652 | + response["faviconUrl"] = "https://nodejs.org/static/favicon.ico"; | ||
| 653 | + response["id"] = id_; | ||
| 654 | + response["title"] = script_name_.empty() ? GetProcessTitle() : script_name_; | ||
| 655 | + Escape(&response["title"]); | ||
| 656 | + response["type"] = "node"; | ||
| 657 | + // This attribute value is a "best effort" URL that is passed as a JSON | ||
| 658 | + // string. It is not guaranteed to resolve to a valid resource. | ||
| 659 | + response["url"] = "file://" + script_path_; | ||
| 660 | + Escape(&response["url"]); | ||
| 661 | + | ||
| 662 | + if (!client_socket_) { | ||
| 663 | + std::string address = GetWsUrl(port_, id_); | ||
| 664 | + | ||
| 665 | + std::ostringstream frontend_url; | ||
| 666 | + frontend_url << "https://chrome-devtools-frontend.appspot.com/serve_file/@"; | ||
| 667 | + frontend_url << V8_INSPECTOR_REVISION; | ||
| 668 | + frontend_url << "/inspector.html?experiments=true&v8only=true&ws="; | ||
| 669 | + frontend_url << address; | ||
| 670 | + | ||
| 671 | + response["devtoolsFrontendUrl"] += frontend_url.str(); | ||
| 672 | + response["webSocketDebuggerUrl"] = "ws://" + address; | ||
| 673 | + } | ||
| 674 | + SendHttpResponse(socket, MapToString(response)); | ||
| 675 | + } | ||
| 676 | + | ||
| 676 | 677 | bool AgentImpl::RespondToGet(InspectorSocket* socket, const std::string& path) { | |
| 677 | 678 | const char* command = match_path_segment(path.c_str(), "/json"); | |
| 678 | 679 | if (command == nullptr) | |
| 679 | 680 | return false; | |
| 680 | 681 | ||
| 681 | 682 | if (match_path_segment(command, "list") || command[0] == '\0') { | |
| 682 | - SendTargentsListResponse(socket, script_name_, script_path_, id_, | ||
| 683 | - GetWsUrl(port_, id_)); | ||
| 683 | + SendTargentsListResponse(socket); | ||
| 684 | 684 | } else if (match_path_segment(command, "protocol")) { | |
| 685 | 685 | SendProtocolJson(socket); | |
| 686 | 686 | } else if (match_path_segment(command, "version")) { | |
@@ -689,8 +689,7 @@ bool AgentImpl::RespondToGet(InspectorSocket* socket, const std::string& path) { | |||
| 689 | 689 | const char* pid = match_path_segment(command, "activate"); | |
| 690 | 690 | if (pid != id_) | |
| 691 | 691 | return false; | |
| 692 | - const char TARGET_ACTIVATED[] = "Target activated"; | ||
| 693 | - SendHttpResponse(socket, TARGET_ACTIVATED, sizeof(TARGET_ACTIVATED) - 1); | ||
| 692 | + SendHttpResponse(socket, "Target activated"); | ||
| 694 | 693 | } | |
| 695 | 694 | return true; | |
| 696 | 695 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -282,6 +282,15 @@ TestSession.prototype.disconnect = function(childDone) { | |||
| 282 | 282 | }); | |
| 283 | 283 | }; | |
| 284 | 284 | ||
| 285 | + TestSession.prototype.testHttpResponse = function(path, check) { | ||
| 286 | + return this.enqueue((callback) => | ||
| 287 | + checkHttpResponse(this.harness_.port, path, (response) => { | ||
| 288 | + check.call(this, response); | ||
| 289 | + callback(); | ||
| 290 | + })); | ||
| 291 | + }; | ||
| 292 | + | ||
| 293 | + | ||
| 285 | 294 | const Harness = function(port, childProcess) { | |
| 286 | 295 | this.port = port; | |
| 287 | 296 | this.mainScriptPath = mainScript; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -152,6 +152,14 @@ function testInspectScope(session) { | |||
| 152 | 152 | ]); | |
| 153 | 153 | } | |
| 154 | 154 | ||
| 155 | + function testNoUrlsWhenConnected(session) { | ||
| 156 | + session.testHttpResponse('/json/list', (response) => { | ||
| 157 | + assert.strictEqual(1, response.length); | ||
| 158 | + assert.ok(!response[0].hasOwnProperty('devtoolsFrontendUrl')); | ||
| 159 | + assert.ok(!response[0].hasOwnProperty('webSocketDebuggerUrl')); | ||
| 160 | + }); | ||
| 161 | + } | ||
| 162 | + | ||
| 155 | 163 | function testWaitsForFrontendDisconnect(session, harness) { | |
| 156 | 164 | console.log('[test]', 'Verify node waits for the frontend to disconnect'); | |
| 157 | 165 | session.sendInspectorCommands({ 'method': 'Debugger.resume'}) | |
@@ -165,6 +173,7 @@ function runTests(harness) { | |||
| 165 | 173 | .testHttpResponse('/json/list', checkListResponse) | |
| 166 | 174 | .testHttpResponse('/json/version', assert.ok) | |
| 167 | 175 | .runFrontendSession([ | |
| 176 | + testNoUrlsWhenConnected, | ||
| 168 | 177 | testBreakpointOnStart, | |
| 169 | 178 | testSetBreakpointAndResume, | |
| 170 | 179 | testInspectScope, | |
| Back | FazBrowse Home | New Git URL |
0 commit comments