GCC Code Coverage Report
Directory: ../src/ Exec Total Coverage
File: /home/node-core-coverage/node-core-coverage/workdir/node/src/inspector_socket.cc Lines: 0 360 0.0 %
Date: 2016-07-26 Branches: 0 167 0.0 %

Line Exec Source
1
#include "inspector_socket.h"
2
#include "util.h"
3
#include "util-inl.h"
4
5
#define NODE_WANT_INTERNALS 1
6
#include "base64.h"
7
8
#include "openssl/sha.h"  // Sha-1 hash
9
10
#include <string.h>
11
#include <vector>
12
13
#define ACCEPT_KEY_LENGTH base64_encoded_size(20)
14
#define BUFFER_GROWTH_CHUNK_SIZE 1024
15
16
#define DUMP_READS 0
17
#define DUMP_WRITES 0
18
19
static const char CLOSE_FRAME[] = {'\x88', '\x00'};
20
21
struct http_parsing_state_s {
22
  http_parser parser;
23
  http_parser_settings parser_settings;
24
  handshake_cb callback;
25
  bool done;
26
  bool parsing_value;
27
  char* ws_key;
28
  char* path;
29
  char* current_header;
30
};
31
32
struct ws_state_s {
33
  uv_alloc_cb alloc_cb;
34
  uv_read_cb read_cb;
35
  inspector_cb close_cb;
36
  bool close_sent;
37
  bool received_close;
38
};
39
40
enum ws_decode_result {
41
  FRAME_OK, FRAME_INCOMPLETE, FRAME_CLOSE, FRAME_ERROR
42
};
43
44
#if DUMP_READS || DUMP_WRITES
45
static void dump_hex(const char* buf, size_t len) {
46
  const char* ptr = buf;
47
  const char* end = ptr + len;
48
  const char* cptr;
49
  char c;
50
  int i;
51
52
  while (ptr < end) {
53
    cptr = ptr;
54
    for (i = 0; i < 16 && ptr < end; i++) {
55
      printf("%2.2X  ", *(ptr++));
56
    }
57
    for (i = 72 - (i * 4); i > 0; i--) {
58
      printf(" ");
59
    }
60
    for (i = 0; i < 16 && cptr < end; i++) {
61
      c = *(cptr++);
62
      printf("%c", (c > 0x19) ? c : '.');
63
    }
64
    printf("\n");
65
  }
66
  printf("\n\n");
67
}
68
#endif
69
70
static void dispose_inspector(uv_handle_t* handle) {
71
  inspector_socket_t* inspector =
72
      reinterpret_cast<inspector_socket_t*>(handle->data);
73
  inspector_cb close =
74
      inspector->ws_mode ? inspector->ws_state->close_cb : nullptr;
75
  free(inspector->buffer);
76
  free(inspector->ws_state);
77
  inspector->ws_state = nullptr;
78
  inspector->buffer = nullptr;
79
  inspector->buffer_size = 0;
80
  inspector->data_len = 0;
81
  inspector->last_read_end = 0;
82
  if (close) {
83
    close(inspector, 0);
84
  }
85
}
86
87
static void close_connection(inspector_socket_t* inspector) {
88
  uv_handle_t* socket = reinterpret_cast<uv_handle_t*>(&inspector->client);
89
  if (!uv_is_closing(socket)) {
90
    uv_read_stop(reinterpret_cast<uv_stream_t*>(socket));
91
    uv_close(socket, dispose_inspector);
92
  }
93
}
94
95
// Cleanup
96
static void write_request_cleanup(uv_write_t* req, int status) {
97
  free((reinterpret_cast<uv_buf_t*>(req->data))->base);
98
  free(req->data);
99
  free(req);
100
}
101
102
static int write_to_client(inspector_socket_t* inspector,
103
                           const char* msg,
104
                           size_t len,
105
                           uv_write_cb write_cb = write_request_cleanup) {
106
#if DUMP_WRITES
107
  printf("%s (%ld bytes):\n", __FUNCTION__, len);
108
  dump_hex(msg, len);
109
#endif
110
111
  // Freed in write_request_cleanup
112
  uv_buf_t* buf = reinterpret_cast<uv_buf_t*>(malloc(sizeof(uv_buf_t)));
113
  uv_write_t* req = reinterpret_cast<uv_write_t*>(malloc(sizeof(uv_write_t)));
114
  CHECK_NE(buf, nullptr);
115
  CHECK_NE(req, nullptr);
116
  memset(req, 0, sizeof(*req));
117
  buf->base = reinterpret_cast<char*>(malloc(len));
118
119
  CHECK_NE(buf->base, nullptr);
120
121
  memcpy(buf->base, msg, len);
122
  buf->len = len;
123
  req->data = buf;
124
125
  uv_stream_t* stream = reinterpret_cast<uv_stream_t*>(&inspector->client);
126
  return uv_write(req, stream, buf, 1, write_cb) < 0;
127
}
128
129
// Constants for hybi-10 frame format.
130
131
typedef int OpCode;
132
133
const OpCode kOpCodeContinuation = 0x0;
134
const OpCode kOpCodeText = 0x1;
135
const OpCode kOpCodeBinary = 0x2;
136
const OpCode kOpCodeClose = 0x8;
137
const OpCode kOpCodePing = 0x9;
138
const OpCode kOpCodePong = 0xA;
139
140
const unsigned char kFinalBit = 0x80;
141
const unsigned char kReserved1Bit = 0x40;
142
const unsigned char kReserved2Bit = 0x20;
143
const unsigned char kReserved3Bit = 0x10;
144
const unsigned char kOpCodeMask = 0xF;
145
const unsigned char kMaskBit = 0x80;
146
const unsigned char kPayloadLengthMask = 0x7F;
147
148
const size_t kMaxSingleBytePayloadLength = 125;
149
const size_t kTwoBytePayloadLengthField = 126;
150
const size_t kEightBytePayloadLengthField = 127;
151
const size_t kMaskingKeyWidthInBytes = 4;
152
153
static std::vector<char> encode_frame_hybi17(const char* message,
154
                                             size_t data_length) {
155
  std::vector<char> frame;
156
  OpCode op_code = kOpCodeText;
157
  frame.push_back(kFinalBit | op_code);
158
  if (data_length <= kMaxSingleBytePayloadLength) {
159
    frame.push_back(static_cast<char>(data_length));
160
  } else if (data_length <= 0xFFFF) {
161
    frame.push_back(kTwoBytePayloadLengthField);
162
    frame.push_back((data_length & 0xFF00) >> 8);
163
    frame.push_back(data_length & 0xFF);
164
  } else {
165
    frame.push_back(kEightBytePayloadLengthField);
166
    char extended_payload_length[8];
167
    size_t remaining = data_length;
168
    // Fill the length into extended_payload_length in the network byte order.
169
    for (int i = 0; i < 8; ++i) {
170
      extended_payload_length[7 - i] = remaining & 0xFF;
171
      remaining >>= 8;
172
    }
173
    frame.insert(frame.end(), extended_payload_length,
174
                 extended_payload_length + 8);
175
    ASSERT_EQ(0, remaining);
176
  }
177
  frame.insert(frame.end(), message, message + data_length);
178
  return frame;
179
}
180
181
static ws_decode_result decode_frame_hybi17(const char* buffer_begin,
182
                                            size_t data_length,
183
                                            bool client_frame,
184
                                            int* bytes_consumed,
185
                                            std::vector<char>* output,
186
                                            bool* compressed) {
187
  *bytes_consumed = 0;
188
  if (data_length < 2)
189
    return FRAME_INCOMPLETE;
190
191
  const char* p = buffer_begin;
192
  const char* buffer_end = p + data_length;
193
194
  unsigned char first_byte = *p++;
195
  unsigned char second_byte = *p++;
196
197
  bool final = (first_byte & kFinalBit) != 0;
198
  bool reserved1 = (first_byte & kReserved1Bit) != 0;
199
  bool reserved2 = (first_byte & kReserved2Bit) != 0;
200
  bool reserved3 = (first_byte & kReserved3Bit) != 0;
201
  int op_code = first_byte & kOpCodeMask;
202
  bool masked = (second_byte & kMaskBit) != 0;
203
  *compressed = reserved1;
204
  if (!final || reserved2 || reserved3)
205
    return FRAME_ERROR;  // Only compression extension is supported.
206
207
  bool closed = false;
208
  switch (op_code) {
209
    case kOpCodeClose:
210
      closed = true;
211
      break;
212
    case kOpCodeText:
213
      break;
214
    case kOpCodeBinary:        // We don't support binary frames yet.
215
    case kOpCodeContinuation:  // We don't support binary frames yet.
216
    case kOpCodePing:          // We don't support binary frames yet.
217
    case kOpCodePong:          // We don't support binary frames yet.
218
    default:
219
      return FRAME_ERROR;
220
  }
221
222
  // In Hybi-17 spec client MUST mask its frame.
223
  if (client_frame && !masked) {
224
    return FRAME_ERROR;
225
  }
226
227
  uint64_t payload_length64 = second_byte & kPayloadLengthMask;
228
  if (payload_length64 > kMaxSingleBytePayloadLength) {
229
    int extended_payload_length_size;
230
    if (payload_length64 == kTwoBytePayloadLengthField) {
231
      extended_payload_length_size = 2;
232
    } else if (payload_length64 == kEightBytePayloadLengthField) {
233
      extended_payload_length_size = 8;
234
    } else {
235
      return FRAME_ERROR;
236
    }
237
    if (buffer_end - p < extended_payload_length_size)
238
      return FRAME_INCOMPLETE;
239
    payload_length64 = 0;
240
    for (int i = 0; i < extended_payload_length_size; ++i) {
241
      payload_length64 <<= 8;
242
      payload_length64 |= static_cast<unsigned char>(*p++);
243
    }
244
  }
245
246
  static const uint64_t max_payload_length = 0x7FFFFFFFFFFFFFFFull;
247
  static const size_t max_length = SIZE_MAX;
248
  if (payload_length64 > max_payload_length ||
249
      payload_length64 > max_length - kMaskingKeyWidthInBytes) {
250
    // WebSocket frame length too large.
251
    return FRAME_ERROR;
252
  }
253
  size_t payload_length = static_cast<size_t>(payload_length64);
254
255
  if (data_length - kMaskingKeyWidthInBytes < payload_length)
256
    return FRAME_INCOMPLETE;
257
258
  const char* masking_key = p;
259
  const char* payload = p + kMaskingKeyWidthInBytes;
260
  for (size_t i = 0; i < payload_length; ++i)  // Unmask the payload.
261
    output->insert(output->end(),
262
                   payload[i] ^ masking_key[i % kMaskingKeyWidthInBytes]);
263
264
  size_t pos = p + kMaskingKeyWidthInBytes + payload_length - buffer_begin;
265
  *bytes_consumed = pos;
266
  return closed ? FRAME_CLOSE : FRAME_OK;
267
}
268
269
static void invoke_read_callback(inspector_socket_t* inspector,
270
                                 int status, const uv_buf_t* buf) {
271
  if (inspector->ws_state->read_cb) {
272
    inspector->ws_state->read_cb(
273
        reinterpret_cast<uv_stream_t*>(&inspector->client), status, buf);
274
  }
275
}
276
277
static void shutdown_complete(inspector_socket_t* inspector) {
278
  close_connection(inspector);
279
}
280
281
static void on_close_frame_written(uv_write_t* write, int status) {
282
  inspector_socket_t* inspector =
283
      reinterpret_cast<inspector_socket_t*>(write->handle->data);
284
  write_request_cleanup(write, status);
285
  inspector->ws_state->close_sent = true;
286
  if (inspector->ws_state->received_close) {
287
    shutdown_complete(inspector);
288
  }
289
}
290
291
static void close_frame_received(inspector_socket_t* inspector) {
292
  inspector->ws_state->received_close = true;
293
  if (!inspector->ws_state->close_sent) {
294
    invoke_read_callback(inspector, 0, 0);
295
    write_to_client(inspector, CLOSE_FRAME, sizeof(CLOSE_FRAME),
296
                    on_close_frame_written);
297
  } else {
298
    shutdown_complete(inspector);
299
  }
300
}
301
302
static int parse_ws_frames(inspector_socket_t* inspector, size_t len) {
303
  int bytes_consumed = 0;
304
  std::vector<char> output;
305
  bool compressed = false;
306
307
  ws_decode_result r =  decode_frame_hybi17(inspector->buffer,
308
                                            len, true /* client_frame */,
309
                                            &bytes_consumed, &output,
310
                                            &compressed);
311
  // Compressed frame means client is ignoring the headers and misbehaves
312
  if (compressed || r == FRAME_ERROR) {
313
    invoke_read_callback(inspector, UV_EPROTO, nullptr);
314
    close_connection(inspector);
315
    bytes_consumed = 0;
316
  } else if (r == FRAME_CLOSE) {
317
    close_frame_received(inspector);
318
    bytes_consumed = 0;
319
  } else if (r == FRAME_OK && inspector->ws_state->alloc_cb
320
             && inspector->ws_state->read_cb) {
321
    uv_buf_t buffer;
322
    size_t len = output.size();
323
    inspector->ws_state->alloc_cb(
324
        reinterpret_cast<uv_handle_t*>(&inspector->client),
325
        len, &buffer);
326
    CHECK_GE(buffer.len, len);
327
    memcpy(buffer.base, &output[0], len);
328
    invoke_read_callback(inspector, len, &buffer);
329
  }
330
  return bytes_consumed;
331
}
332
333
static void prepare_buffer(uv_handle_t* stream, size_t len, uv_buf_t* buf) {
334
  inspector_socket_t* inspector =
335
      reinterpret_cast<inspector_socket_t*>(stream->data);
336
337
  if (len > (inspector->buffer_size - inspector->data_len)) {
338
    int new_size = (inspector->data_len + len + BUFFER_GROWTH_CHUNK_SIZE - 1) /
339
                   BUFFER_GROWTH_CHUNK_SIZE *
340
                   BUFFER_GROWTH_CHUNK_SIZE;
341
    inspector->buffer_size = new_size;
342
    inspector->buffer = reinterpret_cast<char*>(realloc(inspector->buffer,
343
                                        inspector->buffer_size));
344
    ASSERT_NE(inspector->buffer, nullptr);
345
  }
346
  buf->base = inspector->buffer + inspector->data_len;
347
  buf->len = len;
348
  inspector->data_len += len;
349
}
350
351
static void websockets_data_cb(uv_stream_t* stream, ssize_t nread,
352
                               const uv_buf_t* buf) {
353
  inspector_socket_t* inspector =
354
      reinterpret_cast<inspector_socket_t*>(stream->data);
355
  if (nread < 0 || nread == UV_EOF) {
356
    inspector->connection_eof = true;
357
    if (!inspector->shutting_down && inspector->ws_state->read_cb) {
358
      inspector->ws_state->read_cb(stream, nread, nullptr);
359
    }
360
  } else {
361
    #if DUMP_READS
362
      printf("%s read %ld bytes\n", __FUNCTION__, nread);
363
      if (nread > 0) {
364
        dump_hex(buf->base, nread);
365
      }
366
    #endif
367
    // 1. Move read bytes to continue the buffer
368
    // Should be same as this is supposedly last buffer
369
    ASSERT_EQ(buf->base + buf->len, inspector->buffer + inspector->data_len);
370
371
    // Should be noop...
372
    memmove(inspector->buffer + inspector->last_read_end, buf->base, nread);
373
    inspector->last_read_end += nread;
374
375
    // 2. Parse.
376
    int processed = 0;
377
    do {
378
      processed = parse_ws_frames(inspector, inspector->last_read_end);
379
      // 3. Fix the buffer size & length
380
      if (processed > 0) {
381
        memmove(inspector->buffer, inspector->buffer + processed,
382
            inspector->last_read_end - processed);
383
        inspector->last_read_end -= processed;
384
        inspector->data_len = inspector->last_read_end;
385
      }
386
    } while (processed > 0 && inspector->data_len > 0);
387
  }
388
}
389
390
int inspector_read_start(inspector_socket_t* inspector,
391
                          uv_alloc_cb alloc_cb, uv_read_cb read_cb) {
392
  ASSERT(inspector->ws_mode);
393
  ASSERT(!inspector->shutting_down || read_cb == nullptr);
394
  inspector->ws_state->close_sent = false;
395
  inspector->ws_state->alloc_cb = alloc_cb;
396
  inspector->ws_state->read_cb = read_cb;
397
  int err =
398
      uv_read_start(reinterpret_cast<uv_stream_t*>(&inspector->client),
399
                    prepare_buffer,
400
                    websockets_data_cb);
401
  if (err < 0) {
402
    close_connection(inspector);
403
  }
404
  return err;
405
}
406
407
void inspector_read_stop(inspector_socket_t* inspector) {
408
  uv_read_stop(reinterpret_cast<uv_stream_t*>(&inspector->client));
409
  inspector->ws_state->alloc_cb = nullptr;
410
  inspector->ws_state->read_cb = nullptr;
411
}
412
413
static void generate_accept_string(const char* client_key, char* buffer) {
414
  // Magic string from websockets spec.
415
  const char ws_magic[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
416
  size_t key_len = strlen(client_key);
417
  size_t magic_len = sizeof(ws_magic) - 1;
418
419
  char* buf = reinterpret_cast<char*>(malloc(key_len + magic_len));
420
  CHECK_NE(buf, nullptr);
421
  memcpy(buf, client_key, key_len);
422
  memcpy(buf + key_len, ws_magic, magic_len);
423
  char hash[20];
424
  SHA1((unsigned char*) buf, key_len + magic_len, (unsigned char*) hash);
425
  free(buf);
426
  node::base64_encode(hash, 20, buffer, ACCEPT_KEY_LENGTH);
427
  buffer[ACCEPT_KEY_LENGTH] = '\0';
428
}
429
430
static void append(char** value, const char* string, size_t length) {
431
  const size_t INCREMENT = 500;  // There should never be more then 1 chunk...
432
433
  int current_len = *value ? strlen(*value) : 0;
434
  int new_len = current_len + length;
435
  int adjusted = (new_len / INCREMENT + 1) * INCREMENT;
436
  *value = reinterpret_cast<char*>(realloc(*value, adjusted));
437
  memcpy(*value + current_len, string, length);
438
  (*value)[new_len] = '\0';
439
}
440
441
static int header_value_cb(http_parser* parser, const char* at, size_t length) {
442
  char SEC_WEBSOCKET_KEY_HEADER[] = "Sec-WebSocket-Key";
443
  struct http_parsing_state_s* state = (struct http_parsing_state_s*)
444
      (reinterpret_cast<inspector_socket_t*>(parser->data))->http_parsing_state;
445
  state->parsing_value = true;
446
  if (state->current_header &&
447
      node::StringEqualNoCaseN(state->current_header,
448
                               SEC_WEBSOCKET_KEY_HEADER,
449
                               sizeof(SEC_WEBSOCKET_KEY_HEADER))) {
450
    append(&state->ws_key, at, length);
451
  }
452
  return 0;
453
}
454
455
static int header_field_cb(http_parser* parser, const char* at, size_t length) {
456
  struct http_parsing_state_s* state = (struct http_parsing_state_s*)
457
      (reinterpret_cast<inspector_socket_t*>(parser->data))->http_parsing_state;
458
  if (state->parsing_value) {
459
    state->parsing_value = false;
460
    if (state->current_header)
461
      state->current_header[0] = '\0';
462
  }
463
  append(&state->current_header, at, length);
464
  return 0;
465
}
466
467
static int path_cb(http_parser* parser, const char* at, size_t length) {
468
  struct http_parsing_state_s* state = (struct http_parsing_state_s*)
469
    (reinterpret_cast<inspector_socket_t*>(parser->data))->http_parsing_state;
470
  append(&state->path, at, length);
471
  return 0;
472
}
473
474
static void handshake_complete(inspector_socket_t* inspector) {
475
  uv_read_stop(reinterpret_cast<uv_stream_t*>(&inspector->client));
476
  handshake_cb callback = inspector->http_parsing_state->callback;
477
  inspector->ws_state = (struct ws_state_s*) malloc(sizeof(struct ws_state_s));
478
  ASSERT_NE(nullptr, inspector->ws_state);
479
  memset(inspector->ws_state, 0, sizeof(struct ws_state_s));
480
  inspector->last_read_end = 0;
481
  inspector->ws_mode = true;
482
  callback(inspector, kInspectorHandshakeUpgraded,
483
           inspector->http_parsing_state->path);
484
}
485
486
static void cleanup_http_parsing_state(inspector_socket_t* inspector) {
487
  struct http_parsing_state_s* state = inspector->http_parsing_state;
488
  free(state->current_header);
489
  free(state->path);
490
  free(state->ws_key);
491
  free(state);
492
  inspector->http_parsing_state = nullptr;
493
}
494
495
static void report_handshake_failure_cb(uv_handle_t* handle) {
496
  dispose_inspector(handle);
497
  inspector_socket_t* inspector =
498
      static_cast<inspector_socket_t*>(handle->data);
499
  handshake_cb cb = inspector->http_parsing_state->callback;
500
  cleanup_http_parsing_state(inspector);
501
  cb(inspector, kInspectorHandshakeFailed, nullptr);
502
}
503
504
static void close_and_report_handshake_failure(inspector_socket_t* inspector) {
505
  uv_handle_t* socket = reinterpret_cast<uv_handle_t*>(&inspector->client);
506
  if (uv_is_closing(socket)) {
507
    report_handshake_failure_cb(socket);
508
  } else {
509
    uv_read_stop(reinterpret_cast<uv_stream_t*>(socket));
510
    uv_close(socket, report_handshake_failure_cb);
511
  }
512
}
513
514
static void handshake_failed(inspector_socket_t* inspector) {
515
  const char HANDSHAKE_FAILED_RESPONSE[] =
516
      "HTTP/1.0 400 Bad Request\r\n"
517
      "Content-Type: text/html; charset=UTF-8\r\n\r\n"
518
      "WebSockets request was expected\r\n";
519
  write_to_client(inspector, HANDSHAKE_FAILED_RESPONSE,
520
                  sizeof(HANDSHAKE_FAILED_RESPONSE) - 1);
521
  close_and_report_handshake_failure(inspector);
522
}
523
524
// init_handshake references message_complete_cb
525
static void init_handshake(inspector_socket_t* inspector);
526
527
static int message_complete_cb(http_parser* parser) {
528
  inspector_socket_t* inspector =
529
      reinterpret_cast<inspector_socket_t*>(parser->data);
530
  struct http_parsing_state_s* state =
531
      (struct http_parsing_state_s*) inspector->http_parsing_state;
532
  if (parser->method != HTTP_GET) {
533
    handshake_failed(inspector);
534
  } else if (!parser->upgrade) {
535
    if (state->callback(inspector, kInspectorHandshakeHttpGet, state->path)) {
536
      init_handshake(inspector);
537
    } else {
538
      handshake_failed(inspector);
539
    }
540
  } else if (!state->ws_key) {
541
    handshake_failed(inspector);
542
  } else if (state->callback(inspector, kInspectorHandshakeUpgrading,
543
                             state->path)) {
544
    char accept_string[ACCEPT_KEY_LENGTH + 1];
545
    generate_accept_string(state->ws_key, accept_string);
546
547
    const char accept_ws_prefix[] = "HTTP/1.1 101 Switching Protocols\r\n"
548
                                    "Upgrade: websocket\r\n"
549
                                    "Connection: Upgrade\r\n"
550
                                    "Sec-WebSocket-Accept: ";
551
    const char accept_ws_suffix[] = "\r\n\r\n";
552
    // Format has two chars (%s) that are replaced with actual key
553
    char accept_response[sizeof(accept_ws_prefix) - 1 +
554
                         sizeof(accept_ws_suffix) - 1 +
555
                         ACCEPT_KEY_LENGTH];
556
    memcpy(accept_response, accept_ws_prefix, sizeof(accept_ws_prefix) - 1);
557
    memcpy(accept_response + sizeof(accept_ws_prefix) - 1,
558
        accept_string, ACCEPT_KEY_LENGTH);
559
    memcpy(accept_response + sizeof(accept_ws_prefix) - 1 + ACCEPT_KEY_LENGTH,
560
        accept_ws_suffix, sizeof(accept_ws_suffix) - 1);
561
    int len = sizeof(accept_response);
562
    if (write_to_client(inspector, accept_response, len) >= 0) {
563
      handshake_complete(inspector);
564
      inspector->http_parsing_state->done = true;
565
    } else {
566
      close_and_report_handshake_failure(inspector);
567
    }
568
  } else {
569
    handshake_failed(inspector);
570
  }
571
  return 0;
572
}
573
574
static void data_received_cb(uv_stream_s* client, ssize_t nread,
575
                             const uv_buf_t* buf) {
576
#if DUMP_READS
577
  if (nread >= 0) {
578
    printf("%s (%ld bytes)\n", __FUNCTION__, nread);
579
    dump_hex(buf->base, nread);
580
  } else {
581
    printf("[%s:%d] %s\n", __FUNCTION__, __LINE__, uv_err_name(nread));
582
  }
583
#endif
584
  inspector_socket_t* inspector =
585
      reinterpret_cast<inspector_socket_t*>((client->data));
586
  if (nread < 0 || nread == UV_EOF) {
587
    close_and_report_handshake_failure(inspector);
588
  } else {
589
    http_parsing_state_s* state = inspector->http_parsing_state;
590
    http_parser* parser = &state->parser;
591
    http_parser_execute(parser, &state->parser_settings, inspector->buffer,
592
                        nread);
593
    if (parser->http_errno != HPE_OK) {
594
      handshake_failed(inspector);
595
    }
596
    if (inspector->http_parsing_state->done) {
597
      cleanup_http_parsing_state(inspector);
598
    }
599
    inspector->data_len = 0;
600
  }
601
}
602
603
static void init_handshake(inspector_socket_t* inspector) {
604
  http_parsing_state_s* state = inspector->http_parsing_state;
605
  CHECK_NE(state, nullptr);
606
  if (state->current_header) {
607
    state->current_header[0] = '\0';
608
  }
609
  if (state->ws_key) {
610
    state->ws_key[0] = '\0';
611
  }
612
  if (state->path) {
613
    state->path[0] = '\0';
614
  }
615
  state->done = false;
616
  http_parser_init(&state->parser, HTTP_REQUEST);
617
  state->parser.data = inspector;
618
  http_parser_settings* settings = &state->parser_settings;
619
  http_parser_settings_init(settings);
620
  settings->on_header_field = header_field_cb;
621
  settings->on_header_value = header_value_cb;
622
  settings->on_message_complete = message_complete_cb;
623
  settings->on_url = path_cb;
624
}
625
626
int inspector_accept(uv_stream_t* server, inspector_socket_t* inspector,
627
                     handshake_cb callback) {
628
  ASSERT_NE(callback, nullptr);
629
  // The only field that users should care about.
630
  void* data = inspector->data;
631
  memset(inspector, 0, sizeof(*inspector));
632
  inspector->data = data;
633
634
  inspector->http_parsing_state = (struct http_parsing_state_s*)
635
      malloc(sizeof(struct http_parsing_state_s));
636
  ASSERT_NE(nullptr, inspector->http_parsing_state);
637
  memset(inspector->http_parsing_state, 0, sizeof(struct http_parsing_state_s));
638
  uv_stream_t* client = reinterpret_cast<uv_stream_t*>(&inspector->client);
639
  CHECK_NE(client, nullptr);
640
  int err = uv_tcp_init(server->loop, &inspector->client);
641
642
  if (err == 0) {
643
    err = uv_accept(server, client);
644
  }
645
  if (err == 0) {
646
    client->data = inspector;
647
    init_handshake(inspector);
648
    inspector->http_parsing_state->callback = callback;
649
    err = uv_read_start(client, prepare_buffer,
650
                        data_received_cb);
651
  }
652
  if (err != 0) {
653
    uv_close(reinterpret_cast<uv_handle_t*>(client), NULL);
654
  }
655
  return err;
656
}
657
658
void inspector_write(inspector_socket_t* inspector, const char* data,
659
                     size_t len) {
660
  if (inspector->ws_mode) {
661
    std::vector<char> output = encode_frame_hybi17(data, len);
662
    write_to_client(inspector, &output[0], output.size());
663
  } else {
664
    write_to_client(inspector, data, len);
665
  }
666
}
667
668
void inspector_close(inspector_socket_t* inspector,
669
    inspector_cb callback) {
670
  // libuv throws assertions when closing stream that's already closed - we
671
  // need to do the same.
672
  ASSERT(!uv_is_closing(reinterpret_cast<uv_handle_t*>(&inspector->client)));
673
  ASSERT(!inspector->shutting_down);
674
  inspector->shutting_down = true;
675
  inspector->ws_state->close_cb = callback;
676
  if (inspector->connection_eof) {
677
    close_connection(inspector);
678
  } else {
679
    inspector_read_stop(inspector);
680
    write_to_client(inspector, CLOSE_FRAME, sizeof(CLOSE_FRAME),
681
                    on_close_frame_written);
682
    inspector_read_start(inspector, nullptr, nullptr);
683
  }
684
}
685
686
bool inspector_is_active(const struct inspector_socket_s* inspector) {
687
  const uv_handle_t* client =
688
      reinterpret_cast<const uv_handle_t*>(&inspector->client);
689
  return !inspector->shutting_down && !uv_is_closing(client);
690
}