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-09-26 22:31:05 Branches: 98 171 57.3 %

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

43
  if (bracket == std::string::npos || last_colon_pos > bracket)
160
43
    return host.substr(0, last_colon_pos);
161
  return host;
162
}
163
164
43
static bool IsIPAddress(const std::string& host) {
165


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

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

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

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

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

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

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

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

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