GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/inspector_socket.cc Lines: 322 377 85.4 %
Date: 2019-07-27 22:37:30 Branches: 98 171 57.3 %

Line Branch Exec Source
1
#include "inspector_socket.h"
2
3
#define NODE_EXPERIMENTAL_HTTP
4
#include "http_parser_adaptor.h"
5
6
#include "util-inl.h"
7
8
#define NODE_WANT_INTERNALS 1
9
#include "base64.h"
10
11
#include "openssl/sha.h"  // Sha-1 hash
12
13
#include <cstring>
14
#include <map>
15
16
#define ACCEPT_KEY_LENGTH base64_encoded_size(20)
17
18
#define DUMP_READS 0
19
#define DUMP_WRITES 0
20
21
namespace node {
22
namespace inspector {
23
24
class TcpHolder {
25
 public:
26
  static void DisconnectAndDispose(TcpHolder* holder);
27
  using Pointer = DeleteFnPtr<TcpHolder, DisconnectAndDispose>;
28
29
  static Pointer Accept(uv_stream_t* server,
30
                        InspectorSocket::DelegatePointer delegate);
31
  void SetHandler(ProtocolHandler* handler);
32
  int WriteRaw(const std::vector<char>& buffer, uv_write_cb write_cb);
33
  uv_tcp_t* tcp() {
34
    return &tcp_;
35
  }
36
  InspectorSocket::Delegate* delegate();
37
38
 private:
39
222
  static TcpHolder* From(void* handle) {
40
    return node::ContainerOf(&TcpHolder::tcp_,
41
222
                             reinterpret_cast<uv_tcp_t*>(handle));
42
  }
43
  static void OnClosed(uv_handle_t* handle);
44
  static void OnDataReceivedCb(uv_stream_t* stream, ssize_t nread,
45
                               const uv_buf_t* buf);
46
  explicit TcpHolder(InspectorSocket::DelegatePointer delegate);
47
46
  ~TcpHolder() = default;
48
  void ReclaimUvBuf(const uv_buf_t* buf, ssize_t read);
49
50
  uv_tcp_t tcp_;
51
  const InspectorSocket::DelegatePointer delegate_;
52
  ProtocolHandler* handler_;
53
  std::vector<char> buffer;
54
};
55
56
57
class ProtocolHandler {
58
 public:
59
  ProtocolHandler(InspectorSocket* inspector, TcpHolder::Pointer tcp);
60
61
  virtual void AcceptUpgrade(const std::string& accept_key) = 0;
62
  virtual void OnData(std::vector<char>* data) = 0;
63
  virtual void OnEof() = 0;
64
  virtual void Write(const std::vector<char> data) = 0;
65
  virtual void CancelHandshake() = 0;
66
67
  std::string GetHost() const;
68
69
3
  InspectorSocket* inspector() {
70
3
    return inspector_;
71
  }
72
  virtual void Shutdown() = 0;
73
74
 protected:
75
63
  virtual ~ProtocolHandler() = default;
76
  int WriteRaw(const std::vector<char>& buffer, uv_write_cb write_cb);
77
  InspectorSocket::Delegate* delegate();
78
79
  InspectorSocket* const inspector_;
80
  TcpHolder::Pointer tcp_;
81
};
82
83
namespace {
84
85
#if DUMP_READS || DUMP_WRITES
86
static void dump_hex(const char* buf, size_t len) {
87
  const char* ptr = buf;
88
  const char* end = ptr + len;
89
  const char* cptr;
90
  char c;
91
  int i;
92
93
  while (ptr < end) {
94
    cptr = ptr;
95
    for (i = 0; i < 16 && ptr < end; i++) {
96
      printf("%2.2X  ", static_cast<unsigned char>(*(ptr++)));
97
    }
98
    for (i = 72 - (i * 4); i > 0; i--) {
99
      printf(" ");
100
    }
101
    for (i = 0; i < 16 && cptr < end; i++) {
102
      c = *(cptr++);
103
      printf("%c", (c > 0x19) ? c : '.');
104
    }
105
    printf("\n");
106
  }
107
  printf("\n\n");
108
}
109
#endif
110
111
898
class WriteRequest {
112
 public:
113
898
  WriteRequest(ProtocolHandler* handler, const std::vector<char>& buffer)
114
      : handler(handler)
115
      , storage(buffer)
116
      , req(uv_write_t())
117
898
      , buf(uv_buf_init(storage.data(), storage.size())) {}
118
119
901
  static WriteRequest* from_write_req(uv_write_t* req) {
120
901
    return node::ContainerOf(&WriteRequest::req, req);
121
  }
122
123
897
  static void Cleanup(uv_write_t* req, int status) {
124
897
    delete WriteRequest::from_write_req(req);
125
897
  }
126
127
  ProtocolHandler* const handler;
128
  std::vector<char> storage;
129
  uv_write_t req;
130
  uv_buf_t buf;
131
};
132
133
176
void allocate_buffer(uv_handle_t* stream, size_t len, uv_buf_t* buf) {
134
176
  *buf = uv_buf_init(new char[len], len);
135
176
}
136
137
122
static void remove_from_beginning(std::vector<char>* buffer, size_t count) {
138
122
  buffer->erase(buffer->begin(), buffer->begin() + count);
139
122
}
140
141
static const char CLOSE_FRAME[] = {'\x88', '\x00'};
142
143
enum ws_decode_result {
144
  FRAME_OK, FRAME_INCOMPLETE, FRAME_CLOSE, FRAME_ERROR
145
};
146
147
17
static void generate_accept_string(const std::string& client_key,
148
                                   char (*buffer)[ACCEPT_KEY_LENGTH]) {
149
  // Magic string from websockets spec.
150
  static const char ws_magic[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
151
17
  std::string input(client_key + ws_magic);
152
  char hash[SHA_DIGEST_LENGTH];
153
17
  SHA1(reinterpret_cast<const unsigned char*>(&input[0]), input.size(),
154
34
       reinterpret_cast<unsigned char*>(hash));
155
17
  node::base64_encode(hash, sizeof(hash), *buffer, sizeof(*buffer));
156
17
}
157
158
43
static std::string TrimPort(const std::string& host) {
159
43
  size_t last_colon_pos = host.rfind(':');
160
43
  if (last_colon_pos == std::string::npos)
161
    return host;
162
43
  size_t bracket = host.rfind(']');
163

43
  if (bracket == std::string::npos || last_colon_pos > bracket)
164
43
    return host.substr(0, last_colon_pos);
165
  return host;
166
}
167
168
43
static bool IsIPAddress(const std::string& host) {
169


43
  if (host.length() >= 4 && host.front() == '[' && host.back() == ']')
170
    return true;
171
43
  int quads = 0;
172
70
  for (char c : host) {
173
67
    if (c == '.')
174
9
      quads++;
175
58
    else if (!isdigit(c))
176
40
      return false;
177
  }
178
3
  return quads == 3;
179
}
180
181
// Constants for hybi-10 frame format.
182
183
typedef int OpCode;
184
185
const OpCode kOpCodeContinuation = 0x0;
186
const OpCode kOpCodeText = 0x1;
187
const OpCode kOpCodeBinary = 0x2;
188
const OpCode kOpCodeClose = 0x8;
189
const OpCode kOpCodePing = 0x9;
190
const OpCode kOpCodePong = 0xA;
191
192
const unsigned char kFinalBit = 0x80;
193
const unsigned char kReserved1Bit = 0x40;
194
const unsigned char kReserved2Bit = 0x20;
195
const unsigned char kReserved3Bit = 0x10;
196
const unsigned char kOpCodeMask = 0xF;
197
const unsigned char kMaskBit = 0x80;
198
const unsigned char kPayloadLengthMask = 0x7F;
199
200
const size_t kMaxSingleBytePayloadLength = 125;
201
const size_t kTwoBytePayloadLengthField = 126;
202
const size_t kEightBytePayloadLengthField = 127;
203
const size_t kMaskingKeyWidthInBytes = 4;
204
205
831
static std::vector<char> encode_frame_hybi17(const std::vector<char>& message) {
206
831
  std::vector<char> frame;
207
831
  OpCode op_code = kOpCodeText;
208
831
  frame.push_back(kFinalBit | op_code);
209
831
  const size_t data_length = message.size();
210
831
  if (data_length <= kMaxSingleBytePayloadLength) {
211
150
    frame.push_back(static_cast<char>(data_length));
212
681
  } else if (data_length <= 0xFFFF) {
213
681
    frame.push_back(kTwoBytePayloadLengthField);
214
681
    frame.push_back((data_length & 0xFF00) >> 8);
215
681
    frame.push_back(data_length & 0xFF);
216
  } else {
217
    frame.push_back(kEightBytePayloadLengthField);
218
    char extended_payload_length[8];
219
    size_t remaining = data_length;
220
    // Fill the length into extended_payload_length in the network byte order.
221
    for (int i = 0; i < 8; ++i) {
222
      extended_payload_length[7 - i] = remaining & 0xFF;
223
      remaining >>= 8;
224
    }
225
    frame.insert(frame.end(), extended_payload_length,
226
                 extended_payload_length + 8);
227
    CHECK_EQ(0, remaining);
228
  }
229
831
  frame.insert(frame.end(), message.begin(), message.end());
230
831
  return frame;
231
}
232
233
123
static ws_decode_result decode_frame_hybi17(const std::vector<char>& buffer,
234
                                            bool client_frame,
235
                                            int* bytes_consumed,
236
                                            std::vector<char>* output,
237
                                            bool* compressed) {
238
123
  *bytes_consumed = 0;
239
123
  if (buffer.size() < 2)
240
    return FRAME_INCOMPLETE;
241
242
123
  auto it = buffer.begin();
243
244
123
  unsigned char first_byte = *it++;
245
123
  unsigned char second_byte = *it++;
246
247
123
  bool final = (first_byte & kFinalBit) != 0;
248
123
  bool reserved1 = (first_byte & kReserved1Bit) != 0;
249
123
  bool reserved2 = (first_byte & kReserved2Bit) != 0;
250
123
  bool reserved3 = (first_byte & kReserved3Bit) != 0;
251
123
  int op_code = first_byte & kOpCodeMask;
252
123
  bool masked = (second_byte & kMaskBit) != 0;
253
123
  *compressed = reserved1;
254

123
  if (!final || reserved2 || reserved3)
255
    return FRAME_ERROR;  // Only compression extension is supported.
256
257
123
  bool closed = false;
258
123
  switch (op_code) {
259
    case kOpCodeClose:
260
1
      closed = true;
261
1
      break;
262
    case kOpCodeText:
263
122
      break;
264
    case kOpCodeBinary:        // We don't support binary frames yet.
265
    case kOpCodeContinuation:  // We don't support binary frames yet.
266
    case kOpCodePing:          // We don't support binary frames yet.
267
    case kOpCodePong:          // We don't support binary frames yet.
268
    default:
269
      return FRAME_ERROR;
270
  }
271
272
  // In Hybi-17 spec client MUST mask its frame.
273

123
  if (client_frame && !masked) {
274
1
    return FRAME_ERROR;
275
  }
276
277
122
  uint64_t payload_length64 = second_byte & kPayloadLengthMask;
278
122
  if (payload_length64 > kMaxSingleBytePayloadLength) {
279
    int extended_payload_length_size;
280
18
    if (payload_length64 == kTwoBytePayloadLengthField) {
281
18
      extended_payload_length_size = 2;
282
    } else if (payload_length64 == kEightBytePayloadLengthField) {
283
      extended_payload_length_size = 8;
284
    } else {
285
      return FRAME_ERROR;
286
    }
287
18
    if ((buffer.end() - it) < extended_payload_length_size)
288
      return FRAME_INCOMPLETE;
289
18
    payload_length64 = 0;
290
54
    for (int i = 0; i < extended_payload_length_size; ++i) {
291
36
      payload_length64 <<= 8;
292
36
      payload_length64 |= static_cast<unsigned char>(*it++);
293
    }
294
  }
295
296
  static const uint64_t max_payload_length = 0x7FFFFFFFFFFFFFFFull;
297
  static const size_t max_length = SIZE_MAX;
298

122
  if (payload_length64 > max_payload_length ||
299
      payload_length64 > max_length - kMaskingKeyWidthInBytes) {
300
    // WebSocket frame length too large.
301
    return FRAME_ERROR;
302
  }
303
122
  size_t payload_length = static_cast<size_t>(payload_length64);
304
305
122
  if (buffer.size() - kMaskingKeyWidthInBytes < payload_length)
306
    return FRAME_INCOMPLETE;
307
308
122
  std::vector<char>::const_iterator masking_key = it;
309
122
  std::vector<char>::const_iterator payload = it + kMaskingKeyWidthInBytes;
310
10124
  for (size_t i = 0; i < payload_length; ++i)  // Unmask the payload.
311
    output->insert(output->end(),
312
10002
                   payload[i] ^ masking_key[i % kMaskingKeyWidthInBytes]);
313
314
122
  size_t pos = it + kMaskingKeyWidthInBytes + payload_length - buffer.begin();
315
122
  *bytes_consumed = pos;
316
122
  return closed ? FRAME_CLOSE : FRAME_OK;
317
}
318
319
// WS protocol
320
34
class WsHandler : public ProtocolHandler {
321
 public:
322
17
  WsHandler(InspectorSocket* inspector, TcpHolder::Pointer tcp)
323
17
            : ProtocolHandler(inspector, std::move(tcp)),
324
              OnCloseSent(&WsHandler::WaitForCloseReply),
325
              OnCloseRecieved(&WsHandler::CloseFrameReceived),
326
17
              dispose_(false) { }
327
328
  void AcceptUpgrade(const std::string& accept_key) override { }
329
  void CancelHandshake() override {}
330
331
17
  void OnEof() override {
332
17
    tcp_.reset();
333
17
    if (dispose_)
334
1
      delete this;
335
17
  }
336
337
91
  void OnData(std::vector<char>* data) override {
338
    // 1. Parse.
339
91
    int processed = 0;
340
123
    do {
341
123
      processed = ParseWsFrames(*data);
342
      // 2. Fix the data size & length
343
123
      if (processed > 0) {
344
122
        remove_from_beginning(data, processed);
345
      }
346

123
    } while (processed > 0 && !data->empty());
347
91
  }
348
349
831
  void Write(const std::vector<char> data) override {
350
831
    std::vector<char> output = encode_frame_hybi17(data);
351
831
    WriteRaw(output, WriteRequest::Cleanup);
352
831
  }
353
354
 protected:
355
17
  void Shutdown() override {
356
17
    if (tcp_) {
357
1
      dispose_ = true;
358
1
      SendClose();
359
    } else {
360
16
      delete this;
361
    }
362
17
  }
363
364
 private:
365
  using Callback = void (WsHandler::*)();
366
367
1
  static void OnCloseFrameWritten(uv_write_t* req, int status) {
368
1
    WriteRequest* wr = WriteRequest::from_write_req(req);
369
1
    WsHandler* handler = static_cast<WsHandler*>(wr->handler);
370
1
    delete wr;
371
1
    Callback cb = handler->OnCloseSent;
372
1
    (handler->*cb)();
373
1
  }
374
375
1
  void WaitForCloseReply() {
376
1
    OnCloseRecieved = &WsHandler::OnEof;
377
1
  }
378
379
1
  void SendClose() {
380
    WriteRaw(std::vector<char>(CLOSE_FRAME, CLOSE_FRAME + sizeof(CLOSE_FRAME)),
381
1
             OnCloseFrameWritten);
382
1
  }
383
384
  void CloseFrameReceived() {
385
    OnCloseSent = &WsHandler::OnEof;
386
    SendClose();
387
  }
388
389
123
  int ParseWsFrames(const std::vector<char>& buffer) {
390
123
    int bytes_consumed = 0;
391
123
    std::vector<char> output;
392
123
    bool compressed = false;
393
394
    ws_decode_result r =  decode_frame_hybi17(buffer,
395
                                              true /* client_frame */,
396
                                              &bytes_consumed, &output,
397
123
                                              &compressed);
398
    // Compressed frame means client is ignoring the headers and misbehaves
399

123
    if (compressed || r == FRAME_ERROR) {
400
1
      OnEof();
401
1
      bytes_consumed = 0;
402
122
    } else if (r == FRAME_CLOSE) {
403
      (this->*OnCloseRecieved)();
404
      bytes_consumed = 0;
405
122
    } else if (r == FRAME_OK) {
406
122
      delegate()->OnWsFrame(output);
407
    }
408
123
    return bytes_consumed;
409
  }
410
411
412
  Callback OnCloseSent;
413
  Callback OnCloseRecieved;
414
  bool dispose_;
415
};
416
417
// HTTP protocol
418
43
class HttpEvent {
419
 public:
420
43
  HttpEvent(const std::string& path, bool upgrade, bool isGET,
421
            const std::string& ws_key, const std::string& host)
422
            : path(path), upgrade(upgrade), isGET(isGET), ws_key(ws_key),
423
43
              host(host) { }
424
425
  std::string path;
426
  bool upgrade;
427
  bool isGET;
428
  std::string ws_key;
429
  std::string host;
430
};
431
432
92
class HttpHandler : public ProtocolHandler {
433
 public:
434
46
  explicit HttpHandler(InspectorSocket* inspector, TcpHolder::Pointer tcp)
435
46
                       : ProtocolHandler(inspector, std::move(tcp)),
436
46
                         parsing_value_(false) {
437
46
    llhttp_init(&parser_, HTTP_REQUEST, &parser_settings);
438
46
    llhttp_settings_init(&parser_settings);
439
46
    parser_settings.on_header_field = OnHeaderField;
440
46
    parser_settings.on_header_value = OnHeaderValue;
441
46
    parser_settings.on_message_complete = OnMessageComplete;
442
46
    parser_settings.on_url = OnPath;
443
46
  }
444
445
17
  void AcceptUpgrade(const std::string& accept_key) override {
446
    char accept_string[ACCEPT_KEY_LENGTH];
447
17
    generate_accept_string(accept_key, &accept_string);
448
    const char accept_ws_prefix[] = "HTTP/1.1 101 Switching Protocols\r\n"
449
                                    "Upgrade: websocket\r\n"
450
                                    "Connection: Upgrade\r\n"
451
17
                                    "Sec-WebSocket-Accept: ";
452
17
    const char accept_ws_suffix[] = "\r\n\r\n";
453
    std::vector<char> reply(accept_ws_prefix,
454
17
                            accept_ws_prefix + sizeof(accept_ws_prefix) - 1);
455
    reply.insert(reply.end(), accept_string,
456
17
                 accept_string + sizeof(accept_string));
457
    reply.insert(reply.end(), accept_ws_suffix,
458
17
                 accept_ws_suffix + sizeof(accept_ws_suffix) - 1);
459
17
    if (WriteRaw(reply, WriteRequest::Cleanup) >= 0) {
460
17
      inspector_->SwitchProtocol(new WsHandler(inspector_, std::move(tcp_)));
461
    } else {
462
      tcp_.reset();
463
17
    }
464
17
  }
465
466
3
  void CancelHandshake() override {
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
3
        "WebSockets request was expected\r\n";
471
    WriteRaw(std::vector<char>(HANDSHAKE_FAILED_RESPONSE,
472
3
             HANDSHAKE_FAILED_RESPONSE + sizeof(HANDSHAKE_FAILED_RESPONSE) - 1),
473
6
             ThenCloseAndReportFailure);
474
3
  }
475
476
477
26
  void OnEof() override {
478
26
    tcp_.reset();
479
26
  }
480
481
43
  void OnData(std::vector<char>* data) override {
482
    parser_errno_t err;
483
43
    err = llhttp_execute(&parser_, data->data(), data->size());
484
485
43
    if (err == HPE_PAUSED_UPGRADE) {
486
17
      err = HPE_OK;
487
17
      llhttp_resume_after_upgrade(&parser_);
488
    }
489
43
    data->clear();
490
43
    if (err != HPE_OK) {
491
      CancelHandshake();
492
    }
493
    // Event handling may delete *this
494
43
    std::vector<HttpEvent> events;
495
43
    std::swap(events, events_);
496
86
    for (const HttpEvent& event : events) {
497

43
      if (!IsAllowedHost(event.host) || !event.isGET) {
498
        CancelHandshake();
499
        return;
500
43
      } else if (!event.upgrade) {
501
26
        delegate()->OnHttpGet(event.host, event.path);
502
17
      } else if (event.ws_key.empty()) {
503
        CancelHandshake();
504
        return;
505
      } else {
506
17
        delegate()->OnSocketUpgrade(event.host, event.path, event.ws_key);
507
      }
508
43
    }
509
  }
510
511
46
  void Write(const std::vector<char> data) override {
512
46
    WriteRaw(data, WriteRequest::Cleanup);
513
46
  }
514
515
 protected:
516
46
  void Shutdown() override {
517
46
    delete this;
518
46
  }
519
520
 private:
521
3
  static void ThenCloseAndReportFailure(uv_write_t* req, int status) {
522
3
    ProtocolHandler* handler = WriteRequest::from_write_req(req)->handler;
523
3
    WriteRequest::Cleanup(req, status);
524
3
    handler->inspector()->SwitchProtocol(nullptr);
525
3
  }
526
527
137
  static int OnHeaderValue(parser_t* parser, const char* at, size_t length) {
528
137
    HttpHandler* handler = From(parser);
529
137
    handler->parsing_value_ = true;
530
137
    handler->headers_[handler->current_header_].append(at, length);
531
137
    return 0;
532
  }
533
534
137
  static int OnHeaderField(parser_t* parser, const char* at, size_t length) {
535
137
    HttpHandler* handler = From(parser);
536
137
    if (handler->parsing_value_) {
537
94
      handler->parsing_value_ = false;
538
94
      handler->current_header_.clear();
539
    }
540
137
    handler->current_header_.append(at, length);
541
137
    return 0;
542
  }
543
544
43
  static int OnPath(parser_t* parser, const char* at, size_t length) {
545
43
    HttpHandler* handler = From(parser);
546
43
    handler->path_.append(at, length);
547
43
    return 0;
548
  }
549
550
360
  static HttpHandler* From(parser_t* parser) {
551
360
    return node::ContainerOf(&HttpHandler::parser_, parser);
552
  }
553
554
43
  static int OnMessageComplete(parser_t* parser) {
555
    // Event needs to be fired after the parser is done.
556
43
    HttpHandler* handler = From(parser);
557
    handler->events_.emplace_back(handler->path_,
558
                                  parser->upgrade,
559
43
                                  parser->method == HTTP_GET,
560
                                  handler->HeaderValue("Sec-WebSocket-Key"),
561
86
                                  handler->HeaderValue("Host"));
562
43
    handler->path_ = "";
563
43
    handler->parsing_value_ = false;
564
43
    handler->headers_.clear();
565
43
    handler->current_header_ = "";
566
43
    return 0;
567
  }
568
569
86
  std::string HeaderValue(const std::string& header) const {
570
86
    bool header_found = false;
571
86
    std::string value;
572
360
    for (const auto& header_value : headers_) {
573
274
      if (node::StringEqualNoCaseN(header_value.first.data(), header.data(),
574
274
                                   header.length())) {
575
60
        if (header_found)
576
          return "";
577
60
        value = header_value.second;
578
60
        header_found = true;
579
      }
580
    }
581
86
    return value;
582
  }
583
584
43
  bool IsAllowedHost(const std::string& host_with_port) const {
585
43
    std::string host = TrimPort(host_with_port);
586
86
    return host.empty() || IsIPAddress(host)
587
40
           || node::StringEqualNoCase(host.data(), "localhost")
588

43
           || node::StringEqualNoCase(host.data(), "localhost6");
589
  }
590
591
  bool parsing_value_;
592
  parser_t parser_;
593
  parser_settings_t parser_settings;
594
  std::vector<HttpEvent> events_;
595
  std::string current_header_;
596
  std::map<std::string, std::string> headers_;
597
  std::string path_;
598
};
599
600
}  // namespace
601
602
// Any protocol
603
63
ProtocolHandler::ProtocolHandler(InspectorSocket* inspector,
604
                                 TcpHolder::Pointer tcp)
605
63
                                 : inspector_(inspector), tcp_(std::move(tcp)) {
606
63
  CHECK_NOT_NULL(tcp_);
607
63
  tcp_->SetHandler(this);
608
63
}
609
610
898
int ProtocolHandler::WriteRaw(const std::vector<char>& buffer,
611
                              uv_write_cb write_cb) {
612
898
  return tcp_->WriteRaw(buffer, write_cb);
613
}
614
615
165
InspectorSocket::Delegate* ProtocolHandler::delegate() {
616
165
  return tcp_->delegate();
617
}
618
619
std::string ProtocolHandler::GetHost() const {
620
  char ip[INET6_ADDRSTRLEN];
621
  sockaddr_storage addr;
622
  int len = sizeof(addr);
623
  int err = uv_tcp_getsockname(tcp_->tcp(),
624
                               reinterpret_cast<struct sockaddr*>(&addr),
625
                               &len);
626
  if (err != 0)
627
    return "";
628
  if (addr.ss_family == AF_INET6) {
629
    const sockaddr_in6* v6 = reinterpret_cast<const sockaddr_in6*>(&addr);
630
    err = uv_ip6_name(v6, ip, sizeof(ip));
631
  } else {
632
    const sockaddr_in* v4 = reinterpret_cast<const sockaddr_in*>(&addr);
633
    err = uv_ip4_name(v4, ip, sizeof(ip));
634
  }
635
  if (err != 0)
636
    return "";
637
  return ip;
638
}
639
640
// RAII uv_tcp_t wrapper
641
46
TcpHolder::TcpHolder(InspectorSocket::DelegatePointer delegate)
642
                     : tcp_(),
643
46
                       delegate_(std::move(delegate)),
644
92
                       handler_(nullptr) { }
645
646
// static
647
46
TcpHolder::Pointer TcpHolder::Accept(
648
    uv_stream_t* server,
649
    InspectorSocket::DelegatePointer delegate) {
650
46
  TcpHolder* result = new TcpHolder(std::move(delegate));
651
46
  uv_stream_t* tcp = reinterpret_cast<uv_stream_t*>(&result->tcp_);
652
46
  int err = uv_tcp_init(server->loop, &result->tcp_);
653
46
  if (err == 0) {
654
46
    err = uv_accept(server, tcp);
655
  }
656
46
  if (err == 0) {
657
46
    err = uv_read_start(tcp, allocate_buffer, OnDataReceivedCb);
658
  }
659
46
  if (err == 0) {
660
46
    return TcpHolder::Pointer(result);
661
  } else {
662
    delete result;
663
    return nullptr;
664
  }
665
}
666
667
63
void TcpHolder::SetHandler(ProtocolHandler* handler) {
668
63
  handler_ = handler;
669
63
}
670
671
898
int TcpHolder::WriteRaw(const std::vector<char>& buffer, uv_write_cb write_cb) {
672
#if DUMP_WRITES
673
  printf("%s (%ld bytes):\n", __FUNCTION__, buffer.size());
674
  dump_hex(buffer.data(), buffer.size());
675
  printf("\n");
676
#endif
677
678
  // Freed in write_request_cleanup
679
898
  WriteRequest* wr = new WriteRequest(handler_, buffer);
680
898
  uv_stream_t* stream = reinterpret_cast<uv_stream_t*>(&tcp_);
681
898
  int err = uv_write(&wr->req, stream, &wr->buf, 1, write_cb);
682
898
  if (err < 0)
683
    delete wr;
684
898
  return err < 0;
685
}
686
687
165
InspectorSocket::Delegate* TcpHolder::delegate() {
688
165
  return delegate_.get();
689
}
690
691
// static
692
46
void TcpHolder::OnClosed(uv_handle_t* handle) {
693
46
  delete From(handle);
694
46
}
695
696
176
void TcpHolder::OnDataReceivedCb(uv_stream_t* tcp, ssize_t nread,
697
                                 const uv_buf_t* buf) {
698
#if DUMP_READS
699
  if (nread >= 0) {
700
    printf("%s (%ld bytes)\n", __FUNCTION__, nread);
701
    dump_hex(buf->base, nread);
702
  } else {
703
    printf("[%s:%d] %s\n", __FUNCTION__, __LINE__, uv_err_name(nread));
704
  }
705
#endif
706
176
  TcpHolder* holder = From(tcp);
707
176
  holder->ReclaimUvBuf(buf, nread);
708

176
  if (nread < 0 || nread == UV_EOF) {
709
42
    holder->handler_->OnEof();
710
  } else {
711
134
    holder->handler_->OnData(&holder->buffer);
712
  }
713
176
}
714
715
// static
716
46
void TcpHolder::DisconnectAndDispose(TcpHolder* holder) {
717
46
  uv_handle_t* handle = reinterpret_cast<uv_handle_t*>(&holder->tcp_);
718
46
  uv_close(handle, OnClosed);
719
46
}
720
721
176
void TcpHolder::ReclaimUvBuf(const uv_buf_t* buf, ssize_t read) {
722
176
  if (read > 0) {
723
134
    buffer.insert(buffer.end(), buf->base, buf->base + read);
724
  }
725
176
  delete[] buf->base;
726
176
}
727
728
InspectorSocket::~InspectorSocket() = default;
729
730
// static
731
63
void InspectorSocket::Shutdown(ProtocolHandler* handler) {
732
63
  handler->Shutdown();
733
63
}
734
735
// static
736
46
InspectorSocket::Pointer InspectorSocket::Accept(uv_stream_t* server,
737
                                                 DelegatePointer delegate) {
738
46
  auto tcp = TcpHolder::Accept(server, std::move(delegate));
739
46
  if (tcp) {
740
46
    InspectorSocket* inspector = new InspectorSocket();
741
46
    inspector->SwitchProtocol(new HttpHandler(inspector, std::move(tcp)));
742
46
    return InspectorSocket::Pointer(inspector);
743
  } else {
744
    return InspectorSocket::Pointer(nullptr);
745
46
  }
746
}
747
748
17
void InspectorSocket::AcceptUpgrade(const std::string& ws_key) {
749
17
  protocol_handler_->AcceptUpgrade(ws_key);
750
17
}
751
752
3
void InspectorSocket::CancelHandshake() {
753
3
  protocol_handler_->CancelHandshake();
754
3
}
755
756
std::string InspectorSocket::GetHost() {
757
  return protocol_handler_->GetHost();
758
}
759
760
66
void InspectorSocket::SwitchProtocol(ProtocolHandler* handler) {
761
66
  protocol_handler_.reset(std::move(handler));
762
66
}
763
764
877
void InspectorSocket::Write(const char* data, size_t len) {
765
877
  protocol_handler_->Write(std::vector<char>(data, data + len));
766
877
}
767
768
}  // namespace inspector
769
}  // namespace node