GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: inspector_socket.cc Lines: 348 384 90.6 %
Date: 2022-11-05 03:21:31 Branches: 121 169 71.6 %

Line Branch Exec Source
1
#include "inspector_socket.h"
2
#include "llhttp.h"
3
4
#include "base64-inl.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
598
  static TcpHolder* From(void* handle) {
36
598
    return node::ContainerOf(&TcpHolder::tcp_,
37
598
                             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
97
  ~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
31
  InspectorSocket* inspector() {
66
31
    return inspector_;
67
  }
68
  virtual void Shutdown() = 0;
69
70
 protected:
71
266
  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
class WriteRequest {
108
 public:
109
2381
  WriteRequest(ProtocolHandler* handler, const std::vector<char>& buffer)
110
2381
      : handler(handler)
111
      , storage(buffer)
112
      , req(uv_write_t())
113
2381
      , buf(uv_buf_init(storage.data(), storage.size())) {}
114
115
2412
  static WriteRequest* from_write_req(uv_write_t* req) {
116
2412
    return node::ContainerOf(&WriteRequest::req, req);
117
  }
118
119
2372
  static void Cleanup(uv_write_t* req, int status) {
120
2372
    delete WriteRequest::from_write_req(req);
121
2372
  }
122
123
  ProtocolHandler* const handler;
124
  std::vector<char> storage;
125
  uv_write_t req;
126
  uv_buf_t buf;
127
};
128
129
501
void allocate_buffer(uv_handle_t* stream, size_t len, uv_buf_t* buf) {
130
501
  *buf = uv_buf_init(new char[len], len);
131
501
}
132
133
147
static void remove_from_beginning(std::vector<char>* buffer, size_t count) {
134
147
  buffer->erase(buffer->begin(), buffer->begin() + count);
135
147
}
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
36
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
72
  std::string input(client_key + ws_magic);
148
  char hash[SHA_DIGEST_LENGTH];
149
36
  USE(SHA1(reinterpret_cast<const unsigned char*>(&input[0]), input.size(),
150
       reinterpret_cast<unsigned char*>(hash)));
151
36
  node::base64_encode(hash, sizeof(hash), *buffer, sizeof(*buffer));
152
36
}
153
154
99
static std::string TrimPort(const std::string& host) {
155
99
  size_t last_colon_pos = host.rfind(':');
156
99
  if (last_colon_pos == std::string::npos)
157
    return host;
158
99
  size_t bracket = host.rfind(']');
159

99
  if (bracket == std::string::npos || last_colon_pos > bracket)
160
99
    return host.substr(0, last_colon_pos);
161
  return host;
162
}
163
164
99
static bool IsIPAddress(const std::string& host) {
165
  // TODO(tniessen): add CVEs to the following bullet points
166
  // To avoid DNS rebinding attacks, we are aware of the following requirements:
167
  // * the host name must be an IP address,
168
  // * the IP address must be routable, and
169
  // * the IP address must be formatted unambiguously.
170
171
  // The logic below assumes that the string is null-terminated, so ensure that
172
  // we did not somehow end up with null characters within the string.
173
99
  if (host.find('\0') != std::string::npos) return false;
174
175
  // All IPv6 addresses must be enclosed in square brackets, and anything
176
  // enclosed in square brackets must be an IPv6 address.
177


99
  if (host.length() >= 4 && host.front() == '[' && host.back() == ']') {
178
    // INET6_ADDRSTRLEN is the maximum length of the dual format (including the
179
    // terminating null character), which is the longest possible representation
180
    // of an IPv6 address: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd
181
4
    if (host.length() - 2 >= INET6_ADDRSTRLEN) return false;
182
183
    // Annoyingly, libuv's implementation of inet_pton() deviates from other
184
    // implementations of the function in that it allows '%' in IPv6 addresses.
185
4
    if (host.find('%') != std::string::npos) return false;
186
187
    // Parse the IPv6 address to ensure it is syntactically valid.
188
    char ipv6_str[INET6_ADDRSTRLEN];
189
4
    std::copy(host.begin() + 1, host.end() - 1, ipv6_str);
190
4
    ipv6_str[host.length()] = '\0';
191
    unsigned char ipv6[sizeof(struct in6_addr)];
192
4
    if (uv_inet_pton(AF_INET6, ipv6_str, ipv6) != 0) return false;
193
194
    // The only non-routable IPv6 address is ::/128. It should not be necessary
195
    // to explicitly reject it because it will still be enclosed in square
196
    // brackets and not even macOS should make DNS requests in that case, but
197
    // history has taught us that we cannot be careful enough.
198
    // Note that RFC 4291 defines both "IPv4-Compatible IPv6 Addresses" and
199
    // "IPv4-Mapped IPv6 Addresses", which means that there are IPv6 addresses
200
    // (other than ::/128) that represent non-routable IPv4 addresses. However,
201
    // this translation assumes that the host is interpreted as an IPv6 address
202
    // in the first place, at which point DNS rebinding should not be an issue.
203
    if (std::all_of(ipv6, ipv6 + sizeof(ipv6), [](auto b) { return b == 0; })) {
204
      return false;
205
    }
206
207
    // It is a syntactically valid and routable IPv6 address enclosed in square
208
    // brackets. No client should be able to misinterpret this.
209
    return true;
210
  }
211
212
  // Anything not enclosed in square brackets must be an IPv4 address. It is
213
  // important here that inet_pton() accepts only the so-called dotted-decimal
214
  // notation, which is a strict subset of the so-called numbers-and-dots
215
  // notation that is allowed by inet_aton() and inet_addr(). This subset does
216
  // not allow hexadecimal or octal number formats.
217
  unsigned char ipv4[sizeof(struct in_addr)];
218
95
  if (uv_inet_pton(AF_INET, host.c_str(), ipv4) != 0) return false;
219
220
  // The only strictly non-routable IPv4 address is 0.0.0.0, and macOS will make
221
  // DNS requests for this IP address, so we need to explicitly reject it. In
222
  // fact, we can safely reject all of 0.0.0.0/8 (see Section 3.2 of RFC 791 and
223
  // Section 3.2.1.3 of RFC 1122).
224
  // Note that inet_pton() stores the IPv4 address in network byte order.
225
4
  if (ipv4[0] == 0) return false;
226
227
  // It is a routable IPv4 address in dotted-decimal notation.
228
3
  return true;
229
}
230
231
// Constants for hybi-10 frame format.
232
233
typedef int OpCode;
234
235
const OpCode kOpCodeContinuation = 0x0;
236
const OpCode kOpCodeText = 0x1;
237
const OpCode kOpCodeBinary = 0x2;
238
const OpCode kOpCodeClose = 0x8;
239
const OpCode kOpCodePing = 0x9;
240
const OpCode kOpCodePong = 0xA;
241
242
const unsigned char kFinalBit = 0x80;
243
const unsigned char kReserved1Bit = 0x40;
244
const unsigned char kReserved2Bit = 0x20;
245
const unsigned char kReserved3Bit = 0x10;
246
const unsigned char kOpCodeMask = 0xF;
247
const unsigned char kMaskBit = 0x80;
248
const unsigned char kPayloadLengthMask = 0x7F;
249
250
const size_t kMaxSingleBytePayloadLength = 125;
251
const size_t kTwoBytePayloadLengthField = 126;
252
const size_t kEightBytePayloadLengthField = 127;
253
const size_t kMaskingKeyWidthInBytes = 4;
254
255
2240
static std::vector<char> encode_frame_hybi17(const std::vector<char>& message) {
256
2240
  std::vector<char> frame;
257
2240
  OpCode op_code = kOpCodeText;
258
2240
  frame.push_back(kFinalBit | op_code);
259
2240
  const size_t data_length = message.size();
260
2240
  if (data_length <= kMaxSingleBytePayloadLength) {
261
173
    frame.push_back(static_cast<char>(data_length));
262
2067
  } else if (data_length <= 0xFFFF) {
263
2066
    frame.push_back(kTwoBytePayloadLengthField);
264
2066
    frame.push_back((data_length & 0xFF00) >> 8);
265
2066
    frame.push_back(data_length & 0xFF);
266
  } else {
267
1
    frame.push_back(kEightBytePayloadLengthField);
268
    char extended_payload_length[8];
269
1
    size_t remaining = data_length;
270
    // Fill the length into extended_payload_length in the network byte order.
271
9
    for (int i = 0; i < 8; ++i) {
272
8
      extended_payload_length[7 - i] = remaining & 0xFF;
273
8
      remaining >>= 8;
274
    }
275
2
    frame.insert(frame.end(), extended_payload_length,
276
1
                 extended_payload_length + 8);
277
1
    CHECK_EQ(0, remaining);
278
  }
279
2240
  frame.insert(frame.end(), message.begin(), message.end());
280
2240
  return frame;
281
}
282
283
172
static ws_decode_result decode_frame_hybi17(const std::vector<char>& buffer,
284
                                            bool client_frame,
285
                                            int* bytes_consumed,
286
                                            std::vector<char>* output,
287
                                            bool* compressed) {
288
172
  *bytes_consumed = 0;
289
172
  if (buffer.size() < 2)
290
    return FRAME_INCOMPLETE;
291
292
172
  auto it = buffer.begin();
293
294
172
  unsigned char first_byte = *it++;
295
172
  unsigned char second_byte = *it++;
296
297
172
  bool final = (first_byte & kFinalBit) != 0;
298
172
  bool reserved1 = (first_byte & kReserved1Bit) != 0;
299
172
  bool reserved2 = (first_byte & kReserved2Bit) != 0;
300
172
  bool reserved3 = (first_byte & kReserved3Bit) != 0;
301
172
  int op_code = first_byte & kOpCodeMask;
302
172
  bool masked = (second_byte & kMaskBit) != 0;
303
172
  *compressed = reserved1;
304

172
  if (!final || reserved2 || reserved3)
305
2
    return FRAME_ERROR;  // Only compression extension is supported.
306
307
170
  bool closed = false;
308
170
  switch (op_code) {
309
8
    case kOpCodeClose:
310
8
      closed = true;
311
8
      break;
312
162
    case kOpCodeText:
313
162
      break;
314
    case kOpCodeBinary:        // We don't support binary frames yet.
315
    case kOpCodeContinuation:  // We don't support binary frames yet.
316
    case kOpCodePing:          // We don't support binary frames yet.
317
    case kOpCodePong:          // We don't support binary frames yet.
318
    default:
319
      return FRAME_ERROR;
320
  }
321
322
  // In Hybi-17 spec client MUST mask its frame.
323

170
  if (client_frame && !masked) {
324
1
    return FRAME_ERROR;
325
  }
326
327
169
  uint64_t payload_length64 = second_byte & kPayloadLengthMask;
328
169
  if (payload_length64 > kMaxSingleBytePayloadLength) {
329
    int extended_payload_length_size;
330
34
    if (payload_length64 == kTwoBytePayloadLengthField) {
331
18
      extended_payload_length_size = 2;
332
16
    } else if (payload_length64 == kEightBytePayloadLengthField) {
333
16
      extended_payload_length_size = 8;
334
    } else {
335
      return FRAME_ERROR;
336
    }
337
34
    if ((buffer.end() - it) < extended_payload_length_size)
338
      return FRAME_INCOMPLETE;
339
34
    payload_length64 = 0;
340
198
    for (int i = 0; i < extended_payload_length_size; ++i) {
341
164
      payload_length64 <<= 8;
342
164
      payload_length64 |= static_cast<unsigned char>(*it++);
343
    }
344
  }
345
346
  static const uint64_t max_payload_length = 0x7FFFFFFFFFFFFFFFull;
347
  static const size_t max_length = SIZE_MAX;
348

169
  if (payload_length64 > max_payload_length ||
349
      payload_length64 > max_length - kMaskingKeyWidthInBytes) {
350
    // WebSocket frame length too large.
351
    return FRAME_ERROR;
352
  }
353
169
  size_t payload_length = static_cast<size_t>(payload_length64);
354
355
169
  if (buffer.size() - kMaskingKeyWidthInBytes < payload_length)
356
15
    return FRAME_INCOMPLETE;
357
358
154
  std::vector<char>::const_iterator masking_key = it;
359
154
  std::vector<char>::const_iterator payload = it + kMaskingKeyWidthInBytes;
360
1010751
  for (size_t i = 0; i < payload_length; ++i)  // Unmask the payload.
361
2021194
    output->insert(output->end(),
362
1010597
                   payload[i] ^ masking_key[i % kMaskingKeyWidthInBytes]);
363
364
154
  size_t pos = it + kMaskingKeyWidthInBytes + payload_length - buffer.begin();
365
154
  *bytes_consumed = pos;
366
154
  return closed ? FRAME_CLOSE : FRAME_OK;
367
}
368
369
// WS protocol
370
class WsHandler : public ProtocolHandler {
371
 public:
372
36
  WsHandler(InspectorSocket* inspector, TcpHolder::Pointer tcp)
373
72
            : ProtocolHandler(inspector, std::move(tcp)),
374
              OnCloseSent(&WsHandler::WaitForCloseReply),
375
              OnCloseReceived(&WsHandler::CloseFrameReceived),
376
36
              dispose_(false) { }
377
378
  void AcceptUpgrade(const std::string& accept_key) override { }
379
  void CancelHandshake() override {}
380
381
36
  void OnEof() override {
382
36
    tcp_.reset();
383
36
    if (dispose_)
384
6
      delete this;
385
36
  }
386
387
141
  void OnData(std::vector<char>* data) override {
388
    // 1. Parse.
389
141
    int processed = 0;
390
31
    do {
391
172
      processed = ParseWsFrames(*data);
392
      // 2. Fix the data size & length
393
172
      if (processed > 0) {
394
147
        remove_from_beginning(data, processed);
395
      }
396

172
    } while (processed > 0 && !data->empty());
397
141
  }
398
399
2240
  void Write(const std::vector<char> data) override {
400
4480
    std::vector<char> output = encode_frame_hybi17(data);
401
2240
    WriteRaw(output, WriteRequest::Cleanup);
402
2240
  }
403
404
 protected:
405
36
  void Shutdown() override {
406
36
    if (tcp_) {
407
6
      dispose_ = true;
408
6
      SendClose();
409
    } else {
410
30
      delete this;
411
    }
412
36
  }
413
414
 private:
415
  using Callback = void (WsHandler::*)();
416
417
9
  static void OnCloseFrameWritten(uv_write_t* req, int status) {
418
9
    WriteRequest* wr = WriteRequest::from_write_req(req);
419
9
    WsHandler* handler = static_cast<WsHandler*>(wr->handler);
420
9
    delete wr;
421
9
    Callback cb = handler->OnCloseSent;
422
9
    (handler->*cb)();
423
9
  }
424
425
6
  void WaitForCloseReply() {
426
6
    OnCloseReceived = &WsHandler::OnEof;
427
6
  }
428
429
9
  void SendClose() {
430
9
    WriteRaw(std::vector<char>(CLOSE_FRAME, CLOSE_FRAME + sizeof(CLOSE_FRAME)),
431
             OnCloseFrameWritten);
432
9
  }
433
434
3
  void CloseFrameReceived() {
435
3
    OnCloseSent = &WsHandler::OnEof;
436
3
    SendClose();
437
3
  }
438
439
172
  int ParseWsFrames(const std::vector<char>& buffer) {
440
172
    int bytes_consumed = 0;
441
172
    std::vector<char> output;
442
172
    bool compressed = false;
443
444
172
    ws_decode_result r =  decode_frame_hybi17(buffer,
445
                                              true /* client_frame */,
446
                                              &bytes_consumed, &output,
447
                                              &compressed);
448
    // Compressed frame means client is ignoring the headers and misbehaves
449

172
    if (compressed || r == FRAME_ERROR) {
450
3
      OnEof();
451
3
      bytes_consumed = 0;
452
169
    } else if (r == FRAME_CLOSE) {
453
7
      (this->*OnCloseReceived)();
454
7
      bytes_consumed = 0;
455
162
    } else if (r == FRAME_OK) {
456
147
      delegate()->OnWsFrame(output);
457
    }
458
172
    return bytes_consumed;
459
  }
460
461
462
  Callback OnCloseSent;
463
  Callback OnCloseReceived;
464
  bool dispose_;
465
};
466
467
// HTTP protocol
468
class HttpEvent {
469
 public:
470
99
  HttpEvent(const std::string& path, bool upgrade, bool isGET,
471
            const std::string& ws_key, const std::string& host)
472
99
            : path(path), upgrade(upgrade), isGET(isGET), ws_key(ws_key),
473
99
              host(host) { }
474
475
  std::string path;
476
  bool upgrade;
477
  bool isGET;
478
  std::string ws_key;
479
  std::string host;
480
};
481
482
class HttpHandler : public ProtocolHandler {
483
 public:
484
97
  explicit HttpHandler(InspectorSocket* inspector, TcpHolder::Pointer tcp)
485
194
                       : ProtocolHandler(inspector, std::move(tcp)),
486
97
                         parsing_value_(false) {
487
97
    llhttp_init(&parser_, HTTP_REQUEST, &parser_settings);
488
97
    llhttp_settings_init(&parser_settings);
489
97
    parser_settings.on_header_field = OnHeaderField;
490
97
    parser_settings.on_header_value = OnHeaderValue;
491
97
    parser_settings.on_message_complete = OnMessageComplete;
492
97
    parser_settings.on_url = OnPath;
493
97
  }
494
495
36
  void AcceptUpgrade(const std::string& accept_key) override {
496
    char accept_string[ACCEPT_KEY_LENGTH];
497
36
    generate_accept_string(accept_key, &accept_string);
498
36
    const char accept_ws_prefix[] = "HTTP/1.1 101 Switching Protocols\r\n"
499
                                    "Upgrade: websocket\r\n"
500
                                    "Connection: Upgrade\r\n"
501
                                    "Sec-WebSocket-Accept: ";
502
36
    const char accept_ws_suffix[] = "\r\n\r\n";
503
    std::vector<char> reply(accept_ws_prefix,
504
72
                            accept_ws_prefix + sizeof(accept_ws_prefix) - 1);
505
72
    reply.insert(reply.end(), accept_string,
506
36
                 accept_string + sizeof(accept_string));
507
72
    reply.insert(reply.end(), accept_ws_suffix,
508
36
                 accept_ws_suffix + sizeof(accept_ws_suffix) - 1);
509
36
    if (WriteRaw(reply, WriteRequest::Cleanup) >= 0) {
510
36
      inspector_->SwitchProtocol(new WsHandler(inspector_, std::move(tcp_)));
511
    } else {
512
      tcp_.reset();
513
    }
514
36
  }
515
516
31
  void CancelHandshake() override {
517
31
    const char HANDSHAKE_FAILED_RESPONSE[] =
518
        "HTTP/1.0 400 Bad Request\r\n"
519
        "Content-Type: text/html; charset=UTF-8\r\n\r\n"
520
        "WebSockets request was expected\r\n";
521
31
    WriteRaw(std::vector<char>(HANDSHAKE_FAILED_RESPONSE,
522
             HANDSHAKE_FAILED_RESPONSE + sizeof(HANDSHAKE_FAILED_RESPONSE) - 1),
523
             ThenCloseAndReportFailure);
524
31
  }
525
526
527
30
  void OnEof() override {
528
30
    tcp_.reset();
529
30
  }
530
531
304
  void OnData(std::vector<char>* data) override {
532
    llhttp_errno_t err;
533
304
    err = llhttp_execute(&parser_, data->data(), data->size());
534
535
304
    if (err == HPE_PAUSED_UPGRADE) {
536
40
      err = HPE_OK;
537
40
      llhttp_resume_after_upgrade(&parser_);
538
    }
539
304
    data->clear();
540
304
    if (err != HPE_OK) {
541
2
      CancelHandshake();
542
    }
543
    // Event handling may delete *this
544
304
    std::vector<HttpEvent> events;
545
304
    std::swap(events, events_);
546
380
    for (const HttpEvent& event : events) {
547

99
      if (!IsAllowedHost(event.host) || !event.isGET) {
548
22
        CancelHandshake();
549
23
        return;
550
77
      } else if (!event.upgrade) {
551
38
        delegate()->OnHttpGet(event.host, event.path);
552
39
      } else if (event.ws_key.empty()) {
553
1
        CancelHandshake();
554
1
        return;
555
      } else {
556
38
        delegate()->OnSocketUpgrade(event.host, event.path, event.ws_key);
557
      }
558
    }
559
  }
560
561
65
  void Write(const std::vector<char> data) override {
562
65
    WriteRaw(data, WriteRequest::Cleanup);
563
65
  }
564
565
 protected:
566
97
  void Shutdown() override {
567
97
    delete this;
568
97
  }
569
570
 private:
571
31
  static void ThenCloseAndReportFailure(uv_write_t* req, int status) {
572
31
    ProtocolHandler* handler = WriteRequest::from_write_req(req)->handler;
573
31
    WriteRequest::Cleanup(req, status);
574
31
    handler->inspector()->SwitchProtocol(nullptr);
575
31
  }
576
577
364
  static int OnHeaderValue(llhttp_t* parser, const char* at, size_t length) {
578
364
    HttpHandler* handler = From(parser);
579
364
    handler->parsing_value_ = true;
580
364
    handler->headers_[handler->current_header_].append(at, length);
581
364
    return 0;
582
  }
583
584
346
  static int OnHeaderField(llhttp_t* parser, const char* at, size_t length) {
585
346
    HttpHandler* handler = From(parser);
586
346
    if (handler->parsing_value_) {
587
192
      handler->parsing_value_ = false;
588
192
      handler->current_header_.clear();
589
    }
590
346
    handler->current_header_.append(at, length);
591
346
    return 0;
592
  }
593
594
135
  static int OnPath(llhttp_t* parser, const char* at, size_t length) {
595
135
    HttpHandler* handler = From(parser);
596
135
    handler->path_.append(at, length);
597
135
    return 0;
598
  }
599
600
944
  static HttpHandler* From(llhttp_t* parser) {
601
944
    return node::ContainerOf(&HttpHandler::parser_, parser);
602
  }
603
604
99
  static int OnMessageComplete(llhttp_t* parser) {
605
    // Event needs to be fired after the parser is done.
606
99
    HttpHandler* handler = From(parser);
607
99
    handler->events_.emplace_back(handler->path_,
608
99
                                  parser->upgrade,
609
198
                                  parser->method == HTTP_GET,
610
198
                                  handler->HeaderValue("Sec-WebSocket-Key"),
611
297
                                  handler->HeaderValue("Host"));
612
99
    handler->path_ = "";
613
99
    handler->parsing_value_ = false;
614
99
    handler->headers_.clear();
615
99
    handler->current_header_ = "";
616
99
    return 0;
617
  }
618
619
198
  std::string HeaderValue(const std::string& header) const {
620
198
    bool header_found = false;
621
396
    std::string value;
622
780
    for (const auto& header_value : headers_) {
623
582
      if (node::StringEqualNoCaseN(header_value.first.data(), header.data(),
624
                                   header.length())) {
625
141
        if (header_found)
626
          return "";
627
141
        value = header_value.second;
628
141
        header_found = true;
629
      }
630
    }
631
198
    return value;
632
  }
633
634
99
  bool IsAllowedHost(const std::string& host_with_port) const {
635
99
    std::string host = TrimPort(host_with_port);
636
198
    return host.empty() || IsIPAddress(host)
637

198
           || node::StringEqualNoCase(host.data(), "localhost");
638
  }
639
640
  bool parsing_value_;
641
  llhttp_t parser_;
642
  llhttp_settings_t parser_settings;
643
  std::vector<HttpEvent> events_;
644
  std::string current_header_;
645
  std::map<std::string, std::string> headers_;
646
  std::string path_;
647
};
648
649
}  // namespace
650
651
// Any protocol
652
133
ProtocolHandler::ProtocolHandler(InspectorSocket* inspector,
653
133
                                 TcpHolder::Pointer tcp)
654
133
                                 : inspector_(inspector), tcp_(std::move(tcp)) {
655
133
  CHECK_NOT_NULL(tcp_);
656
133
  tcp_->SetHandler(this);
657
133
}
658
659
2381
int ProtocolHandler::WriteRaw(const std::vector<char>& buffer,
660
                              uv_write_cb write_cb) {
661
2381
  return tcp_->WriteRaw(buffer, write_cb);
662
}
663
664
223
InspectorSocket::Delegate* ProtocolHandler::delegate() {
665
223
  return tcp_->delegate();
666
}
667
668
std::string ProtocolHandler::GetHost() const {
669
  char ip[INET6_ADDRSTRLEN];
670
  sockaddr_storage addr;
671
  int len = sizeof(addr);
672
  int err = uv_tcp_getsockname(tcp_->tcp(),
673
                               reinterpret_cast<struct sockaddr*>(&addr),
674
                               &len);
675
  if (err != 0)
676
    return "";
677
  if (addr.ss_family == AF_INET6) {
678
    const sockaddr_in6* v6 = reinterpret_cast<const sockaddr_in6*>(&addr);
679
    err = uv_ip6_name(v6, ip, sizeof(ip));
680
  } else {
681
    const sockaddr_in* v4 = reinterpret_cast<const sockaddr_in*>(&addr);
682
    err = uv_ip4_name(v4, ip, sizeof(ip));
683
  }
684
  if (err != 0)
685
    return "";
686
  return ip;
687
}
688
689
// RAII uv_tcp_t wrapper
690
97
TcpHolder::TcpHolder(InspectorSocket::DelegatePointer delegate)
691
                     : tcp_(),
692
97
                       delegate_(std::move(delegate)),
693
97
                       handler_(nullptr) { }
694
695
// static
696
97
TcpHolder::Pointer TcpHolder::Accept(
697
    uv_stream_t* server,
698
    InspectorSocket::DelegatePointer delegate) {
699
97
  TcpHolder* result = new TcpHolder(std::move(delegate));
700
97
  uv_stream_t* tcp = reinterpret_cast<uv_stream_t*>(&result->tcp_);
701
97
  int err = uv_tcp_init(server->loop, &result->tcp_);
702
97
  if (err == 0) {
703
97
    err = uv_accept(server, tcp);
704
  }
705
97
  if (err == 0) {
706
97
    err = uv_read_start(tcp, allocate_buffer, OnDataReceivedCb);
707
  }
708
97
  if (err == 0) {
709
97
    return TcpHolder::Pointer(result);
710
  } else {
711
    delete result;
712
    return nullptr;
713
  }
714
}
715
716
133
void TcpHolder::SetHandler(ProtocolHandler* handler) {
717
133
  handler_ = handler;
718
133
}
719
720
2381
int TcpHolder::WriteRaw(const std::vector<char>& buffer, uv_write_cb write_cb) {
721
#if DUMP_WRITES
722
  printf("%s (%ld bytes):\n", __FUNCTION__, buffer.size());
723
  dump_hex(buffer.data(), buffer.size());
724
  printf("\n");
725
#endif
726
727
  // Freed in write_request_cleanup
728
2381
  WriteRequest* wr = new WriteRequest(handler_, buffer);
729
2381
  uv_stream_t* stream = reinterpret_cast<uv_stream_t*>(&tcp_);
730
2381
  int err = uv_write(&wr->req, stream, &wr->buf, 1, write_cb);
731
2381
  if (err < 0)
732
    delete wr;
733
2381
  return err < 0;
734
}
735
736
223
InspectorSocket::Delegate* TcpHolder::delegate() {
737
223
  return delegate_.get();
738
}
739
740
// static
741
97
void TcpHolder::OnClosed(uv_handle_t* handle) {
742
97
  delete From(handle);
743
97
}
744
745
501
void TcpHolder::OnDataReceivedCb(uv_stream_t* tcp, ssize_t nread,
746
                                 const uv_buf_t* buf) {
747
#if DUMP_READS
748
  if (nread >= 0) {
749
    printf("%s (%ld bytes)\n", __FUNCTION__, nread);
750
    dump_hex(buf->base, nread);
751
  } else {
752
    printf("[%s:%d] %s\n", __FUNCTION__, __LINE__, uv_err_name(nread));
753
  }
754
#endif
755
501
  TcpHolder* holder = From(tcp);
756
501
  holder->ReclaimUvBuf(buf, nread);
757

501
  if (nread < 0 || nread == UV_EOF) {
758
56
    holder->handler_->OnEof();
759
  } else {
760
445
    holder->handler_->OnData(&holder->buffer);
761
  }
762
501
}
763
764
// static
765
97
void TcpHolder::DisconnectAndDispose(TcpHolder* holder) {
766
97
  uv_handle_t* handle = reinterpret_cast<uv_handle_t*>(&holder->tcp_);
767
97
  uv_close(handle, OnClosed);
768
97
}
769
770
501
void TcpHolder::ReclaimUvBuf(const uv_buf_t* buf, ssize_t read) {
771
501
  if (read > 0) {
772
445
    buffer.insert(buffer.end(), buf->base, buf->base + read);
773
  }
774
501
  delete[] buf->base;
775
501
}
776
777
InspectorSocket::~InspectorSocket() = default;
778
779
// static
780
133
void InspectorSocket::Shutdown(ProtocolHandler* handler) {
781
133
  handler->Shutdown();
782
133
}
783
784
// static
785
97
InspectorSocket::Pointer InspectorSocket::Accept(uv_stream_t* server,
786
                                                 DelegatePointer delegate) {
787
194
  auto tcp = TcpHolder::Accept(server, std::move(delegate));
788
97
  if (tcp) {
789
97
    InspectorSocket* inspector = new InspectorSocket();
790
97
    inspector->SwitchProtocol(new HttpHandler(inspector, std::move(tcp)));
791
97
    return InspectorSocket::Pointer(inspector);
792
  } else {
793
    return InspectorSocket::Pointer(nullptr);
794
  }
795
}
796
797
36
void InspectorSocket::AcceptUpgrade(const std::string& ws_key) {
798
36
  protocol_handler_->AcceptUpgrade(ws_key);
799
36
}
800
801
6
void InspectorSocket::CancelHandshake() {
802
6
  protocol_handler_->CancelHandshake();
803
6
}
804
805
std::string InspectorSocket::GetHost() {
806
  return protocol_handler_->GetHost();
807
}
808
809
164
void InspectorSocket::SwitchProtocol(ProtocolHandler* handler) {
810
164
  protocol_handler_.reset(std::move(handler));
811
164
}
812
813
2305
void InspectorSocket::Write(const char* data, size_t len) {
814
2305
  protocol_handler_->Write(std::vector<char>(data, data + len));
815
2305
}
816
817
}  // namespace inspector
818
}  // namespace node