GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage/nodes/benchmark/out/../src/inspector_socket.cc Lines: 341 377 90.5 %
Date: 2019-01-07 12:15:22 Branches: 116 171 67.8 %

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

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


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

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

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

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

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

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

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

70
           || 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
101
ProtocolHandler::ProtocolHandler(InspectorSocket* inspector,
604
                                 TcpHolder::Pointer tcp)
605
101
                                 : inspector_(inspector), tcp_(std::move(tcp)) {
606
101
  CHECK_NOT_NULL(tcp_);
607
101
  tcp_->SetHandler(this);
608
101
}
609
610
1564
int ProtocolHandler::WriteRaw(const std::vector<char>& buffer,
611
                              uv_write_cb write_cb) {
612
1564
  return tcp_->WriteRaw(buffer, write_cb);
613
}
614
615
199
InspectorSocket::Delegate* ProtocolHandler::delegate() {
616
199
  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
69
TcpHolder::TcpHolder(InspectorSocket::DelegatePointer delegate)
642
                     : tcp_(),
643
69
                       delegate_(std::move(delegate)),
644
138
                       handler_(nullptr) { }
645
646
// static
647
69
TcpHolder::Pointer TcpHolder::Accept(
648
    uv_stream_t* server,
649
    InspectorSocket::DelegatePointer delegate) {
650
69
  TcpHolder* result = new TcpHolder(std::move(delegate));
651
69
  uv_stream_t* tcp = reinterpret_cast<uv_stream_t*>(&result->tcp_);
652
69
  int err = uv_tcp_init(server->loop, &result->tcp_);
653
69
  if (err == 0) {
654
69
    err = uv_accept(server, tcp);
655
  }
656
69
  if (err == 0) {
657
69
    err = uv_read_start(tcp, allocate_buffer, OnDataReceivedCb);
658
  }
659
69
  if (err == 0) {
660
69
    return TcpHolder::Pointer(result);
661
  } else {
662
    delete result;
663
    return nullptr;
664
  }
665
}
666
667
101
void TcpHolder::SetHandler(ProtocolHandler* handler) {
668
101
  handler_ = handler;
669
101
}
670
671
1564
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
1564
  WriteRequest* wr = new WriteRequest(handler_, buffer);
680
1564
  uv_stream_t* stream = reinterpret_cast<uv_stream_t*>(&tcp_);
681
1564
  int err = uv_write(&wr->req, stream, &wr->buf, 1, write_cb);
682
1564
  if (err < 0)
683
    delete wr;
684
1564
  return err < 0;
685
}
686
687
199
InspectorSocket::Delegate* TcpHolder::delegate() {
688
199
  return delegate_.get();
689
}
690
691
// static
692
69
void TcpHolder::OnClosed(uv_handle_t* handle) {
693
69
  delete From(handle);
694
69
}
695
696
334
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
334
  TcpHolder* holder = From(tcp);
707
334
  holder->ReclaimUvBuf(buf, nread);
708

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