summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/inspector_agent.cc31
-rw-r--r--src/inspector_socket.cc209
-rw-r--r--src/inspector_socket.h28
3 files changed, 108 insertions, 160 deletions
diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc
index fee459146c..0446f462e9 100644
--- a/src/inspector_agent.cc
+++ b/src/inspector_agent.cc
@@ -48,8 +48,8 @@ void PrintDebuggerReadyMessage(int port) {
port, DEVTOOLS_HASH, port);
}
-bool AcceptsConnection(inspector_socket_t* socket, const char* path) {
- return strncmp(DEVTOOLS_PATH, path, sizeof(DEVTOOLS_PATH)) == 0;
+bool AcceptsConnection(inspector_socket_t* socket, const std::string& path) {
+ return 0 == path.compare(0, sizeof(DEVTOOLS_PATH) - 1, DEVTOOLS_PATH);
}
void DisposeInspector(inspector_socket_t* socket, int status) {
@@ -63,10 +63,7 @@ void DisconnectAndDisposeIO(inspector_socket_t* socket) {
}
void OnBufferAlloc(uv_handle_t* handle, size_t len, uv_buf_t* buf) {
- if (len > 0) {
- buf->base = static_cast<char*>(malloc(len));
- CHECK_NE(buf->base, nullptr);
- }
+ buf->base = new char[len];
buf->len = len;
}
@@ -133,18 +130,19 @@ void SendTargentsListResponse(inspector_socket_t* socket, int port) {
SendHttpResponse(socket, buffer, len);
}
-bool RespondToGet(inspector_socket_t* socket, const char* path, int port) {
+bool RespondToGet(inspector_socket_t* socket, const std::string& path,
+ int port) {
const char PATH[] = "/json";
const char PATH_LIST[] = "/json/list";
const char PATH_VERSION[] = "/json/version";
const char PATH_ACTIVATE[] = "/json/activate/";
- if (!strncmp(PATH_VERSION, path, sizeof(PATH_VERSION))) {
+ if (0 == path.compare(0, sizeof(PATH_VERSION) - 1, PATH_VERSION)) {
SendVersionResponse(socket);
- } else if (!strncmp(PATH_LIST, path, sizeof(PATH_LIST)) ||
- !strncmp(PATH, path, sizeof(PATH))) {
+ } else if (0 == path.compare(0, sizeof(PATH_LIST) - 1, PATH_LIST) ||
+ 0 == path.compare(0, sizeof(PATH) - 1, PATH)) {
SendTargentsListResponse(socket, port);
- } else if (!strncmp(path, PATH_ACTIVATE, sizeof(PATH_ACTIVATE) - 1) &&
- atoi(path + (sizeof(PATH_ACTIVATE) - 1)) == getpid()) {
+ } else if (0 == path.compare(0, sizeof(PATH_ACTIVATE) - 1, PATH_ACTIVATE) &&
+ atoi(path.substr(sizeof(PATH_ACTIVATE) - 1).c_str()) == getpid()) {
const char TARGET_ACTIVATED[] = "Target activated";
SendHttpResponse(socket, TARGET_ACTIVATED, sizeof(TARGET_ACTIVATED) - 1);
} else {
@@ -181,7 +179,7 @@ class AgentImpl {
static void OnSocketConnectionIO(uv_stream_t* server, int status);
static bool OnInspectorHandshakeIO(inspector_socket_t* socket,
enum inspector_handshake_event state,
- const char* path);
+ const std::string& path);
static void WriteCbIO(uv_async_t* async);
void WorkerRunIO();
@@ -388,7 +386,6 @@ void AgentImpl::ThreadCbIO(void* agent) {
void AgentImpl::OnSocketConnectionIO(uv_stream_t* server, int status) {
if (status == 0) {
inspector_socket_t* socket = new inspector_socket_t();
- memset(socket, 0, sizeof(*socket));
socket->data = server->data;
if (inspector_accept(server, socket,
AgentImpl::OnInspectorHandshakeIO) != 0) {
@@ -399,8 +396,8 @@ void AgentImpl::OnSocketConnectionIO(uv_stream_t* server, int status) {
// static
bool AgentImpl::OnInspectorHandshakeIO(inspector_socket_t* socket,
- enum inspector_handshake_event state,
- const char* path) {
+ enum inspector_handshake_event state,
+ const std::string& path) {
AgentImpl* agent = static_cast<AgentImpl*>(socket->data);
switch (state) {
case kInspectorHandshakeHttpGet:
@@ -443,7 +440,7 @@ void AgentImpl::OnRemoteDataIO(inspector_socket_t* socket,
DisconnectAndDisposeIO(socket);
}
if (buf) {
- free(buf->base);
+ delete[] buf->base;
}
pause_cond_.Broadcast(scoped_lock);
}
diff --git a/src/inspector_socket.cc b/src/inspector_socket.cc
index d3a8d8efff..c360ef0db9 100644
--- a/src/inspector_socket.cc
+++ b/src/inspector_socket.cc
@@ -18,25 +18,6 @@
static const char CLOSE_FRAME[] = {'\x88', '\x00'};
-struct http_parsing_state_s {
- http_parser parser;
- http_parser_settings parser_settings;
- handshake_cb callback;
- bool done;
- bool parsing_value;
- char* ws_key;
- char* path;
- char* current_header;
-};
-
-struct ws_state_s {
- uv_alloc_cb alloc_cb;
- uv_read_cb read_cb;
- inspector_cb close_cb;
- bool close_sent;
- bool received_close;
-};
-
enum ws_decode_result {
FRAME_OK, FRAME_INCOMPLETE, FRAME_CLOSE, FRAME_ERROR
};
@@ -72,11 +53,9 @@ static void dispose_inspector(uv_handle_t* handle) {
reinterpret_cast<inspector_socket_t*>(handle->data);
inspector_cb close =
inspector->ws_mode ? inspector->ws_state->close_cb : nullptr;
- free(inspector->buffer);
- free(inspector->ws_state);
+ inspector->buffer.clear();
+ delete inspector->ws_state;
inspector->ws_state = nullptr;
- inspector->buffer = nullptr;
- inspector->buffer_size = 0;
inspector->data_len = 0;
inspector->last_read_end = 0;
if (close) {
@@ -92,11 +71,25 @@ static void close_connection(inspector_socket_t* inspector) {
}
}
+struct WriteRequest {
+ WriteRequest(inspector_socket_t* inspector, const char* data, size_t size)
+ : inspector(inspector)
+ , storage(data, data + size)
+ , buf(uv_buf_init(&storage[0], storage.size())) {}
+
+ static WriteRequest* from_write_req(uv_write_t* req) {
+ return node::ContainerOf(&WriteRequest::req, req);
+ }
+
+ inspector_socket_t* const inspector;
+ std::vector<char> storage;
+ uv_write_t req;
+ uv_buf_t buf;
+};
+
// Cleanup
static void write_request_cleanup(uv_write_t* req, int status) {
- free((reinterpret_cast<uv_buf_t*>(req->data))->base);
- free(req->data);
- free(req);
+ delete WriteRequest::from_write_req(req);
}
static int write_to_client(inspector_socket_t* inspector,
@@ -109,21 +102,9 @@ static int write_to_client(inspector_socket_t* inspector,
#endif
// Freed in write_request_cleanup
- uv_buf_t* buf = reinterpret_cast<uv_buf_t*>(malloc(sizeof(uv_buf_t)));
- uv_write_t* req = reinterpret_cast<uv_write_t*>(malloc(sizeof(uv_write_t)));
- CHECK_NE(buf, nullptr);
- CHECK_NE(req, nullptr);
- memset(req, 0, sizeof(*req));
- buf->base = reinterpret_cast<char*>(malloc(len));
-
- CHECK_NE(buf->base, nullptr);
-
- memcpy(buf->base, msg, len);
- buf->len = len;
- req->data = buf;
-
+ WriteRequest* wr = new WriteRequest(inspector, msg, len);
uv_stream_t* stream = reinterpret_cast<uv_stream_t*>(&inspector->client);
- return uv_write(req, stream, buf, 1, write_cb) < 0;
+ return uv_write(&wr->req, stream, &wr->buf, 1, write_cb) < 0;
}
// Constants for hybi-10 frame format.
@@ -278,10 +259,10 @@ static void shutdown_complete(inspector_socket_t* inspector) {
close_connection(inspector);
}
-static void on_close_frame_written(uv_write_t* write, int status) {
- inspector_socket_t* inspector =
- reinterpret_cast<inspector_socket_t*>(write->handle->data);
- write_request_cleanup(write, status);
+static void on_close_frame_written(uv_write_t* req, int status) {
+ WriteRequest* wr = WriteRequest::from_write_req(req);
+ inspector_socket_t* inspector = wr->inspector;
+ delete wr;
inspector->ws_state->close_sent = true;
if (inspector->ws_state->received_close) {
shutdown_complete(inspector);
@@ -304,7 +285,7 @@ static int parse_ws_frames(inspector_socket_t* inspector, size_t len) {
std::vector<char> output;
bool compressed = false;
- ws_decode_result r = decode_frame_hybi17(inspector->buffer,
+ ws_decode_result r = decode_frame_hybi17(&inspector->buffer[0],
len, true /* client_frame */,
&bytes_consumed, &output,
&compressed);
@@ -334,16 +315,13 @@ static void prepare_buffer(uv_handle_t* stream, size_t len, uv_buf_t* buf) {
inspector_socket_t* inspector =
reinterpret_cast<inspector_socket_t*>(stream->data);
- if (len > (inspector->buffer_size - inspector->data_len)) {
+ if (len > (inspector->buffer.size() - inspector->data_len)) {
int new_size = (inspector->data_len + len + BUFFER_GROWTH_CHUNK_SIZE - 1) /
BUFFER_GROWTH_CHUNK_SIZE *
BUFFER_GROWTH_CHUNK_SIZE;
- inspector->buffer_size = new_size;
- inspector->buffer = reinterpret_cast<char*>(realloc(inspector->buffer,
- inspector->buffer_size));
- ASSERT_NE(inspector->buffer, nullptr);
+ inspector->buffer.resize(new_size);
}
- buf->base = inspector->buffer + inspector->data_len;
+ buf->base = &inspector->buffer[inspector->data_len];
buf->len = len;
inspector->data_len += len;
}
@@ -366,10 +344,10 @@ static void websockets_data_cb(uv_stream_t* stream, ssize_t nread,
#endif
// 1. Move read bytes to continue the buffer
// Should be same as this is supposedly last buffer
- ASSERT_EQ(buf->base + buf->len, inspector->buffer + inspector->data_len);
+ ASSERT_EQ(buf->base + buf->len, &inspector->buffer[inspector->data_len]);
// Should be noop...
- memmove(inspector->buffer + inspector->last_read_end, buf->base, nread);
+ memmove(&inspector->buffer[inspector->last_read_end], buf->base, nread);
inspector->last_read_end += nread;
// 2. Parse.
@@ -378,8 +356,8 @@ static void websockets_data_cb(uv_stream_t* stream, ssize_t nread,
processed = parse_ws_frames(inspector, inspector->last_read_end);
// 3. Fix the buffer size & length
if (processed > 0) {
- memmove(inspector->buffer, inspector->buffer + processed,
- inspector->last_read_end - processed);
+ memmove(&inspector->buffer[0], &inspector->buffer[processed],
+ inspector->last_read_end - processed);
inspector->last_read_end -= processed;
inspector->data_len = inspector->last_read_end;
}
@@ -410,73 +388,53 @@ void inspector_read_stop(inspector_socket_t* inspector) {
inspector->ws_state->read_cb = nullptr;
}
-static void generate_accept_string(const char* client_key, char* buffer) {
+static void generate_accept_string(const std::string& client_key,
+ char (*buffer)[ACCEPT_KEY_LENGTH]) {
// Magic string from websockets spec.
- const char ws_magic[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
- size_t key_len = strlen(client_key);
- size_t magic_len = sizeof(ws_magic) - 1;
-
- char* buf = reinterpret_cast<char*>(malloc(key_len + magic_len));
- CHECK_NE(buf, nullptr);
- memcpy(buf, client_key, key_len);
- memcpy(buf + key_len, ws_magic, magic_len);
- char hash[20];
- SHA1((unsigned char*) buf, key_len + magic_len, (unsigned char*) hash);
- free(buf);
- node::base64_encode(hash, 20, buffer, ACCEPT_KEY_LENGTH);
- buffer[ACCEPT_KEY_LENGTH] = '\0';
-}
-
-static void append(char** value, const char* string, size_t length) {
- const size_t INCREMENT = 500; // There should never be more then 1 chunk...
-
- int current_len = *value ? strlen(*value) : 0;
- int new_len = current_len + length;
- int adjusted = (new_len / INCREMENT + 1) * INCREMENT;
- *value = reinterpret_cast<char*>(realloc(*value, adjusted));
- memcpy(*value + current_len, string, length);
- (*value)[new_len] = '\0';
+ static const char ws_magic[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+ std::string input(client_key + ws_magic);
+ char hash[SHA_DIGEST_LENGTH];
+ SHA1(reinterpret_cast<const unsigned char*>(&input[0]), input.size(),
+ reinterpret_cast<unsigned char*>(hash));
+ node::base64_encode(hash, sizeof(hash), *buffer, sizeof(*buffer));
}
static int header_value_cb(http_parser* parser, const char* at, size_t length) {
- char SEC_WEBSOCKET_KEY_HEADER[] = "Sec-WebSocket-Key";
- struct http_parsing_state_s* state = (struct http_parsing_state_s*)
- (reinterpret_cast<inspector_socket_t*>(parser->data))->http_parsing_state;
+ static const char SEC_WEBSOCKET_KEY_HEADER[] = "Sec-WebSocket-Key";
+ auto inspector = static_cast<inspector_socket_t*>(parser->data);
+ auto state = inspector->http_parsing_state;
state->parsing_value = true;
- if (state->current_header &&
- node::StringEqualNoCaseN(state->current_header,
+ if (state->current_header.size() == sizeof(SEC_WEBSOCKET_KEY_HEADER) - 1 &&
+ node::StringEqualNoCaseN(state->current_header.data(),
SEC_WEBSOCKET_KEY_HEADER,
- sizeof(SEC_WEBSOCKET_KEY_HEADER))) {
- append(&state->ws_key, at, length);
+ sizeof(SEC_WEBSOCKET_KEY_HEADER) - 1)) {
+ state->ws_key.append(at, length);
}
return 0;
}
static int header_field_cb(http_parser* parser, const char* at, size_t length) {
- struct http_parsing_state_s* state = (struct http_parsing_state_s*)
- (reinterpret_cast<inspector_socket_t*>(parser->data))->http_parsing_state;
+ auto inspector = static_cast<inspector_socket_t*>(parser->data);
+ auto state = inspector->http_parsing_state;
if (state->parsing_value) {
state->parsing_value = false;
- if (state->current_header)
- state->current_header[0] = '\0';
+ state->current_header.clear();
}
- append(&state->current_header, at, length);
+ state->current_header.append(at, length);
return 0;
}
static int path_cb(http_parser* parser, const char* at, size_t length) {
- struct http_parsing_state_s* state = (struct http_parsing_state_s*)
- (reinterpret_cast<inspector_socket_t*>(parser->data))->http_parsing_state;
- append(&state->path, at, length);
+ auto inspector = static_cast<inspector_socket_t*>(parser->data);
+ auto state = inspector->http_parsing_state;
+ state->path.append(at, length);
return 0;
}
static void handshake_complete(inspector_socket_t* inspector) {
uv_read_stop(reinterpret_cast<uv_stream_t*>(&inspector->client));
handshake_cb callback = inspector->http_parsing_state->callback;
- inspector->ws_state = (struct ws_state_s*) malloc(sizeof(struct ws_state_s));
- ASSERT_NE(nullptr, inspector->ws_state);
- memset(inspector->ws_state, 0, sizeof(struct ws_state_s));
+ inspector->ws_state = new ws_state_s();
inspector->last_read_end = 0;
inspector->ws_mode = true;
callback(inspector, kInspectorHandshakeUpgraded,
@@ -484,11 +442,7 @@ static void handshake_complete(inspector_socket_t* inspector) {
}
static void cleanup_http_parsing_state(inspector_socket_t* inspector) {
- struct http_parsing_state_s* state = inspector->http_parsing_state;
- free(state->current_header);
- free(state->path);
- free(state->ws_key);
- free(state);
+ delete inspector->http_parsing_state;
inspector->http_parsing_state = nullptr;
}
@@ -498,7 +452,7 @@ static void report_handshake_failure_cb(uv_handle_t* handle) {
static_cast<inspector_socket_t*>(handle->data);
handshake_cb cb = inspector->http_parsing_state->callback;
cleanup_http_parsing_state(inspector);
- cb(inspector, kInspectorHandshakeFailed, nullptr);
+ cb(inspector, kInspectorHandshakeFailed, std::string());
}
static void close_and_report_handshake_failure(inspector_socket_t* inspector) {
@@ -537,29 +491,21 @@ static int message_complete_cb(http_parser* parser) {
} else {
handshake_failed(inspector);
}
- } else if (!state->ws_key) {
+ } else if (state->ws_key.empty()) {
handshake_failed(inspector);
} else if (state->callback(inspector, kInspectorHandshakeUpgrading,
state->path)) {
- char accept_string[ACCEPT_KEY_LENGTH + 1];
- generate_accept_string(state->ws_key, accept_string);
-
+ char accept_string[ACCEPT_KEY_LENGTH];
+ generate_accept_string(state->ws_key, &accept_string);
const char accept_ws_prefix[] = "HTTP/1.1 101 Switching Protocols\r\n"
"Upgrade: websocket\r\n"
"Connection: Upgrade\r\n"
"Sec-WebSocket-Accept: ";
const char accept_ws_suffix[] = "\r\n\r\n";
- // Format has two chars (%s) that are replaced with actual key
- char accept_response[sizeof(accept_ws_prefix) - 1 +
- sizeof(accept_ws_suffix) - 1 +
- ACCEPT_KEY_LENGTH];
- memcpy(accept_response, accept_ws_prefix, sizeof(accept_ws_prefix) - 1);
- memcpy(accept_response + sizeof(accept_ws_prefix) - 1,
- accept_string, ACCEPT_KEY_LENGTH);
- memcpy(accept_response + sizeof(accept_ws_prefix) - 1 + ACCEPT_KEY_LENGTH,
- accept_ws_suffix, sizeof(accept_ws_suffix) - 1);
- int len = sizeof(accept_response);
- if (write_to_client(inspector, accept_response, len) >= 0) {
+ std::string reply(accept_ws_prefix, sizeof(accept_ws_prefix) - 1);
+ reply.append(accept_string, sizeof(accept_string));
+ reply.append(accept_ws_suffix, sizeof(accept_ws_suffix) - 1);
+ if (write_to_client(inspector, &reply[0], reply.size()) >= 0) {
handshake_complete(inspector);
inspector->http_parsing_state->done = true;
} else {
@@ -588,7 +534,7 @@ static void data_received_cb(uv_stream_s* client, ssize_t nread,
} else {
http_parsing_state_s* state = inspector->http_parsing_state;
http_parser* parser = &state->parser;
- http_parser_execute(parser, &state->parser_settings, inspector->buffer,
+ http_parser_execute(parser, &state->parser_settings, &inspector->buffer[0],
nread);
if (parser->http_errno != HPE_OK) {
handshake_failed(inspector);
@@ -603,15 +549,9 @@ static void data_received_cb(uv_stream_s* client, ssize_t nread,
static void init_handshake(inspector_socket_t* inspector) {
http_parsing_state_s* state = inspector->http_parsing_state;
CHECK_NE(state, nullptr);
- if (state->current_header) {
- state->current_header[0] = '\0';
- }
- if (state->ws_key) {
- state->ws_key[0] = '\0';
- }
- if (state->path) {
- state->path[0] = '\0';
- }
+ state->current_header.clear();
+ state->ws_key.clear();
+ state->path.clear();
state->done = false;
http_parser_init(&state->parser, HTTP_REQUEST);
state->parser.data = inspector;
@@ -626,15 +566,8 @@ static void init_handshake(inspector_socket_t* inspector) {
int inspector_accept(uv_stream_t* server, inspector_socket_t* inspector,
handshake_cb callback) {
ASSERT_NE(callback, nullptr);
- // The only field that users should care about.
- void* data = inspector->data;
- memset(inspector, 0, sizeof(*inspector));
- inspector->data = data;
-
- inspector->http_parsing_state = (struct http_parsing_state_s*)
- malloc(sizeof(struct http_parsing_state_s));
- ASSERT_NE(nullptr, inspector->http_parsing_state);
- memset(inspector->http_parsing_state, 0, sizeof(struct http_parsing_state_s));
+ CHECK_EQ(inspector->http_parsing_state, nullptr);
+ inspector->http_parsing_state = new http_parsing_state_s();
uv_stream_t* client = reinterpret_cast<uv_stream_t*>(&inspector->client);
CHECK_NE(client, nullptr);
int err = uv_tcp_init(server->loop, &inspector->client);
diff --git a/src/inspector_socket.h b/src/inspector_socket.h
index 3e52762e71..5d3477b98c 100644
--- a/src/inspector_socket.h
+++ b/src/inspector_socket.h
@@ -4,6 +4,9 @@
#include "http_parser.h"
#include "uv.h"
+#include <string>
+#include <vector>
+
enum inspector_handshake_event {
kInspectorHandshakeUpgrading,
kInspectorHandshakeUpgraded,
@@ -19,17 +22,32 @@ typedef void (*inspector_cb)(struct inspector_socket_s*, int);
// the connection. inspector_write can be used from the callback.
typedef bool (*handshake_cb)(struct inspector_socket_s*,
enum inspector_handshake_event state,
- const char* path);
+ const std::string& path);
+
+struct http_parsing_state_s {
+ http_parser parser;
+ http_parser_settings parser_settings;
+ handshake_cb callback;
+ bool done;
+ bool parsing_value;
+ std::string ws_key;
+ std::string path;
+ std::string current_header;
+};
-struct http_parsing_state_s;
-struct ws_state_s;
+struct ws_state_s {
+ uv_alloc_cb alloc_cb;
+ uv_read_cb read_cb;
+ inspector_cb close_cb;
+ bool close_sent;
+ bool received_close;
+};
struct inspector_socket_s {
void* data;
struct http_parsing_state_s* http_parsing_state;
struct ws_state_s* ws_state;
- char* buffer;
- size_t buffer_size;
+ std::vector<char> buffer;
size_t data_len;
size_t last_read_end;
uv_tcp_t client;