5 #define NODE_WANT_INTERNALS 1 8 #include "openssl/sha.h" 13 #define ACCEPT_KEY_LENGTH base64_encoded_size(20) 14 #define BUFFER_GROWTH_CHUNK_SIZE 1024 22 static const char CLOSE_FRAME[] = {
'\x88',
'\x00'};
28 #if DUMP_READS || DUMP_WRITES 29 static void dump_hex(
const char*
buf,
size_t len) {
30 const char* ptr =
buf;
31 const char* end = ptr +
len;
38 for (i = 0; i < 16 && ptr < end; i++) {
39 printf(
"%2.2X ", static_cast<unsigned char>(*(ptr++)));
41 for (i = 72 - (i * 4); i > 0; i--) {
44 for (i = 0; i < 16 && cptr < end; i++) {
46 printf(
"%c", (c > 0x19) ? c :
'.');
54 static void remove_from_beginning(std::vector<char>* buffer,
size_t count) {
55 buffer->erase(buffer->begin(), buffer->begin() + count);
58 static void dispose_inspector(uv_handle_t* handle) {
71 uv_handle_t* socket =
reinterpret_cast<uv_handle_t*
>(&inspector->
tcp);
72 if (!uv_is_closing(socket)) {
73 uv_read_stop(reinterpret_cast<uv_stream_t*>(socket));
74 uv_close(socket, dispose_inspector);
80 : inspector(inspector)
95 static void write_request_cleanup(uv_write_t*
req,
int status) {
102 uv_write_cb write_cb = write_request_cleanup) {
104 printf(
"%s (%ld bytes):\n", __FUNCTION__, len);
110 uv_stream_t* stream =
reinterpret_cast<uv_stream_t*
>(&inspector->
tcp);
111 return uv_write(&wr->
req, stream, &wr->
buf, 1, write_cb) < 0;
138 static std::vector<char> encode_frame_hybi17(
const char* message,
139 size_t data_length) {
140 std::vector<char> frame;
142 frame.push_back(kFinalBit | op_code);
143 if (data_length <= kMaxSingleBytePayloadLength) {
144 frame.push_back(static_cast<char>(data_length));
145 }
else if (data_length <= 0xFFFF) {
146 frame.push_back(kTwoBytePayloadLengthField);
147 frame.push_back((data_length & 0xFF00) >> 8);
148 frame.push_back(data_length & 0xFF);
150 frame.push_back(kEightBytePayloadLengthField);
151 char extended_payload_length[8];
152 size_t remaining = data_length;
154 for (
int i = 0; i < 8; ++i) {
155 extended_payload_length[7 - i] = remaining & 0xFF;
158 frame.insert(frame.end(), extended_payload_length,
159 extended_payload_length + 8);
160 CHECK_EQ(0, remaining);
162 frame.insert(frame.end(), message, message + data_length);
166 static ws_decode_result decode_frame_hybi17(
const std::vector<char>& buffer,
169 std::vector<char>* output,
172 if (buffer.size() < 2)
175 auto it = buffer.begin();
177 unsigned char first_byte = *it++;
178 unsigned char second_byte = *it++;
180 bool final = (first_byte &
kFinalBit) != 0;
185 bool masked = (second_byte &
kMaskBit) != 0;
186 *compressed = reserved1;
187 if (!
final || reserved2 || reserved3)
206 if (client_frame && !masked) {
211 if (payload_length64 > kMaxSingleBytePayloadLength) {
212 int extended_payload_length_size;
213 if (payload_length64 == kTwoBytePayloadLengthField) {
214 extended_payload_length_size = 2;
215 }
else if (payload_length64 == kEightBytePayloadLengthField) {
216 extended_payload_length_size = 8;
220 if ((buffer.end() - it) < extended_payload_length_size)
222 payload_length64 = 0;
223 for (
int i = 0; i < extended_payload_length_size; ++i) {
224 payload_length64 <<= 8;
225 payload_length64 |=
static_cast<unsigned char>(*it++);
229 static const uint64_t max_payload_length = 0x7FFFFFFFFFFFFFFFull;
230 static const size_t max_length = SIZE_MAX;
231 if (payload_length64 > max_payload_length ||
232 payload_length64 > max_length - kMaskingKeyWidthInBytes) {
236 size_t payload_length =
static_cast<size_t>(payload_length64);
238 if (buffer.size() - kMaskingKeyWidthInBytes < payload_length)
241 std::vector<char>::const_iterator masking_key = it;
243 for (
size_t i = 0; i < payload_length; ++i)
244 output->insert(output->end(),
247 size_t pos = it + kMaskingKeyWidthInBytes + payload_length - buffer.begin();
248 *bytes_consumed = pos;
256 reinterpret_cast<uv_stream_t*>(&inspector->
tcp), status, buf);
261 close_connection(inspector);
264 static void on_close_frame_written(uv_write_t*
req,
int status) {
270 shutdown_complete(inspector);
277 invoke_read_callback(inspector, 0, 0);
278 write_to_client(inspector, CLOSE_FRAME,
sizeof(CLOSE_FRAME),
279 on_close_frame_written);
281 shutdown_complete(inspector);
286 int bytes_consumed = 0;
287 std::vector<char> output;
288 bool compressed =
false;
292 &bytes_consumed, &output,
295 if (compressed || r == FRAME_ERROR) {
296 invoke_read_callback(inspector, UV_EPROTO,
nullptr);
297 close_connection(inspector);
300 close_frame_received(inspector);
305 size_t len = output.size();
307 reinterpret_cast<uv_handle_t*>(&inspector->
tcp),
309 CHECK_GE(buffer.len, len);
310 memcpy(buffer.base, &output[0], len);
311 invoke_read_callback(inspector, len, &buffer);
313 return bytes_consumed;
316 static void prepare_buffer(uv_handle_t* stream,
size_t len, uv_buf_t* buf) {
317 *buf = uv_buf_init(
new char[len], len);
320 static void reclaim_uv_buf(
InspectorSocket* inspector,
const uv_buf_t* buf,
323 std::vector<char>& buffer = inspector->
buffer;
324 buffer.insert(buffer.end(), buf->base, buf->base + read);
329 static void websockets_data_cb(uv_stream_t* stream, ssize_t nread,
330 const uv_buf_t* buf) {
332 reclaim_uv_buf(inspector, buf, nread);
333 if (nread < 0 || nread == UV_EOF) {
340 shutdown_complete(inspector);
344 printf(
"%s read %ld bytes\n", __FUNCTION__, nread);
346 dump_hex(inspector->
buffer.data() + inspector->
buffer.size() - nread,
353 processed = parse_ws_frames(inspector);
356 remove_from_beginning(&inspector->
buffer, processed);
358 }
while (processed > 0 && !inspector->
buffer.empty());
363 uv_alloc_cb alloc_cb, uv_read_cb read_cb) {
370 uv_read_start(reinterpret_cast<uv_stream_t*>(&inspector->
tcp),
374 close_connection(inspector);
380 uv_read_stop(reinterpret_cast<uv_stream_t*>(&inspector->
tcp));
385 static void generate_accept_string(
const std::string& client_key,
388 static const char ws_magic[] =
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
389 std::string input(client_key + ws_magic);
390 char hash[SHA_DIGEST_LENGTH];
391 SHA1(reinterpret_cast<const unsigned char*>(&input[0]), input.size(),
392 reinterpret_cast<unsigned char*
>(hash));
393 node::base64_encode(hash,
sizeof(hash), *buffer,
sizeof(*buffer));
396 static int header_value_cb(http_parser* parser,
const char* at,
size_t length) {
397 static const char SEC_WEBSOCKET_KEY_HEADER[] =
"Sec-WebSocket-Key";
401 if (state->current_header.size() ==
sizeof(SEC_WEBSOCKET_KEY_HEADER) - 1 &&
402 node::StringEqualNoCaseN(state->current_header.data(),
403 SEC_WEBSOCKET_KEY_HEADER,
404 sizeof(SEC_WEBSOCKET_KEY_HEADER) - 1)) {
405 state->ws_key.append(at, length);
410 static int header_field_cb(http_parser* parser,
const char* at,
size_t length) {
413 if (state->parsing_value) {
415 state->current_header.clear();
417 state->current_header.append(at, length);
421 static int path_cb(http_parser* parser,
const char* at,
size_t length) {
424 state->
path.append(at, length);
429 uv_read_stop(reinterpret_cast<uv_stream_t*>(&inspector->
tcp));
442 static void report_handshake_failure_cb(uv_handle_t* handle) {
443 dispose_inspector(handle);
446 cleanup_http_parsing_state(inspector);
450 static void close_and_report_handshake_failure(
InspectorSocket* inspector) {
451 uv_handle_t* socket =
reinterpret_cast<uv_handle_t*
>(&inspector->
tcp);
452 if (uv_is_closing(socket)) {
453 report_handshake_failure_cb(socket);
455 uv_read_stop(reinterpret_cast<uv_stream_t*>(socket));
456 uv_close(socket, report_handshake_failure_cb);
460 static void then_close_and_report_failure(uv_write_t* req,
int status) {
462 write_request_cleanup(req, status);
463 close_and_report_handshake_failure(inspector);
467 const char HANDSHAKE_FAILED_RESPONSE[] =
468 "HTTP/1.0 400 Bad Request\r\n" 469 "Content-Type: text/html; charset=UTF-8\r\n\r\n" 470 "WebSockets request was expected\r\n";
471 write_to_client(inspector, HANDSHAKE_FAILED_RESPONSE,
472 sizeof(HANDSHAKE_FAILED_RESPONSE) - 1,
473 then_close_and_report_failure);
479 static int message_complete_cb(http_parser* parser) {
482 if (parser->method != HTTP_GET) {
483 handshake_failed(inspector);
484 }
else if (!parser->upgrade) {
486 init_handshake(inspector);
488 handshake_failed(inspector);
490 }
else if (state->
ws_key.empty()) {
491 handshake_failed(inspector);
495 generate_accept_string(state->
ws_key, &accept_string);
496 const char accept_ws_prefix[] =
"HTTP/1.1 101 Switching Protocols\r\n" 497 "Upgrade: websocket\r\n" 498 "Connection: Upgrade\r\n" 499 "Sec-WebSocket-Accept: ";
500 const char accept_ws_suffix[] =
"\r\n\r\n";
501 std::string reply(accept_ws_prefix,
sizeof(accept_ws_prefix) - 1);
502 reply.append(accept_string,
sizeof(accept_string));
503 reply.append(accept_ws_suffix,
sizeof(accept_ws_suffix) - 1);
504 if (write_to_client(inspector, &reply[0], reply.size()) >= 0) {
505 handshake_complete(inspector);
508 close_and_report_handshake_failure(inspector);
511 handshake_failed(inspector);
516 static void data_received_cb(uv_stream_s* tcp, ssize_t nread,
517 const uv_buf_t* buf) {
520 printf(
"%s (%ld bytes)\n", __FUNCTION__, nread);
521 dump_hex(buf->base, nread);
523 printf(
"[%s:%d] %s\n", __FUNCTION__, __LINE__, uv_err_name(nread));
527 reclaim_uv_buf(inspector, buf, nread);
528 if (nread < 0 || nread == UV_EOF) {
529 close_and_report_handshake_failure(inspector);
532 http_parser* parser = &state->
parser;
534 inspector->
buffer.data(), nread);
535 remove_from_beginning(&inspector->
buffer, nread);
536 if (parser->http_errno != HPE_OK) {
537 handshake_failed(inspector);
540 cleanup_http_parsing_state(inspector);
547 CHECK_NE(state,
nullptr);
552 http_parser_init(&state->
parser, HTTP_REQUEST);
553 state->
parser.data = socket;
555 http_parser_settings_init(settings);
556 settings->on_header_field = header_field_cb;
557 settings->on_header_value = header_value_cb;
558 settings->on_message_complete = message_complete_cb;
559 settings->on_url = path_cb;
564 CHECK_NE(callback,
nullptr);
568 uv_stream_t* tcp =
reinterpret_cast<uv_stream_t*
>(&socket->
tcp);
569 int err = uv_tcp_init(server->loop, &socket->
tcp);
572 err = uv_accept(server, tcp);
575 init_handshake(socket);
577 err = uv_read_start(tcp, prepare_buffer,
581 uv_close(reinterpret_cast<uv_handle_t*>(tcp), NULL);
589 std::vector<char> output = encode_frame_hybi17(data, len);
590 write_to_client(inspector, &output[0], output.size());
592 write_to_client(inspector, data, len);
600 CHECK(!uv_is_closing(reinterpret_cast<uv_handle_t*>(&inspector->
tcp)));
605 close_connection(inspector);
608 write_to_client(inspector, CLOSE_FRAME,
sizeof(CLOSE_FRAME),
609 on_close_frame_written);
615 const uv_handle_t* tcp =
616 reinterpret_cast<const uv_handle_t*
>(&inspector->
tcp);
621 http_parsing_state =
nullptr;
625 shutting_down =
false;
626 connection_eof =
false;
bool(* handshake_cb)(InspectorSocket *, enum inspector_handshake_event state, const std::string &path)
void inspector_close(InspectorSocket *inspector, inspector_cb callback)
http_parser_settings parser_settings
InspectorSocket *const inspector
void inspector_read_stop(InspectorSocket *inspector)
const unsigned char kOpCodeMask
const unsigned char kReserved3Bit
void(* inspector_cb)(InspectorSocket *, int)
#define ACCEPT_KEY_LENGTH
static WriteRequest * from_write_req(uv_write_t *req)
std::string current_header
void inspector_write(InspectorSocket *inspector, const char *data, size_t len)
const OpCode kOpCodeClose
const unsigned char kPayloadLengthMask
const unsigned char kReserved1Bit
const size_t kMaxSingleBytePayloadLength
union node::cares_wrap::@8::CaresAsyncData::@0 data
const OpCode kOpCodeContinuation
const size_t kTwoBytePayloadLengthField
const unsigned char kFinalBit
InspectorSocket * inspector_from_stream(uv_tcp_t *stream)
WriteRequest(InspectorSocket *inspector, const char *data, size_t size)
struct ws_state_s * ws_state
int inspector_accept(uv_stream_t *server, InspectorSocket *socket, handshake_cb callback)
std::vector< char > buffer
const unsigned char kMaskBit
struct http_parsing_state_s * http_parsing_state
bool inspector_is_active(const InspectorSocket *inspector)
const size_t kEightBytePayloadLengthField
const size_t kMaskingKeyWidthInBytes
const OpCode kOpCodeBinary
int inspector_read_start(InspectorSocket *inspector, uv_alloc_cb alloc_cb, uv_read_cb read_cb)
const unsigned char kReserved2Bit
std::vector< char > storage