mirror of
https://github.com/nodejs/node.git
synced 2025-05-07 08:00:26 +00:00
src: add /json/protocol endpoint to inspector
Embed the compressed and minified protocol.json from the bundled v8_inspector and make it available through the /json/protocol endpoint. Refs: https://github.com/nodejs/diagnostics/issues/52 PR-URL: https://github.com/nodejs/node/pull/7491 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
a8d2c9d775
commit
782620f03f
4
deps/zlib/zlib.gyp
vendored
4
deps/zlib/zlib.gyp
vendored
@ -12,6 +12,7 @@
|
||||
{
|
||||
'target_name': 'zlib',
|
||||
'type': 'static_library',
|
||||
'defines': [ 'ZLIB_CONST' ],
|
||||
'sources': [
|
||||
'adler32.c',
|
||||
'compress.c',
|
||||
@ -44,6 +45,7 @@
|
||||
'.',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'defines': [ 'ZLIB_CONST' ],
|
||||
'include_dirs': [
|
||||
'.',
|
||||
],
|
||||
@ -72,10 +74,12 @@
|
||||
'direct_dependent_settings': {
|
||||
'defines': [
|
||||
'USE_SYSTEM_ZLIB',
|
||||
'ZLIB_CONST',
|
||||
],
|
||||
},
|
||||
'defines': [
|
||||
'USE_SYSTEM_ZLIB',
|
||||
'ZLIB_CONST',
|
||||
],
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
|
29
node.gyp
29
node.gyp
@ -323,6 +323,7 @@
|
||||
'dependencies': [
|
||||
'deps/v8_inspector/third_party/v8_inspector/platform/'
|
||||
'v8_inspector/v8_inspector.gyp:v8_inspector_stl',
|
||||
'v8_inspector_compress_protocol_json#host',
|
||||
],
|
||||
'include_dirs': [
|
||||
'deps/v8_inspector/third_party/v8_inspector',
|
||||
@ -651,6 +652,34 @@
|
||||
} ]
|
||||
]
|
||||
},
|
||||
{
|
||||
'target_name': 'v8_inspector_compress_protocol_json',
|
||||
'type': 'none',
|
||||
'toolsets': ['host'],
|
||||
'conditions': [
|
||||
[ 'v8_inspector=="true"', {
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'v8_inspector_compress_protocol_json',
|
||||
'process_outputs_as_sources': 1,
|
||||
'inputs': [
|
||||
'deps/v8_inspector/third_party/'
|
||||
'v8_inspector/platform/v8_inspector/js_protocol.json',
|
||||
],
|
||||
'outputs': [
|
||||
'<(SHARED_INTERMEDIATE_DIR)/v8_inspector_protocol_json.h',
|
||||
],
|
||||
'action': [
|
||||
'python',
|
||||
'tools/compress_json.py',
|
||||
'<@(_inputs)',
|
||||
'<@(_outputs)',
|
||||
],
|
||||
},
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'node_js2c',
|
||||
'type': 'none',
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "node_version.h"
|
||||
#include "v8-platform.h"
|
||||
#include "util.h"
|
||||
#include "zlib.h"
|
||||
|
||||
#include "platform/v8_inspector/public/InspectorVersion.h"
|
||||
#include "platform/v8_inspector/public/V8Inspector.h"
|
||||
@ -41,6 +42,10 @@ const char TAG_DISCONNECT[] = "#disconnect";
|
||||
const char DEVTOOLS_PATH[] = "/node";
|
||||
const char DEVTOOLS_HASH[] = V8_INSPECTOR_REVISION;
|
||||
|
||||
static const uint8_t PROTOCOL_JSON[] = {
|
||||
#include "v8_inspector_protocol_json.h" // NOLINT(build/include_order)
|
||||
};
|
||||
|
||||
void PrintDebuggerReadyMessage(int port) {
|
||||
fprintf(stderr, "Debugger listening on port %d.\n"
|
||||
"Warning: This is an experimental feature and could change at any time.\n"
|
||||
@ -161,6 +166,27 @@ void SendTargentsListResponse(InspectorSocket* socket,
|
||||
SendHttpResponse(socket, buffer.data(), len);
|
||||
}
|
||||
|
||||
void SendProtocolJson(InspectorSocket* socket) {
|
||||
z_stream strm;
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
CHECK_EQ(Z_OK, inflateInit(&strm));
|
||||
static const size_t kDecompressedSize =
|
||||
PROTOCOL_JSON[0] * 0x10000u +
|
||||
PROTOCOL_JSON[1] * 0x100u +
|
||||
PROTOCOL_JSON[2];
|
||||
strm.next_in = PROTOCOL_JSON + 3;
|
||||
strm.avail_in = sizeof(PROTOCOL_JSON) - 3;
|
||||
std::vector<char> data(kDecompressedSize);
|
||||
strm.next_out = reinterpret_cast<Byte*>(&data[0]);
|
||||
strm.avail_out = data.size();
|
||||
CHECK_EQ(Z_STREAM_END, inflate(&strm, Z_FINISH));
|
||||
CHECK_EQ(0, strm.avail_out);
|
||||
CHECK_EQ(Z_OK, inflateEnd(&strm));
|
||||
SendHttpResponse(socket, &data[0], data.size());
|
||||
}
|
||||
|
||||
const char* match_path_segment(const char* path, const char* expected) {
|
||||
size_t len = strlen(expected);
|
||||
if (StringEqualNoCaseN(path, expected, len)) {
|
||||
@ -179,6 +205,8 @@ bool RespondToGet(InspectorSocket* socket, const std::string& script_name_,
|
||||
|
||||
if (match_path_segment(command, "list") || command[0] == '\0') {
|
||||
SendTargentsListResponse(socket, script_name_, script_path_, port);
|
||||
} else if (match_path_segment(command, "protocol")) {
|
||||
SendProtocolJson(socket);
|
||||
} else if (match_path_segment(command, "version")) {
|
||||
SendVersionResponse(socket);
|
||||
} else {
|
||||
|
@ -16,6 +16,7 @@ exports.testDir = __dirname;
|
||||
exports.fixturesDir = path.join(exports.testDir, 'fixtures');
|
||||
exports.libDir = path.join(exports.testDir, '../lib');
|
||||
exports.tmpDirName = 'tmp';
|
||||
// PORT should match the definition in test/testpy/__init__.py.
|
||||
exports.PORT = +process.env.NODE_COMMON_PORT || 12346;
|
||||
exports.isWindows = process.platform === 'win32';
|
||||
exports.isWOW64 = exports.isWindows &&
|
||||
|
22
test/parallel/test-v8-inspector-json-protocol.js
Normal file
22
test/parallel/test-v8-inspector-json-protocol.js
Normal file
@ -0,0 +1,22 @@
|
||||
// Flags: --inspect={PORT}
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
|
||||
const options = {
|
||||
path: '/json/protocol',
|
||||
port: common.PORT,
|
||||
host: common.localhostIPv4,
|
||||
};
|
||||
|
||||
http.get(options, common.mustCall((res) => {
|
||||
let body = '';
|
||||
res.setEncoding('utf8');
|
||||
res.on('data', (data) => body += data);
|
||||
res.on('end', common.mustCall(() => {
|
||||
assert(body.length > 0);
|
||||
assert.deepStrictEqual(JSON.stringify(JSON.parse(body)), body);
|
||||
}));
|
||||
}));
|
@ -61,7 +61,10 @@ class SimpleTestCase(test.TestCase):
|
||||
source = open(self.file).read()
|
||||
flags_match = FLAGS_PATTERN.search(source)
|
||||
if flags_match:
|
||||
result += flags_match.group(1).strip().split()
|
||||
# PORT should match the definition in test/common.js.
|
||||
env = { 'PORT': int(os.getenv('NODE_COMMON_PORT', '12346')) }
|
||||
env['PORT'] += self.thread_id * 100
|
||||
result += flags_match.group(1).strip().format(**env).split()
|
||||
files_match = FILES_PATTERN.search(source);
|
||||
additional_files = []
|
||||
if files_match:
|
||||
|
25
tools/compress_json.py
Normal file
25
tools/compress_json.py
Normal file
@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import json
|
||||
import struct
|
||||
import sys
|
||||
import zlib
|
||||
|
||||
if __name__ == '__main__':
|
||||
fp = open(sys.argv[1])
|
||||
obj = json.load(fp)
|
||||
text = json.dumps(obj, separators=(',', ':'))
|
||||
data = zlib.compress(text, zlib.Z_BEST_COMPRESSION)
|
||||
|
||||
# To make decompression a little easier, we prepend the compressed data
|
||||
# with the size of the uncompressed data as a 24 bits BE unsigned integer.
|
||||
assert len(text) < 1 << 24, 'Uncompressed JSON must be < 16 MB.'
|
||||
data = struct.pack('>I', len(text))[1:4] + data
|
||||
|
||||
step = 20
|
||||
slices = (data[i:i+step] for i in xrange(0, len(data), step))
|
||||
slices = map(lambda s: ','.join(str(ord(c)) for c in s), slices)
|
||||
text = ',\n'.join(slices)
|
||||
|
||||
fp = open(sys.argv[2], 'w')
|
||||
fp.write(text)
|
Loading…
Reference in New Issue
Block a user