11cb0ef41Sopenharmony_ci#include "inspector_socket.h"
21cb0ef41Sopenharmony_ci#include "util-inl.h"
31cb0ef41Sopenharmony_ci#include "gtest/gtest.h"
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include <queue>
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#define PORT 9444
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_cinamespace {
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ciusing node::inspector::InspectorSocket;
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_cistatic const int MAX_LOOP_ITERATIONS = 10000;
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_cistatic uv_loop_t loop;
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ciclass Timeout {
181cb0ef41Sopenharmony_ci public:
191cb0ef41Sopenharmony_ci  explicit Timeout(uv_loop_t* loop) : timed_out(false), done_(false) {
201cb0ef41Sopenharmony_ci    uv_timer_init(loop, &timer_);
211cb0ef41Sopenharmony_ci    uv_timer_start(&timer_, Timeout::set_flag, 5000, 0);
221cb0ef41Sopenharmony_ci  }
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci  ~Timeout() {
251cb0ef41Sopenharmony_ci    uv_timer_stop(&timer_);
261cb0ef41Sopenharmony_ci    uv_close(reinterpret_cast<uv_handle_t*>(&timer_), mark_done);
271cb0ef41Sopenharmony_ci    while (!done_) {
281cb0ef41Sopenharmony_ci      uv_run(&loop, UV_RUN_NOWAIT);
291cb0ef41Sopenharmony_ci    }
301cb0ef41Sopenharmony_ci  }
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  bool timed_out;
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci private:
351cb0ef41Sopenharmony_ci  static void set_flag(uv_timer_t* timer) {
361cb0ef41Sopenharmony_ci    Timeout* t = node::ContainerOf(&Timeout::timer_, timer);
371cb0ef41Sopenharmony_ci    t->timed_out = true;
381cb0ef41Sopenharmony_ci  }
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  static void mark_done(uv_handle_t* timer) {
411cb0ef41Sopenharmony_ci    Timeout* t = node::ContainerOf(&Timeout::timer_,
421cb0ef41Sopenharmony_ci        reinterpret_cast<uv_timer_t*>(timer));
431cb0ef41Sopenharmony_ci    t->done_ = true;
441cb0ef41Sopenharmony_ci  }
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci  bool done_;
471cb0ef41Sopenharmony_ci  uv_timer_t timer_;
481cb0ef41Sopenharmony_ci};
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci#define SPIN_WHILE(condition)                                                  \
511cb0ef41Sopenharmony_ci  {                                                                            \
521cb0ef41Sopenharmony_ci    Timeout timeout(&loop);                                                    \
531cb0ef41Sopenharmony_ci    while ((condition) && !timeout.timed_out) {                                \
541cb0ef41Sopenharmony_ci      uv_run(&loop, UV_RUN_NOWAIT);                                            \
551cb0ef41Sopenharmony_ci    }                                                                          \
561cb0ef41Sopenharmony_ci    ASSERT_FALSE((condition));                                                 \
571cb0ef41Sopenharmony_ci  }
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_cienum inspector_handshake_event {
601cb0ef41Sopenharmony_ci  kInspectorHandshakeHttpGet,
611cb0ef41Sopenharmony_ci  kInspectorHandshakeUpgraded,
621cb0ef41Sopenharmony_ci  kInspectorHandshakeNoEvents
631cb0ef41Sopenharmony_ci};
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_cistatic bool waiting_to_close = true;
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_civoid handle_closed(uv_handle_t* handle) {
681cb0ef41Sopenharmony_ci  waiting_to_close = false;
691cb0ef41Sopenharmony_ci}
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_cistatic void really_close(uv_handle_t* handle) {
721cb0ef41Sopenharmony_ci  waiting_to_close = true;
731cb0ef41Sopenharmony_ci  if (!uv_is_closing(handle)) {
741cb0ef41Sopenharmony_ci    uv_close(handle, handle_closed);
751cb0ef41Sopenharmony_ci    SPIN_WHILE(waiting_to_close);
761cb0ef41Sopenharmony_ci  }
771cb0ef41Sopenharmony_ci}
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_cistatic void buffer_alloc_cb(uv_handle_t* stream, size_t len, uv_buf_t* buf) {
801cb0ef41Sopenharmony_ci  buf->base = new char[len];
811cb0ef41Sopenharmony_ci  buf->len = len;
821cb0ef41Sopenharmony_ci}
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ciclass TestInspectorDelegate;
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_cistatic TestInspectorDelegate* delegate = nullptr;
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci// Gtest asserts can't be used in dtor directly.
891cb0ef41Sopenharmony_cistatic void assert_is_delegate(TestInspectorDelegate* d) {
901cb0ef41Sopenharmony_ci  GTEST_ASSERT_EQ(delegate, d);
911cb0ef41Sopenharmony_ci}
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ciclass TestInspectorDelegate : public InspectorSocket::Delegate {
941cb0ef41Sopenharmony_ci public:
951cb0ef41Sopenharmony_ci  using delegate_fn = void(*)(inspector_handshake_event, const std::string&,
961cb0ef41Sopenharmony_ci                              bool* should_continue);
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ci  TestInspectorDelegate() : inspector_ready(false),
991cb0ef41Sopenharmony_ci                            last_event(kInspectorHandshakeNoEvents),
1001cb0ef41Sopenharmony_ci                            handshake_events(0),
1011cb0ef41Sopenharmony_ci                            handshake_delegate_(stop_if_stop_path),
1021cb0ef41Sopenharmony_ci                            fail_on_ws_frame_(false) { }
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  ~TestInspectorDelegate() override {
1051cb0ef41Sopenharmony_ci    assert_is_delegate(this);
1061cb0ef41Sopenharmony_ci    delegate = nullptr;
1071cb0ef41Sopenharmony_ci  }
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ci  void OnHttpGet(const std::string& host, const std::string& path) override {
1101cb0ef41Sopenharmony_ci    process(kInspectorHandshakeHttpGet, path);
1111cb0ef41Sopenharmony_ci  }
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci  void OnSocketUpgrade(const std::string& host, const std::string& path,
1141cb0ef41Sopenharmony_ci                       const std::string& ws_key) override {
1151cb0ef41Sopenharmony_ci    ws_key_ = ws_key;
1161cb0ef41Sopenharmony_ci    process(kInspectorHandshakeUpgraded, path);
1171cb0ef41Sopenharmony_ci  }
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci  void OnWsFrame(const std::vector<char>& buffer) override {
1201cb0ef41Sopenharmony_ci    ASSERT_FALSE(fail_on_ws_frame_);
1211cb0ef41Sopenharmony_ci    frames.push(buffer);
1221cb0ef41Sopenharmony_ci  }
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci  void SetDelegate(delegate_fn d) {
1251cb0ef41Sopenharmony_ci    handshake_delegate_ = d;
1261cb0ef41Sopenharmony_ci  }
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci  void SetInspector(InspectorSocket::Pointer inspector) {
1291cb0ef41Sopenharmony_ci    socket_ = std::move(inspector);
1301cb0ef41Sopenharmony_ci  }
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci  void Write(const char* buf, size_t len) {
1331cb0ef41Sopenharmony_ci    socket_->Write(buf, len);
1341cb0ef41Sopenharmony_ci  }
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci  void ExpectReadError() {
1371cb0ef41Sopenharmony_ci    SPIN_WHILE(frames.empty() || !frames.back().empty());
1381cb0ef41Sopenharmony_ci  }
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci  void ExpectData(const char* data, size_t len) {
1411cb0ef41Sopenharmony_ci    const char* cur = data;
1421cb0ef41Sopenharmony_ci    const char* end = data + len;
1431cb0ef41Sopenharmony_ci    while (cur < end) {
1441cb0ef41Sopenharmony_ci      SPIN_WHILE(frames.empty());
1451cb0ef41Sopenharmony_ci      const std::vector<char>& frame = frames.front();
1461cb0ef41Sopenharmony_ci      EXPECT_FALSE(frame.empty());
1471cb0ef41Sopenharmony_ci      auto c = frame.begin();
1481cb0ef41Sopenharmony_ci      for (; c < frame.end() && cur < end; c++) {
1491cb0ef41Sopenharmony_ci        GTEST_ASSERT_EQ(*cur, *c) << "Character #" << cur - data;
1501cb0ef41Sopenharmony_ci        cur = cur + 1;
1511cb0ef41Sopenharmony_ci      }
1521cb0ef41Sopenharmony_ci      EXPECT_EQ(c, frame.end());
1531cb0ef41Sopenharmony_ci      frames.pop();
1541cb0ef41Sopenharmony_ci    }
1551cb0ef41Sopenharmony_ci  }
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_ci  void FailOnWsFrame() {
1581cb0ef41Sopenharmony_ci    fail_on_ws_frame_ = true;
1591cb0ef41Sopenharmony_ci  }
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ci  void WaitForDispose() {
1621cb0ef41Sopenharmony_ci    SPIN_WHILE(delegate != nullptr);
1631cb0ef41Sopenharmony_ci  }
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci  void Close() {
1661cb0ef41Sopenharmony_ci    socket_.reset();
1671cb0ef41Sopenharmony_ci  }
1681cb0ef41Sopenharmony_ci
1691cb0ef41Sopenharmony_ci  bool inspector_ready;
1701cb0ef41Sopenharmony_ci  std::string last_path;  // NOLINT(runtime/string)
1711cb0ef41Sopenharmony_ci  inspector_handshake_event last_event;
1721cb0ef41Sopenharmony_ci  int handshake_events;
1731cb0ef41Sopenharmony_ci  std::queue<std::vector<char>> frames;
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci private:
1761cb0ef41Sopenharmony_ci  static void stop_if_stop_path(enum inspector_handshake_event state,
1771cb0ef41Sopenharmony_ci                              const std::string& path, bool* cont) {
1781cb0ef41Sopenharmony_ci    *cont = path.empty() || path != "/close";
1791cb0ef41Sopenharmony_ci  }
1801cb0ef41Sopenharmony_ci
1811cb0ef41Sopenharmony_ci  void process(inspector_handshake_event event, const std::string& path);
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_ci  delegate_fn handshake_delegate_;
1841cb0ef41Sopenharmony_ci  InspectorSocket::Pointer socket_;
1851cb0ef41Sopenharmony_ci  std::string ws_key_;
1861cb0ef41Sopenharmony_ci  bool fail_on_ws_frame_;
1871cb0ef41Sopenharmony_ci};
1881cb0ef41Sopenharmony_ci
1891cb0ef41Sopenharmony_cistatic bool connected = false;
1901cb0ef41Sopenharmony_cistatic uv_tcp_t server, client_socket;
1911cb0ef41Sopenharmony_cistatic const char SERVER_CLOSE_FRAME[] = {'\x88', '\x00'};
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_cistruct read_expects {
1941cb0ef41Sopenharmony_ci  const char* expected;
1951cb0ef41Sopenharmony_ci  size_t expected_len;
1961cb0ef41Sopenharmony_ci  size_t pos;
1971cb0ef41Sopenharmony_ci  bool read_expected;
1981cb0ef41Sopenharmony_ci  bool callback_called;
1991cb0ef41Sopenharmony_ci};
2001cb0ef41Sopenharmony_ci
2011cb0ef41Sopenharmony_cistatic const char HANDSHAKE_REQ[] = "GET /ws/path HTTP/1.1\r\n"
2021cb0ef41Sopenharmony_ci                                    "Host: localhost:9229\r\n"
2031cb0ef41Sopenharmony_ci                                    "Upgrade: websocket\r\n"
2041cb0ef41Sopenharmony_ci                                    "Connection: Upgrade\r\n"
2051cb0ef41Sopenharmony_ci                                    "Sec-WebSocket-Key: aaa==\r\n"
2061cb0ef41Sopenharmony_ci                                    "Sec-WebSocket-Version: 13\r\n\r\n";
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_civoid TestInspectorDelegate::process(inspector_handshake_event event,
2091cb0ef41Sopenharmony_ci                                    const std::string& path) {
2101cb0ef41Sopenharmony_ci  inspector_ready = event == kInspectorHandshakeUpgraded;
2111cb0ef41Sopenharmony_ci  last_event = event;
2121cb0ef41Sopenharmony_ci  if (path.empty()) {
2131cb0ef41Sopenharmony_ci    last_path = "@@@ Nothing received @@@";
2141cb0ef41Sopenharmony_ci  } else {
2151cb0ef41Sopenharmony_ci    last_path = path;
2161cb0ef41Sopenharmony_ci  }
2171cb0ef41Sopenharmony_ci  handshake_events++;
2181cb0ef41Sopenharmony_ci  bool should_continue = true;
2191cb0ef41Sopenharmony_ci  handshake_delegate_(event, path, &should_continue);
2201cb0ef41Sopenharmony_ci  if (should_continue) {
2211cb0ef41Sopenharmony_ci    if (inspector_ready)
2221cb0ef41Sopenharmony_ci      socket_->AcceptUpgrade(ws_key_);
2231cb0ef41Sopenharmony_ci  } else {
2241cb0ef41Sopenharmony_ci    socket_->CancelHandshake();
2251cb0ef41Sopenharmony_ci  }
2261cb0ef41Sopenharmony_ci}
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_cistatic void on_new_connection(uv_stream_t* server, int status) {
2291cb0ef41Sopenharmony_ci  GTEST_ASSERT_EQ(0, status);
2301cb0ef41Sopenharmony_ci  connected = true;
2311cb0ef41Sopenharmony_ci  delegate = new TestInspectorDelegate();
2321cb0ef41Sopenharmony_ci  delegate->SetInspector(
2331cb0ef41Sopenharmony_ci      InspectorSocket::Accept(server,
2341cb0ef41Sopenharmony_ci                              InspectorSocket::DelegatePointer(delegate)));
2351cb0ef41Sopenharmony_ci  GTEST_ASSERT_NE(nullptr, delegate);
2361cb0ef41Sopenharmony_ci}
2371cb0ef41Sopenharmony_ci
2381cb0ef41Sopenharmony_civoid write_done(uv_write_t* req, int status) { req->data = nullptr; }
2391cb0ef41Sopenharmony_ci
2401cb0ef41Sopenharmony_cistatic void do_write(const char* data, int len) {
2411cb0ef41Sopenharmony_ci  uv_write_t req;
2421cb0ef41Sopenharmony_ci  bool done = false;
2431cb0ef41Sopenharmony_ci  req.data = &done;
2441cb0ef41Sopenharmony_ci  uv_buf_t buf[1];
2451cb0ef41Sopenharmony_ci  buf[0].base = const_cast<char*>(data);
2461cb0ef41Sopenharmony_ci  buf[0].len = len;
2471cb0ef41Sopenharmony_ci  GTEST_ASSERT_EQ(0,
2481cb0ef41Sopenharmony_ci                  uv_write(&req, reinterpret_cast<uv_stream_t*>(&client_socket),
2491cb0ef41Sopenharmony_ci                           buf, 1, write_done));
2501cb0ef41Sopenharmony_ci  SPIN_WHILE(req.data);
2511cb0ef41Sopenharmony_ci}
2521cb0ef41Sopenharmony_ci
2531cb0ef41Sopenharmony_cistatic void check_data_cb(read_expects* expectation, ssize_t nread,
2541cb0ef41Sopenharmony_ci                          const uv_buf_t* buf, bool* retval) {
2551cb0ef41Sopenharmony_ci  *retval = false;
2561cb0ef41Sopenharmony_ci  EXPECT_TRUE(nread >= 0 && nread != UV_EOF);
2571cb0ef41Sopenharmony_ci  ssize_t i;
2581cb0ef41Sopenharmony_ci  char c, actual;
2591cb0ef41Sopenharmony_ci  CHECK_GT(expectation->expected_len, 0);
2601cb0ef41Sopenharmony_ci  for (i = 0; i < nread && expectation->pos <= expectation->expected_len; i++) {
2611cb0ef41Sopenharmony_ci    c = expectation->expected[expectation->pos++];
2621cb0ef41Sopenharmony_ci    actual = buf->base[i];
2631cb0ef41Sopenharmony_ci    if (c != actual) {
2641cb0ef41Sopenharmony_ci      fprintf(stderr, "Unexpected character at position %zd\n",
2651cb0ef41Sopenharmony_ci              expectation->pos - 1);
2661cb0ef41Sopenharmony_ci      GTEST_ASSERT_EQ(c, actual);
2671cb0ef41Sopenharmony_ci    }
2681cb0ef41Sopenharmony_ci  }
2691cb0ef41Sopenharmony_ci  GTEST_ASSERT_EQ(i, nread);
2701cb0ef41Sopenharmony_ci  delete[] buf->base;
2711cb0ef41Sopenharmony_ci  if (expectation->pos == expectation->expected_len) {
2721cb0ef41Sopenharmony_ci    expectation->read_expected = true;
2731cb0ef41Sopenharmony_ci    *retval = true;
2741cb0ef41Sopenharmony_ci  }
2751cb0ef41Sopenharmony_ci}
2761cb0ef41Sopenharmony_ci
2771cb0ef41Sopenharmony_cistatic void check_data_cb(uv_stream_t* stream, ssize_t nread,
2781cb0ef41Sopenharmony_ci                          const uv_buf_t* buf) {
2791cb0ef41Sopenharmony_ci  bool retval = false;
2801cb0ef41Sopenharmony_ci  read_expects* expects = static_cast<read_expects*>(stream->data);
2811cb0ef41Sopenharmony_ci  expects->callback_called = true;
2821cb0ef41Sopenharmony_ci  check_data_cb(expects, nread, buf, &retval);
2831cb0ef41Sopenharmony_ci  if (retval) {
2841cb0ef41Sopenharmony_ci    stream->data = nullptr;
2851cb0ef41Sopenharmony_ci    uv_read_stop(stream);
2861cb0ef41Sopenharmony_ci  }
2871cb0ef41Sopenharmony_ci}
2881cb0ef41Sopenharmony_ci
2891cb0ef41Sopenharmony_cistatic read_expects prepare_expects(const char* data, size_t len) {
2901cb0ef41Sopenharmony_ci  read_expects expectation;
2911cb0ef41Sopenharmony_ci  expectation.expected = data;
2921cb0ef41Sopenharmony_ci  expectation.expected_len = len;
2931cb0ef41Sopenharmony_ci  expectation.pos = 0;
2941cb0ef41Sopenharmony_ci  expectation.read_expected = false;
2951cb0ef41Sopenharmony_ci  expectation.callback_called = false;
2961cb0ef41Sopenharmony_ci  return expectation;
2971cb0ef41Sopenharmony_ci}
2981cb0ef41Sopenharmony_ci
2991cb0ef41Sopenharmony_cistatic void fail_callback(uv_stream_t* stream, ssize_t nread,
3001cb0ef41Sopenharmony_ci                          const uv_buf_t* buf) {
3011cb0ef41Sopenharmony_ci  if (nread < 0) {
3021cb0ef41Sopenharmony_ci    fprintf(stderr, "IO error: %s\n", uv_strerror(nread));
3031cb0ef41Sopenharmony_ci  } else {
3041cb0ef41Sopenharmony_ci    fprintf(stderr, "Read %zd bytes\n", nread);
3051cb0ef41Sopenharmony_ci  }
3061cb0ef41Sopenharmony_ci  ASSERT_TRUE(false);  // Shouldn't have been called
3071cb0ef41Sopenharmony_ci}
3081cb0ef41Sopenharmony_ci
3091cb0ef41Sopenharmony_cistatic void expect_nothing_on_client() {
3101cb0ef41Sopenharmony_ci  uv_stream_t* stream = reinterpret_cast<uv_stream_t*>(&client_socket);
3111cb0ef41Sopenharmony_ci  int err = uv_read_start(stream, buffer_alloc_cb, fail_callback);
3121cb0ef41Sopenharmony_ci  GTEST_ASSERT_EQ(0, err);
3131cb0ef41Sopenharmony_ci  for (int i = 0; i < MAX_LOOP_ITERATIONS; i++)
3141cb0ef41Sopenharmony_ci    uv_run(&loop, UV_RUN_NOWAIT);
3151cb0ef41Sopenharmony_ci  uv_read_stop(stream);
3161cb0ef41Sopenharmony_ci}
3171cb0ef41Sopenharmony_ci
3181cb0ef41Sopenharmony_cistatic void expect_on_client(const char* data, size_t len) {
3191cb0ef41Sopenharmony_ci  read_expects expectation = prepare_expects(data, len);
3201cb0ef41Sopenharmony_ci  client_socket.data = &expectation;
3211cb0ef41Sopenharmony_ci  uv_read_start(reinterpret_cast<uv_stream_t*>(&client_socket),
3221cb0ef41Sopenharmony_ci                buffer_alloc_cb, check_data_cb);
3231cb0ef41Sopenharmony_ci  SPIN_WHILE(!expectation.read_expected);
3241cb0ef41Sopenharmony_ci}
3251cb0ef41Sopenharmony_ci
3261cb0ef41Sopenharmony_cistatic void expect_handshake() {
3271cb0ef41Sopenharmony_ci  const char UPGRADE_RESPONSE[] =
3281cb0ef41Sopenharmony_ci      "HTTP/1.1 101 Switching Protocols\r\n"
3291cb0ef41Sopenharmony_ci      "Upgrade: websocket\r\n"
3301cb0ef41Sopenharmony_ci      "Connection: Upgrade\r\n"
3311cb0ef41Sopenharmony_ci      "Sec-WebSocket-Accept: Dt87H1OULVZnSJo/KgMUYI7xPCg=\r\n\r\n";
3321cb0ef41Sopenharmony_ci  expect_on_client(UPGRADE_RESPONSE, sizeof(UPGRADE_RESPONSE) - 1);
3331cb0ef41Sopenharmony_ci}
3341cb0ef41Sopenharmony_ci
3351cb0ef41Sopenharmony_cistatic void expect_handshake_failure() {
3361cb0ef41Sopenharmony_ci  const char UPGRADE_RESPONSE[] =
3371cb0ef41Sopenharmony_ci      "HTTP/1.0 400 Bad Request\r\n"
3381cb0ef41Sopenharmony_ci      "Content-Type: text/html; charset=UTF-8\r\n\r\n"
3391cb0ef41Sopenharmony_ci      "WebSockets request was expected\r\n";
3401cb0ef41Sopenharmony_ci  expect_on_client(UPGRADE_RESPONSE, sizeof(UPGRADE_RESPONSE) - 1);
3411cb0ef41Sopenharmony_ci}
3421cb0ef41Sopenharmony_ci
3431cb0ef41Sopenharmony_cistatic void on_connection(uv_connect_t* connect, int status) {
3441cb0ef41Sopenharmony_ci  GTEST_ASSERT_EQ(0, status);
3451cb0ef41Sopenharmony_ci  connect->data = connect;
3461cb0ef41Sopenharmony_ci}
3471cb0ef41Sopenharmony_ci
3481cb0ef41Sopenharmony_ciclass InspectorSocketTest : public ::testing::Test {
3491cb0ef41Sopenharmony_ci protected:
3501cb0ef41Sopenharmony_ci  void SetUp() override {
3511cb0ef41Sopenharmony_ci    connected = false;
3521cb0ef41Sopenharmony_ci    GTEST_ASSERT_EQ(0, uv_loop_init(&loop));
3531cb0ef41Sopenharmony_ci    server = uv_tcp_t();
3541cb0ef41Sopenharmony_ci    client_socket = uv_tcp_t();
3551cb0ef41Sopenharmony_ci    sockaddr_in addr;
3561cb0ef41Sopenharmony_ci    uv_tcp_init(&loop, &server);
3571cb0ef41Sopenharmony_ci    uv_tcp_init(&loop, &client_socket);
3581cb0ef41Sopenharmony_ci    GTEST_ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", PORT, &addr));
3591cb0ef41Sopenharmony_ci    uv_tcp_bind(&server, reinterpret_cast<const struct sockaddr*>(&addr), 0);
3601cb0ef41Sopenharmony_ci    GTEST_ASSERT_EQ(0, uv_listen(reinterpret_cast<uv_stream_t*>(&server),
3611cb0ef41Sopenharmony_ci                                 1, on_new_connection));
3621cb0ef41Sopenharmony_ci    uv_connect_t connect;
3631cb0ef41Sopenharmony_ci    connect.data = nullptr;
3641cb0ef41Sopenharmony_ci    GTEST_ASSERT_EQ(0, uv_tcp_connect(&connect, &client_socket,
3651cb0ef41Sopenharmony_ci                                      reinterpret_cast<const sockaddr*>(&addr),
3661cb0ef41Sopenharmony_ci                                      on_connection));
3671cb0ef41Sopenharmony_ci    uv_tcp_nodelay(&client_socket, 1);  // The buffering messes up the test
3681cb0ef41Sopenharmony_ci    SPIN_WHILE(!connect.data || !connected);
3691cb0ef41Sopenharmony_ci    really_close(reinterpret_cast<uv_handle_t*>(&server));
3701cb0ef41Sopenharmony_ci  }
3711cb0ef41Sopenharmony_ci
3721cb0ef41Sopenharmony_ci  void TearDown() override {
3731cb0ef41Sopenharmony_ci    really_close(reinterpret_cast<uv_handle_t*>(&client_socket));
3741cb0ef41Sopenharmony_ci    SPIN_WHILE(delegate != nullptr);
3751cb0ef41Sopenharmony_ci    const int err = uv_loop_close(&loop);
3761cb0ef41Sopenharmony_ci    if (err != 0) {
3771cb0ef41Sopenharmony_ci      uv_print_all_handles(&loop, stderr);
3781cb0ef41Sopenharmony_ci    }
3791cb0ef41Sopenharmony_ci    EXPECT_EQ(0, err);
3801cb0ef41Sopenharmony_ci  }
3811cb0ef41Sopenharmony_ci};
3821cb0ef41Sopenharmony_ci
3831cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, ReadsAndWritesInspectorMessage) {
3841cb0ef41Sopenharmony_ci  ASSERT_TRUE(connected);
3851cb0ef41Sopenharmony_ci  ASSERT_FALSE(delegate->inspector_ready);
3861cb0ef41Sopenharmony_ci  do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
3871cb0ef41Sopenharmony_ci  SPIN_WHILE(!delegate->inspector_ready);
3881cb0ef41Sopenharmony_ci  expect_handshake();
3891cb0ef41Sopenharmony_ci
3901cb0ef41Sopenharmony_ci  // 2. Brief exchange
3911cb0ef41Sopenharmony_ci  const char SERVER_MESSAGE[] = "abcd";
3921cb0ef41Sopenharmony_ci  const char CLIENT_FRAME[] = {'\x81', '\x04', 'a', 'b', 'c', 'd'};
3931cb0ef41Sopenharmony_ci  delegate->Write(SERVER_MESSAGE, sizeof(SERVER_MESSAGE) - 1);
3941cb0ef41Sopenharmony_ci  expect_on_client(CLIENT_FRAME, sizeof(CLIENT_FRAME));
3951cb0ef41Sopenharmony_ci
3961cb0ef41Sopenharmony_ci  const char SERVER_FRAME[] = {'\x81', '\x84', '\x7F', '\xC2', '\x66',
3971cb0ef41Sopenharmony_ci                               '\x31', '\x4E', '\xF0', '\x55', '\x05'};
3981cb0ef41Sopenharmony_ci  const char CLIENT_MESSAGE[] = "1234";
3991cb0ef41Sopenharmony_ci  do_write(SERVER_FRAME, sizeof(SERVER_FRAME));
4001cb0ef41Sopenharmony_ci  delegate->ExpectData(CLIENT_MESSAGE, sizeof(CLIENT_MESSAGE) - 1);
4011cb0ef41Sopenharmony_ci
4021cb0ef41Sopenharmony_ci  // 3. Close
4031cb0ef41Sopenharmony_ci  const char CLIENT_CLOSE_FRAME[] = {'\x88', '\x80', '\x2D',
4041cb0ef41Sopenharmony_ci                                     '\x0E', '\x1E', '\xFA'};
4051cb0ef41Sopenharmony_ci  const char SERVER_CLOSE_FRAME[] = {'\x88', '\x00'};
4061cb0ef41Sopenharmony_ci  do_write(CLIENT_CLOSE_FRAME, sizeof(CLIENT_CLOSE_FRAME));
4071cb0ef41Sopenharmony_ci  expect_on_client(SERVER_CLOSE_FRAME, sizeof(SERVER_CLOSE_FRAME));
4081cb0ef41Sopenharmony_ci  GTEST_ASSERT_EQ(0, uv_is_active(
4091cb0ef41Sopenharmony_ci                         reinterpret_cast<uv_handle_t*>(&client_socket)));
4101cb0ef41Sopenharmony_ci}
4111cb0ef41Sopenharmony_ci
4121cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, BufferEdgeCases) {
4131cb0ef41Sopenharmony_ci  do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
4141cb0ef41Sopenharmony_ci  expect_handshake();
4151cb0ef41Sopenharmony_ci
4161cb0ef41Sopenharmony_ci  const char MULTIPLE_REQUESTS[] = {
4171cb0ef41Sopenharmony_ci      '\x81', '\xCB', '\x76', '\xCA', '\x06', '\x0C', '\x0D', '\xE8', '\x6F',
4181cb0ef41Sopenharmony_ci      '\x68', '\x54', '\xF0', '\x37', '\x3E', '\x5A', '\xE8', '\x6B', '\x69',
4191cb0ef41Sopenharmony_ci      '\x02', '\xA2', '\x69', '\x68', '\x54', '\xF0', '\x24', '\x5B', '\x19',
4201cb0ef41Sopenharmony_ci      '\xB8', '\x6D', '\x69', '\x04', '\xE4', '\x75', '\x69', '\x02', '\x8B',
4211cb0ef41Sopenharmony_ci      '\x73', '\x78', '\x19', '\xA9', '\x69', '\x62', '\x18', '\xAF', '\x65',
4221cb0ef41Sopenharmony_ci      '\x78', '\x22', '\xA5', '\x51', '\x63', '\x04', '\xA1', '\x63', '\x7E',
4231cb0ef41Sopenharmony_ci      '\x05', '\xE8', '\x2A', '\x2E', '\x06', '\xAB', '\x74', '\x6D', '\x1B',
4241cb0ef41Sopenharmony_ci      '\xB9', '\x24', '\x36', '\x0D', '\xE8', '\x70', '\x6D', '\x1A', '\xBF',
4251cb0ef41Sopenharmony_ci      '\x63', '\x2E', '\x4C', '\xBE', '\x74', '\x79', '\x13', '\xB7', '\x7B',
4261cb0ef41Sopenharmony_ci      '\x81', '\xA2', '\xFC', '\x9E', '\x0D', '\x15', '\x87', '\xBC', '\x64',
4271cb0ef41Sopenharmony_ci      '\x71', '\xDE', '\xA4', '\x3C', '\x26', '\xD0', '\xBC', '\x60', '\x70',
4281cb0ef41Sopenharmony_ci      '\x88', '\xF6', '\x62', '\x71', '\xDE', '\xA4', '\x2F', '\x42', '\x93',
4291cb0ef41Sopenharmony_ci      '\xEC', '\x66', '\x70', '\x8E', '\xB0', '\x68', '\x7B', '\x9D', '\xFC',
4301cb0ef41Sopenharmony_ci      '\x61', '\x70', '\xDE', '\xE3', '\x81', '\xA4', '\x4E', '\x37', '\xB0',
4311cb0ef41Sopenharmony_ci      '\x22', '\x35', '\x15', '\xD9', '\x46', '\x6C', '\x0D', '\x81', '\x16',
4321cb0ef41Sopenharmony_ci      '\x62', '\x15', '\xDD', '\x47', '\x3A', '\x5F', '\xDF', '\x46', '\x6C',
4331cb0ef41Sopenharmony_ci      '\x0D', '\x92', '\x72', '\x3C', '\x58', '\xD6', '\x4B', '\x22', '\x52',
4341cb0ef41Sopenharmony_ci      '\xC2', '\x0C', '\x2B', '\x59', '\xD1', '\x40', '\x22', '\x52', '\x92',
4351cb0ef41Sopenharmony_ci      '\x5F', '\x81', '\xCB', '\xCD', '\xF0', '\x30', '\xC5', '\xB6', '\xD2',
4361cb0ef41Sopenharmony_ci      '\x59', '\xA1', '\xEF', '\xCA', '\x01', '\xF0', '\xE1', '\xD2', '\x5D',
4371cb0ef41Sopenharmony_ci      '\xA0', '\xB9', '\x98', '\x5F', '\xA1', '\xEF', '\xCA', '\x12', '\x95',
4381cb0ef41Sopenharmony_ci      '\xBF', '\x9F', '\x56', '\xAC', '\xA1', '\x95', '\x42', '\xEB', '\xBE',
4391cb0ef41Sopenharmony_ci      '\x95', '\x44', '\x96', '\xAC', '\x9D', '\x40', '\xA9', '\xA4', '\x9E',
4401cb0ef41Sopenharmony_ci      '\x57', '\x8C', '\xA3', '\x84', '\x55', '\xB7', '\xBB', '\x91', '\x5C',
4411cb0ef41Sopenharmony_ci      '\xE7', '\xE1', '\xD2', '\x40', '\xA4', '\xBF', '\x91', '\x5D', '\xB6',
4421cb0ef41Sopenharmony_ci      '\xEF', '\xCA', '\x4B', '\xE7', '\xA4', '\x9E', '\x44', '\xA0', '\xBF',
4431cb0ef41Sopenharmony_ci      '\x86', '\x51', '\xA9', '\xEF', '\xCA', '\x01', '\xF5', '\xFD', '\x8D',
4441cb0ef41Sopenharmony_ci      '\x4D', '\x81', '\xA9', '\x74', '\x6B', '\x72', '\x43', '\x0F', '\x49',
4451cb0ef41Sopenharmony_ci      '\x1B', '\x27', '\x56', '\x51', '\x43', '\x75', '\x58', '\x49', '\x1F',
4461cb0ef41Sopenharmony_ci      '\x26', '\x00', '\x03', '\x1D', '\x27', '\x56', '\x51', '\x50', '\x10',
4471cb0ef41Sopenharmony_ci      '\x11', '\x19', '\x04', '\x2A', '\x17', '\x0E', '\x25', '\x2C', '\x06',
4481cb0ef41Sopenharmony_ci      '\x00', '\x17', '\x31', '\x5A', '\x0E', '\x1C', '\x22', '\x16', '\x07',
4491cb0ef41Sopenharmony_ci      '\x17', '\x61', '\x09', '\x81', '\xB8', '\x7C', '\x1A', '\xEA', '\xEB',
4501cb0ef41Sopenharmony_ci      '\x07', '\x38', '\x83', '\x8F', '\x5E', '\x20', '\xDB', '\xDC', '\x50',
4511cb0ef41Sopenharmony_ci      '\x38', '\x87', '\x8E', '\x08', '\x72', '\x85', '\x8F', '\x5E', '\x20',
4521cb0ef41Sopenharmony_ci      '\xC8', '\xA5', '\x19', '\x6E', '\x9D', '\x84', '\x0E', '\x71', '\xC4',
4531cb0ef41Sopenharmony_ci      '\x88', '\x1D', '\x74', '\xAF', '\x86', '\x09', '\x76', '\x8B', '\x9F',
4541cb0ef41Sopenharmony_ci      '\x19', '\x54', '\x8F', '\x9F', '\x0B', '\x75', '\x98', '\x80', '\x3F',
4551cb0ef41Sopenharmony_ci      '\x75', '\x84', '\x8F', '\x15', '\x6E', '\x83', '\x84', '\x12', '\x69',
4561cb0ef41Sopenharmony_ci      '\xC8', '\x96'};
4571cb0ef41Sopenharmony_ci
4581cb0ef41Sopenharmony_ci  const char EXPECT[] = {
4591cb0ef41Sopenharmony_ci      "{\"id\":12,\"method\":\"Worker.setAutoconnectToWorkers\","
4601cb0ef41Sopenharmony_ci      "\"params\":{\"value\":true}}"
4611cb0ef41Sopenharmony_ci      "{\"id\":13,\"method\":\"Worker.enable\"}"
4621cb0ef41Sopenharmony_ci      "{\"id\":14,\"method\":\"Profiler.enable\"}"
4631cb0ef41Sopenharmony_ci      "{\"id\":15,\"method\":\"Profiler.setSamplingInterval\","
4641cb0ef41Sopenharmony_ci      "\"params\":{\"interval\":100}}"
4651cb0ef41Sopenharmony_ci      "{\"id\":16,\"method\":\"ServiceWorker.enable\"}"
4661cb0ef41Sopenharmony_ci      "{\"id\":17,\"method\":\"Network.canEmulateNetworkConditions\"}"};
4671cb0ef41Sopenharmony_ci
4681cb0ef41Sopenharmony_ci  do_write(MULTIPLE_REQUESTS, sizeof(MULTIPLE_REQUESTS));
4691cb0ef41Sopenharmony_ci  delegate->ExpectData(EXPECT, sizeof(EXPECT) - 1);
4701cb0ef41Sopenharmony_ci}
4711cb0ef41Sopenharmony_ci
4721cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, AcceptsRequestInSeveralWrites) {
4731cb0ef41Sopenharmony_ci  ASSERT_TRUE(connected);
4741cb0ef41Sopenharmony_ci  ASSERT_FALSE(delegate->inspector_ready);
4751cb0ef41Sopenharmony_ci  // Specifically, break up the request in the "Sec-WebSocket-Key" header name
4761cb0ef41Sopenharmony_ci  // and value
4771cb0ef41Sopenharmony_ci  const int write1 = 95;
4781cb0ef41Sopenharmony_ci  const int write2 = 5;
4791cb0ef41Sopenharmony_ci  const int write3 = sizeof(HANDSHAKE_REQ) - write1 - write2 - 1;
4801cb0ef41Sopenharmony_ci  do_write(const_cast<char*>(HANDSHAKE_REQ), write1);
4811cb0ef41Sopenharmony_ci  ASSERT_FALSE(delegate->inspector_ready);
4821cb0ef41Sopenharmony_ci  do_write(const_cast<char*>(HANDSHAKE_REQ) + write1, write2);
4831cb0ef41Sopenharmony_ci  ASSERT_FALSE(delegate->inspector_ready);
4841cb0ef41Sopenharmony_ci  do_write(const_cast<char*>(HANDSHAKE_REQ) + write1 + write2, write3);
4851cb0ef41Sopenharmony_ci  SPIN_WHILE(!delegate->inspector_ready);
4861cb0ef41Sopenharmony_ci  expect_handshake();
4871cb0ef41Sopenharmony_ci  GTEST_ASSERT_EQ(uv_is_active(reinterpret_cast<uv_handle_t*>(&client_socket)),
4881cb0ef41Sopenharmony_ci                  0);
4891cb0ef41Sopenharmony_ci}
4901cb0ef41Sopenharmony_ci
4911cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, ExtraTextBeforeRequest) {
4921cb0ef41Sopenharmony_ci  delegate->last_event = kInspectorHandshakeUpgraded;
4931cb0ef41Sopenharmony_ci  char UNCOOL_BRO[] = "Text before the first req, shouldn't be her\r\n";
4941cb0ef41Sopenharmony_ci  do_write(const_cast<char*>(UNCOOL_BRO), sizeof(UNCOOL_BRO) - 1);
4951cb0ef41Sopenharmony_ci  expect_handshake_failure();
4961cb0ef41Sopenharmony_ci  GTEST_ASSERT_EQ(nullptr, delegate);
4971cb0ef41Sopenharmony_ci}
4981cb0ef41Sopenharmony_ci
4991cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, RequestWithoutKey) {
5001cb0ef41Sopenharmony_ci  const char BROKEN_REQUEST[] = "GET / HTTP/1.1\r\n"
5011cb0ef41Sopenharmony_ci                                "Host: localhost:9229\r\n"
5021cb0ef41Sopenharmony_ci                                "Upgrade: websocket\r\n"
5031cb0ef41Sopenharmony_ci                                "Connection: Upgrade\r\n"
5041cb0ef41Sopenharmony_ci                                "Sec-WebSocket-Version: 13\r\n\r\n";
5051cb0ef41Sopenharmony_ci
5061cb0ef41Sopenharmony_ci  do_write(const_cast<char*>(BROKEN_REQUEST), sizeof(BROKEN_REQUEST) - 1);
5071cb0ef41Sopenharmony_ci  expect_handshake_failure();
5081cb0ef41Sopenharmony_ci}
5091cb0ef41Sopenharmony_ci
5101cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, KillsConnectionOnProtocolViolation) {
5111cb0ef41Sopenharmony_ci  ASSERT_TRUE(connected);
5121cb0ef41Sopenharmony_ci  ASSERT_FALSE(delegate->inspector_ready);
5131cb0ef41Sopenharmony_ci  do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
5141cb0ef41Sopenharmony_ci  SPIN_WHILE(!delegate->inspector_ready);
5151cb0ef41Sopenharmony_ci  ASSERT_TRUE(delegate->inspector_ready);
5161cb0ef41Sopenharmony_ci  expect_handshake();
5171cb0ef41Sopenharmony_ci  const char SERVER_FRAME[] = "I'm not a good WS frame. Nope!";
5181cb0ef41Sopenharmony_ci  do_write(SERVER_FRAME, sizeof(SERVER_FRAME));
5191cb0ef41Sopenharmony_ci  SPIN_WHILE(delegate != nullptr);
5201cb0ef41Sopenharmony_ci  GTEST_ASSERT_EQ(uv_is_active(reinterpret_cast<uv_handle_t*>(&client_socket)),
5211cb0ef41Sopenharmony_ci                  0);
5221cb0ef41Sopenharmony_ci}
5231cb0ef41Sopenharmony_ci
5241cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, CanStopReadingFromInspector) {
5251cb0ef41Sopenharmony_ci  ASSERT_TRUE(connected);
5261cb0ef41Sopenharmony_ci  ASSERT_FALSE(delegate->inspector_ready);
5271cb0ef41Sopenharmony_ci  do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
5281cb0ef41Sopenharmony_ci  expect_handshake();
5291cb0ef41Sopenharmony_ci  ASSERT_TRUE(delegate->inspector_ready);
5301cb0ef41Sopenharmony_ci
5311cb0ef41Sopenharmony_ci  // 2. Brief exchange
5321cb0ef41Sopenharmony_ci  const char SERVER_FRAME[] = {'\x81', '\x84', '\x7F', '\xC2', '\x66',
5331cb0ef41Sopenharmony_ci                               '\x31', '\x4E', '\xF0', '\x55', '\x05'};
5341cb0ef41Sopenharmony_ci  const char CLIENT_MESSAGE[] = "1234";
5351cb0ef41Sopenharmony_ci  do_write(SERVER_FRAME, sizeof(SERVER_FRAME));
5361cb0ef41Sopenharmony_ci  delegate->ExpectData(CLIENT_MESSAGE, sizeof(CLIENT_MESSAGE) - 1);
5371cb0ef41Sopenharmony_ci
5381cb0ef41Sopenharmony_ci  do_write(SERVER_FRAME, sizeof(SERVER_FRAME));
5391cb0ef41Sopenharmony_ci  GTEST_ASSERT_EQ(uv_is_active(
5401cb0ef41Sopenharmony_ci                      reinterpret_cast<uv_handle_t*>(&client_socket)), 0);
5411cb0ef41Sopenharmony_ci}
5421cb0ef41Sopenharmony_ci
5431cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, CloseDoesNotNotifyReadCallback) {
5441cb0ef41Sopenharmony_ci  do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
5451cb0ef41Sopenharmony_ci  expect_handshake();
5461cb0ef41Sopenharmony_ci
5471cb0ef41Sopenharmony_ci  delegate->Close();
5481cb0ef41Sopenharmony_ci  char CLOSE_FRAME[] = {'\x88', '\x00'};
5491cb0ef41Sopenharmony_ci  expect_on_client(CLOSE_FRAME, sizeof(CLOSE_FRAME));
5501cb0ef41Sopenharmony_ci  const char CLIENT_CLOSE_FRAME[] = {'\x88', '\x80', '\x2D',
5511cb0ef41Sopenharmony_ci                                     '\x0E', '\x1E', '\xFA'};
5521cb0ef41Sopenharmony_ci  delegate->FailOnWsFrame();
5531cb0ef41Sopenharmony_ci  do_write(CLIENT_CLOSE_FRAME, sizeof(CLIENT_CLOSE_FRAME));
5541cb0ef41Sopenharmony_ci  SPIN_WHILE(delegate != nullptr);
5551cb0ef41Sopenharmony_ci}
5561cb0ef41Sopenharmony_ci
5571cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, CloseWorksWithoutReadEnabled) {
5581cb0ef41Sopenharmony_ci  do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
5591cb0ef41Sopenharmony_ci  expect_handshake();
5601cb0ef41Sopenharmony_ci  delegate->Close();
5611cb0ef41Sopenharmony_ci  char CLOSE_FRAME[] = {'\x88', '\x00'};
5621cb0ef41Sopenharmony_ci  expect_on_client(CLOSE_FRAME, sizeof(CLOSE_FRAME));
5631cb0ef41Sopenharmony_ci  const char CLIENT_CLOSE_FRAME[] = {'\x88', '\x80', '\x2D',
5641cb0ef41Sopenharmony_ci                                     '\x0E', '\x1E', '\xFA'};
5651cb0ef41Sopenharmony_ci  do_write(CLIENT_CLOSE_FRAME, sizeof(CLIENT_CLOSE_FRAME));
5661cb0ef41Sopenharmony_ci}
5671cb0ef41Sopenharmony_ci
5681cb0ef41Sopenharmony_ci// Make sure buffering works
5691cb0ef41Sopenharmony_cistatic void send_in_chunks(const char* data, size_t len) {
5701cb0ef41Sopenharmony_ci  const int step = 7;
5711cb0ef41Sopenharmony_ci  size_t i = 0;
5721cb0ef41Sopenharmony_ci  // Do not send it all at once - test the buffering!
5731cb0ef41Sopenharmony_ci  for (; i < len - step; i += step) {
5741cb0ef41Sopenharmony_ci    do_write(data + i, step);
5751cb0ef41Sopenharmony_ci  }
5761cb0ef41Sopenharmony_ci  if (i < len) {
5771cb0ef41Sopenharmony_ci    do_write(data + i, len - i);
5781cb0ef41Sopenharmony_ci  }
5791cb0ef41Sopenharmony_ci}
5801cb0ef41Sopenharmony_ci
5811cb0ef41Sopenharmony_cistatic const char TEST_SUCCESS[] = "Test Success\n\n";
5821cb0ef41Sopenharmony_cistatic int ReportsHttpGet_eventsCount = 0;
5831cb0ef41Sopenharmony_ci
5841cb0ef41Sopenharmony_cistatic void ReportsHttpGet_handshake(enum inspector_handshake_event state,
5851cb0ef41Sopenharmony_ci                                     const std::string& path, bool* cont) {
5861cb0ef41Sopenharmony_ci  *cont = true;
5871cb0ef41Sopenharmony_ci  enum inspector_handshake_event expected_state = kInspectorHandshakeHttpGet;
5881cb0ef41Sopenharmony_ci  std::string expected_path;
5891cb0ef41Sopenharmony_ci  switch (delegate->handshake_events) {
5901cb0ef41Sopenharmony_ci  case 1:
5911cb0ef41Sopenharmony_ci    expected_path = "/some/path";
5921cb0ef41Sopenharmony_ci    break;
5931cb0ef41Sopenharmony_ci  case 2:
5941cb0ef41Sopenharmony_ci    expected_path = "/respond/withtext";
5951cb0ef41Sopenharmony_ci    delegate->Write(TEST_SUCCESS, sizeof(TEST_SUCCESS) - 1);
5961cb0ef41Sopenharmony_ci    break;
5971cb0ef41Sopenharmony_ci  case 3:
5981cb0ef41Sopenharmony_ci    expected_path = "/some/path2";
5991cb0ef41Sopenharmony_ci    break;
6001cb0ef41Sopenharmony_ci  case 4:
6011cb0ef41Sopenharmony_ci    expected_path = "/close";
6021cb0ef41Sopenharmony_ci    *cont = false;
6031cb0ef41Sopenharmony_ci    break;
6041cb0ef41Sopenharmony_ci  default:
6051cb0ef41Sopenharmony_ci    ASSERT_TRUE(false);
6061cb0ef41Sopenharmony_ci  }
6071cb0ef41Sopenharmony_ci  EXPECT_EQ(expected_state, state);
6081cb0ef41Sopenharmony_ci  EXPECT_EQ(expected_path, path);
6091cb0ef41Sopenharmony_ci  ReportsHttpGet_eventsCount = delegate->handshake_events;
6101cb0ef41Sopenharmony_ci}
6111cb0ef41Sopenharmony_ci
6121cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, ReportsHttpGet) {
6131cb0ef41Sopenharmony_ci  delegate->SetDelegate(ReportsHttpGet_handshake);
6141cb0ef41Sopenharmony_ci
6151cb0ef41Sopenharmony_ci  const char GET_REQ[] = "GET /some/path HTTP/1.1\r\n"
6161cb0ef41Sopenharmony_ci                         "Host: localhost:9229\r\n"
6171cb0ef41Sopenharmony_ci                         "Sec-WebSocket-Key: aaa==\r\n"
6181cb0ef41Sopenharmony_ci                         "Sec-WebSocket-Version: 13\r\n\r\n";
6191cb0ef41Sopenharmony_ci  send_in_chunks(GET_REQ, sizeof(GET_REQ) - 1);
6201cb0ef41Sopenharmony_ci
6211cb0ef41Sopenharmony_ci  expect_nothing_on_client();
6221cb0ef41Sopenharmony_ci  const char WRITE_REQUEST[] = "GET /respond/withtext HTTP/1.1\r\n"
6231cb0ef41Sopenharmony_ci                               "Host: localhost:9229\r\n\r\n";
6241cb0ef41Sopenharmony_ci  send_in_chunks(WRITE_REQUEST, sizeof(WRITE_REQUEST) - 1);
6251cb0ef41Sopenharmony_ci
6261cb0ef41Sopenharmony_ci  expect_on_client(TEST_SUCCESS, sizeof(TEST_SUCCESS) - 1);
6271cb0ef41Sopenharmony_ci  const char GET_REQS[] = "GET /some/path2 HTTP/1.1\r\n"
6281cb0ef41Sopenharmony_ci                          "Host: localhost:9229\r\n"
6291cb0ef41Sopenharmony_ci                          "Sec-WebSocket-Key: aaa==\r\n"
6301cb0ef41Sopenharmony_ci                          "Sec-WebSocket-Version: 13\r\n\r\n"
6311cb0ef41Sopenharmony_ci                          "GET /close HTTP/1.1\r\n"
6321cb0ef41Sopenharmony_ci                          "Host: localhost:9229\r\n"
6331cb0ef41Sopenharmony_ci                          "Sec-WebSocket-Key: aaa==\r\n"
6341cb0ef41Sopenharmony_ci                          "Sec-WebSocket-Version: 13\r\n\r\n";
6351cb0ef41Sopenharmony_ci  send_in_chunks(GET_REQS, sizeof(GET_REQS) - 1);
6361cb0ef41Sopenharmony_ci  expect_handshake_failure();
6371cb0ef41Sopenharmony_ci  EXPECT_EQ(4, ReportsHttpGet_eventsCount);
6381cb0ef41Sopenharmony_ci  EXPECT_EQ(nullptr, delegate);
6391cb0ef41Sopenharmony_ci}
6401cb0ef41Sopenharmony_ci
6411cb0ef41Sopenharmony_cistatic int HandshakeCanBeCanceled_eventCount = 0;
6421cb0ef41Sopenharmony_ci
6431cb0ef41Sopenharmony_cistatic
6441cb0ef41Sopenharmony_civoid HandshakeCanBeCanceled_handshake(enum inspector_handshake_event state,
6451cb0ef41Sopenharmony_ci                                      const std::string& path, bool* cont) {
6461cb0ef41Sopenharmony_ci  switch (delegate->handshake_events - 1) {
6471cb0ef41Sopenharmony_ci  case 0:
6481cb0ef41Sopenharmony_ci    EXPECT_EQ(kInspectorHandshakeUpgraded, state);
6491cb0ef41Sopenharmony_ci    EXPECT_EQ("/ws/path", path);
6501cb0ef41Sopenharmony_ci    break;
6511cb0ef41Sopenharmony_ci  default:
6521cb0ef41Sopenharmony_ci    EXPECT_TRUE(false);
6531cb0ef41Sopenharmony_ci    break;
6541cb0ef41Sopenharmony_ci  }
6551cb0ef41Sopenharmony_ci  *cont = false;
6561cb0ef41Sopenharmony_ci  HandshakeCanBeCanceled_eventCount = delegate->handshake_events;
6571cb0ef41Sopenharmony_ci}
6581cb0ef41Sopenharmony_ci
6591cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HandshakeCanBeCanceled) {
6601cb0ef41Sopenharmony_ci  delegate->SetDelegate(HandshakeCanBeCanceled_handshake);
6611cb0ef41Sopenharmony_ci
6621cb0ef41Sopenharmony_ci  do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
6631cb0ef41Sopenharmony_ci
6641cb0ef41Sopenharmony_ci  expect_handshake_failure();
6651cb0ef41Sopenharmony_ci  EXPECT_EQ(1, HandshakeCanBeCanceled_eventCount);
6661cb0ef41Sopenharmony_ci  EXPECT_EQ(nullptr, delegate);
6671cb0ef41Sopenharmony_ci}
6681cb0ef41Sopenharmony_ci
6691cb0ef41Sopenharmony_cistatic void GetThenHandshake_handshake(enum inspector_handshake_event state,
6701cb0ef41Sopenharmony_ci                                       const std::string& path, bool* cont) {
6711cb0ef41Sopenharmony_ci  *cont = true;
6721cb0ef41Sopenharmony_ci  std::string expected_path = "/ws/path";
6731cb0ef41Sopenharmony_ci  switch (delegate->handshake_events - 1) {
6741cb0ef41Sopenharmony_ci  case 0:
6751cb0ef41Sopenharmony_ci    EXPECT_EQ(kInspectorHandshakeHttpGet, state);
6761cb0ef41Sopenharmony_ci    expected_path = "/respond/withtext";
6771cb0ef41Sopenharmony_ci    delegate->Write(TEST_SUCCESS, sizeof(TEST_SUCCESS) - 1);
6781cb0ef41Sopenharmony_ci    break;
6791cb0ef41Sopenharmony_ci  case 1:
6801cb0ef41Sopenharmony_ci    EXPECT_EQ(kInspectorHandshakeUpgraded, state);
6811cb0ef41Sopenharmony_ci    break;
6821cb0ef41Sopenharmony_ci  default:
6831cb0ef41Sopenharmony_ci    EXPECT_TRUE(false);
6841cb0ef41Sopenharmony_ci    break;
6851cb0ef41Sopenharmony_ci  }
6861cb0ef41Sopenharmony_ci  EXPECT_EQ(expected_path, path);
6871cb0ef41Sopenharmony_ci}
6881cb0ef41Sopenharmony_ci
6891cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, GetThenHandshake) {
6901cb0ef41Sopenharmony_ci  delegate->SetDelegate(GetThenHandshake_handshake);
6911cb0ef41Sopenharmony_ci  const char WRITE_REQUEST[] = "GET /respond/withtext HTTP/1.1\r\n"
6921cb0ef41Sopenharmony_ci                               "Host: localhost:9229\r\n\r\n";
6931cb0ef41Sopenharmony_ci  send_in_chunks(WRITE_REQUEST, sizeof(WRITE_REQUEST) - 1);
6941cb0ef41Sopenharmony_ci
6951cb0ef41Sopenharmony_ci  expect_on_client(TEST_SUCCESS, sizeof(TEST_SUCCESS) - 1);
6961cb0ef41Sopenharmony_ci
6971cb0ef41Sopenharmony_ci  do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
6981cb0ef41Sopenharmony_ci  expect_handshake();
6991cb0ef41Sopenharmony_ci  EXPECT_EQ(2, delegate->handshake_events);
7001cb0ef41Sopenharmony_ci}
7011cb0ef41Sopenharmony_ci
7021cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, WriteBeforeHandshake) {
7031cb0ef41Sopenharmony_ci  const char MESSAGE1[] = "Message 1";
7041cb0ef41Sopenharmony_ci  const char MESSAGE2[] = "Message 2";
7051cb0ef41Sopenharmony_ci  const char EXPECTED[] = "Message 1Message 2";
7061cb0ef41Sopenharmony_ci
7071cb0ef41Sopenharmony_ci  delegate->Write(MESSAGE1, sizeof(MESSAGE1) - 1);
7081cb0ef41Sopenharmony_ci  delegate->Write(MESSAGE2, sizeof(MESSAGE2) - 1);
7091cb0ef41Sopenharmony_ci  expect_on_client(EXPECTED, sizeof(EXPECTED) - 1);
7101cb0ef41Sopenharmony_ci  really_close(reinterpret_cast<uv_handle_t*>(&client_socket));
7111cb0ef41Sopenharmony_ci  SPIN_WHILE(delegate != nullptr);
7121cb0ef41Sopenharmony_ci}
7131cb0ef41Sopenharmony_ci
7141cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, CleanupSocketAfterEOF) {
7151cb0ef41Sopenharmony_ci  do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
7161cb0ef41Sopenharmony_ci  expect_handshake();
7171cb0ef41Sopenharmony_ci
7181cb0ef41Sopenharmony_ci  for (int i = 0; i < MAX_LOOP_ITERATIONS; ++i) {
7191cb0ef41Sopenharmony_ci    uv_run(&loop, UV_RUN_NOWAIT);
7201cb0ef41Sopenharmony_ci  }
7211cb0ef41Sopenharmony_ci
7221cb0ef41Sopenharmony_ci  uv_close(reinterpret_cast<uv_handle_t*>(&client_socket), nullptr);
7231cb0ef41Sopenharmony_ci  SPIN_WHILE(delegate != nullptr);
7241cb0ef41Sopenharmony_ci}
7251cb0ef41Sopenharmony_ci
7261cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, EOFBeforeHandshake) {
7271cb0ef41Sopenharmony_ci  const char MESSAGE[] = "We'll send EOF afterwards";
7281cb0ef41Sopenharmony_ci  delegate->Write(MESSAGE, sizeof(MESSAGE) - 1);
7291cb0ef41Sopenharmony_ci  expect_on_client(MESSAGE, sizeof(MESSAGE) - 1);
7301cb0ef41Sopenharmony_ci  uv_close(reinterpret_cast<uv_handle_t*>(&client_socket), nullptr);
7311cb0ef41Sopenharmony_ci  SPIN_WHILE(delegate != nullptr);
7321cb0ef41Sopenharmony_ci}
7331cb0ef41Sopenharmony_ci
7341cb0ef41Sopenharmony_cistatic void fill_message(std::string* buffer) {
7351cb0ef41Sopenharmony_ci  for (size_t i = 0; i < buffer->size(); i += 1) {
7361cb0ef41Sopenharmony_ci    (*buffer)[i] = 'a' + (i % ('z' - 'a'));
7371cb0ef41Sopenharmony_ci  }
7381cb0ef41Sopenharmony_ci}
7391cb0ef41Sopenharmony_ci
7401cb0ef41Sopenharmony_cistatic void mask_message(const std::string& message,
7411cb0ef41Sopenharmony_ci                         char* buffer, const char mask[]) {
7421cb0ef41Sopenharmony_ci  const size_t mask_len = 4;
7431cb0ef41Sopenharmony_ci  for (size_t i = 0; i < message.size(); i += 1) {
7441cb0ef41Sopenharmony_ci    buffer[i] = message[i] ^ mask[i % mask_len];
7451cb0ef41Sopenharmony_ci  }
7461cb0ef41Sopenharmony_ci}
7471cb0ef41Sopenharmony_ci
7481cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, Send1Mb) {
7491cb0ef41Sopenharmony_ci  ASSERT_TRUE(connected);
7501cb0ef41Sopenharmony_ci  ASSERT_FALSE(delegate->inspector_ready);
7511cb0ef41Sopenharmony_ci  do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
7521cb0ef41Sopenharmony_ci  SPIN_WHILE(!delegate->inspector_ready);
7531cb0ef41Sopenharmony_ci  expect_handshake();
7541cb0ef41Sopenharmony_ci
7551cb0ef41Sopenharmony_ci  // 2. Brief exchange
7561cb0ef41Sopenharmony_ci  std::string message(1000000, '\0');
7571cb0ef41Sopenharmony_ci  fill_message(&message);
7581cb0ef41Sopenharmony_ci
7591cb0ef41Sopenharmony_ci  // 1000000 is 0xF4240 hex
7601cb0ef41Sopenharmony_ci  const char EXPECTED_FRAME_HEADER[] = {
7611cb0ef41Sopenharmony_ci    '\x81', '\x7f', '\x00', '\x00', '\x00', '\x00', '\x00', '\x0F',
7621cb0ef41Sopenharmony_ci    '\x42', '\x40'
7631cb0ef41Sopenharmony_ci  };
7641cb0ef41Sopenharmony_ci  std::string expected(EXPECTED_FRAME_HEADER, sizeof(EXPECTED_FRAME_HEADER));
7651cb0ef41Sopenharmony_ci  expected.append(message);
7661cb0ef41Sopenharmony_ci
7671cb0ef41Sopenharmony_ci  delegate->Write(message.data(), message.size());
7681cb0ef41Sopenharmony_ci  expect_on_client(expected.data(), expected.size());
7691cb0ef41Sopenharmony_ci
7701cb0ef41Sopenharmony_ci  char MASK[4] = {'W', 'h', 'O', 'a'};
7711cb0ef41Sopenharmony_ci
7721cb0ef41Sopenharmony_ci  const char FRAME_TO_SERVER_HEADER[] = {
7731cb0ef41Sopenharmony_ci    '\x81', '\xff', '\x00', '\x00', '\x00', '\x00', '\x00', '\x0F',
7741cb0ef41Sopenharmony_ci    '\x42', '\x40', MASK[0], MASK[1], MASK[2], MASK[3]
7751cb0ef41Sopenharmony_ci  };
7761cb0ef41Sopenharmony_ci
7771cb0ef41Sopenharmony_ci  std::string outgoing(FRAME_TO_SERVER_HEADER, sizeof(FRAME_TO_SERVER_HEADER));
7781cb0ef41Sopenharmony_ci  outgoing.resize(outgoing.size() + message.size());
7791cb0ef41Sopenharmony_ci  mask_message(message, &outgoing[sizeof(FRAME_TO_SERVER_HEADER)], MASK);
7801cb0ef41Sopenharmony_ci
7811cb0ef41Sopenharmony_ci  do_write(outgoing.data(), outgoing.size());
7821cb0ef41Sopenharmony_ci  delegate->ExpectData(message.data(), message.size());
7831cb0ef41Sopenharmony_ci
7841cb0ef41Sopenharmony_ci  // 3. Close
7851cb0ef41Sopenharmony_ci  const char CLIENT_CLOSE_FRAME[] = {'\x88', '\x80', '\x2D',
7861cb0ef41Sopenharmony_ci                                     '\x0E', '\x1E', '\xFA'};
7871cb0ef41Sopenharmony_ci  do_write(CLIENT_CLOSE_FRAME, sizeof(CLIENT_CLOSE_FRAME));
7881cb0ef41Sopenharmony_ci  expect_on_client(SERVER_CLOSE_FRAME, sizeof(SERVER_CLOSE_FRAME));
7891cb0ef41Sopenharmony_ci  GTEST_ASSERT_EQ(0, uv_is_active(
7901cb0ef41Sopenharmony_ci                         reinterpret_cast<uv_handle_t*>(&client_socket)));
7911cb0ef41Sopenharmony_ci}
7921cb0ef41Sopenharmony_ci
7931cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, ErrorCleansUpTheSocket) {
7941cb0ef41Sopenharmony_ci  do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
7951cb0ef41Sopenharmony_ci  expect_handshake();
7961cb0ef41Sopenharmony_ci  const char NOT_A_GOOD_FRAME[] = {'H', 'e', 'l', 'l', 'o'};
7971cb0ef41Sopenharmony_ci  do_write(NOT_A_GOOD_FRAME, sizeof(NOT_A_GOOD_FRAME));
7981cb0ef41Sopenharmony_ci  SPIN_WHILE(delegate != nullptr);
7991cb0ef41Sopenharmony_ci}
8001cb0ef41Sopenharmony_ci
8011cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, NoCloseResponseFromClient) {
8021cb0ef41Sopenharmony_ci  ASSERT_TRUE(connected);
8031cb0ef41Sopenharmony_ci  ASSERT_FALSE(delegate->inspector_ready);
8041cb0ef41Sopenharmony_ci  do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
8051cb0ef41Sopenharmony_ci  SPIN_WHILE(!delegate->inspector_ready);
8061cb0ef41Sopenharmony_ci  expect_handshake();
8071cb0ef41Sopenharmony_ci
8081cb0ef41Sopenharmony_ci  // 2. Brief exchange
8091cb0ef41Sopenharmony_ci  const char SERVER_MESSAGE[] = "abcd";
8101cb0ef41Sopenharmony_ci  const char CLIENT_FRAME[] = {'\x81', '\x04', 'a', 'b', 'c', 'd'};
8111cb0ef41Sopenharmony_ci  delegate->Write(SERVER_MESSAGE, sizeof(SERVER_MESSAGE) - 1);
8121cb0ef41Sopenharmony_ci  expect_on_client(CLIENT_FRAME, sizeof(CLIENT_FRAME));
8131cb0ef41Sopenharmony_ci
8141cb0ef41Sopenharmony_ci  delegate->Close();
8151cb0ef41Sopenharmony_ci  expect_on_client(SERVER_CLOSE_FRAME, sizeof(SERVER_CLOSE_FRAME));
8161cb0ef41Sopenharmony_ci  uv_close(reinterpret_cast<uv_handle_t*>(&client_socket), nullptr);
8171cb0ef41Sopenharmony_ci  GTEST_ASSERT_EQ(0, uv_is_active(
8181cb0ef41Sopenharmony_ci                  reinterpret_cast<uv_handle_t*>(&client_socket)));
8191cb0ef41Sopenharmony_ci  delegate->WaitForDispose();
8201cb0ef41Sopenharmony_ci}
8211cb0ef41Sopenharmony_ci
8221cb0ef41Sopenharmony_cistatic bool delegate_called = false;
8231cb0ef41Sopenharmony_ci
8241cb0ef41Sopenharmony_civoid shouldnt_be_called(enum inspector_handshake_event state,
8251cb0ef41Sopenharmony_ci                        const std::string& path, bool* cont) {
8261cb0ef41Sopenharmony_ci  delegate_called = true;
8271cb0ef41Sopenharmony_ci}
8281cb0ef41Sopenharmony_ci
8291cb0ef41Sopenharmony_civoid expect_failure_no_delegate(const std::string& request) {
8301cb0ef41Sopenharmony_ci  delegate->SetDelegate(shouldnt_be_called);
8311cb0ef41Sopenharmony_ci  delegate_called = false;
8321cb0ef41Sopenharmony_ci  send_in_chunks(request.c_str(), request.length());
8331cb0ef41Sopenharmony_ci  expect_handshake_failure();
8341cb0ef41Sopenharmony_ci  SPIN_WHILE(delegate != nullptr);
8351cb0ef41Sopenharmony_ci  ASSERT_FALSE(delegate_called);
8361cb0ef41Sopenharmony_ci}
8371cb0ef41Sopenharmony_ci
8381cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostCheckedForGET) {
8391cb0ef41Sopenharmony_ci  const char GET_REQUEST[] = "GET /respond/withtext HTTP/1.1\r\n"
8401cb0ef41Sopenharmony_ci                             "Host: notlocalhost:9229\r\n\r\n";
8411cb0ef41Sopenharmony_ci  expect_failure_no_delegate(GET_REQUEST);
8421cb0ef41Sopenharmony_ci}
8431cb0ef41Sopenharmony_ci
8441cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostCheckedForUPGRADE) {
8451cb0ef41Sopenharmony_ci  const char UPGRADE_REQUEST[] = "GET /ws/path HTTP/1.1\r\n"
8461cb0ef41Sopenharmony_ci                                 "Host: nonlocalhost:9229\r\n"
8471cb0ef41Sopenharmony_ci                                 "Upgrade: websocket\r\n"
8481cb0ef41Sopenharmony_ci                                 "Connection: Upgrade\r\n"
8491cb0ef41Sopenharmony_ci                                 "Sec-WebSocket-Key: aaa==\r\n"
8501cb0ef41Sopenharmony_ci                                 "Sec-WebSocket-Version: 13\r\n\r\n";
8511cb0ef41Sopenharmony_ci  expect_failure_no_delegate(UPGRADE_REQUEST);
8521cb0ef41Sopenharmony_ci}
8531cb0ef41Sopenharmony_ci
8541cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIPChecked) {
8551cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
8561cb0ef41Sopenharmony_ci                                              "Host: 10.0.2.555:9229\r\n\r\n";
8571cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
8581cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
8591cb0ef41Sopenharmony_ci  expect_handshake_failure();
8601cb0ef41Sopenharmony_ci}
8611cb0ef41Sopenharmony_ci
8621cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostNegativeIPChecked) {
8631cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
8641cb0ef41Sopenharmony_ci                                              "Host: 10.0.-23.255:9229\r\n\r\n";
8651cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
8661cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
8671cb0ef41Sopenharmony_ci  expect_handshake_failure();
8681cb0ef41Sopenharmony_ci}
8691cb0ef41Sopenharmony_ci
8701cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIpOctetOutOfIntRangeChecked) {
8711cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST =
8721cb0ef41Sopenharmony_ci      "GET /json HTTP/1.1\r\n"
8731cb0ef41Sopenharmony_ci      "Host: 127.0.0.4294967296:9229\r\n\r\n";
8741cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
8751cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
8761cb0ef41Sopenharmony_ci  expect_handshake_failure();
8771cb0ef41Sopenharmony_ci}
8781cb0ef41Sopenharmony_ci
8791cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIpOctetFarOutOfIntRangeChecked) {
8801cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST =
8811cb0ef41Sopenharmony_ci      "GET /json HTTP/1.1\r\n"
8821cb0ef41Sopenharmony_ci      "Host: 127.0.0.18446744073709552000:9229\r\n\r\n";
8831cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
8841cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
8851cb0ef41Sopenharmony_ci  expect_handshake_failure();
8861cb0ef41Sopenharmony_ci}
8871cb0ef41Sopenharmony_ci
8881cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIpEmptyOctetStartChecked) {
8891cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
8901cb0ef41Sopenharmony_ci                                              "Host: .0.0.1:9229\r\n\r\n";
8911cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
8921cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
8931cb0ef41Sopenharmony_ci  expect_handshake_failure();
8941cb0ef41Sopenharmony_ci}
8951cb0ef41Sopenharmony_ci
8961cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIpEmptyOctetMidChecked) {
8971cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
8981cb0ef41Sopenharmony_ci                                              "Host: 127..0.1:9229\r\n\r\n";
8991cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
9001cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
9011cb0ef41Sopenharmony_ci  expect_handshake_failure();
9021cb0ef41Sopenharmony_ci}
9031cb0ef41Sopenharmony_ci
9041cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIpEmptyOctetEndChecked) {
9051cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
9061cb0ef41Sopenharmony_ci                                              "Host: 127.0.0.:9229\r\n\r\n";
9071cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
9081cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
9091cb0ef41Sopenharmony_ci  expect_handshake_failure();
9101cb0ef41Sopenharmony_ci}
9111cb0ef41Sopenharmony_ci
9121cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIpTooFewOctetsChecked) {
9131cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
9141cb0ef41Sopenharmony_ci                                              "Host: 127.0.1:9229\r\n\r\n";
9151cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
9161cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
9171cb0ef41Sopenharmony_ci  expect_handshake_failure();
9181cb0ef41Sopenharmony_ci}
9191cb0ef41Sopenharmony_ci
9201cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIpTooManyOctetsChecked) {
9211cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
9221cb0ef41Sopenharmony_ci                                              "Host: 127.0.0.0.1:9229\r\n\r\n";
9231cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
9241cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
9251cb0ef41Sopenharmony_ci  expect_handshake_failure();
9261cb0ef41Sopenharmony_ci}
9271cb0ef41Sopenharmony_ci
9281cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIpInvalidOctalOctetStartChecked) {
9291cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
9301cb0ef41Sopenharmony_ci                                              "Host: 08.1.1.1:9229\r\n\r\n";
9311cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
9321cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
9331cb0ef41Sopenharmony_ci  expect_handshake_failure();
9341cb0ef41Sopenharmony_ci}
9351cb0ef41Sopenharmony_ci
9361cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIpInvalidOctalOctetMidChecked) {
9371cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
9381cb0ef41Sopenharmony_ci                                              "Host: 1.09.1.1:9229\r\n\r\n";
9391cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
9401cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
9411cb0ef41Sopenharmony_ci  expect_handshake_failure();
9421cb0ef41Sopenharmony_ci}
9431cb0ef41Sopenharmony_ci
9441cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIpInvalidOctalOctetEndChecked) {
9451cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
9461cb0ef41Sopenharmony_ci                                              "Host: 1.1.1.009:9229\r\n\r\n";
9471cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
9481cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
9491cb0ef41Sopenharmony_ci  expect_handshake_failure();
9501cb0ef41Sopenharmony_ci}
9511cb0ef41Sopenharmony_ci
9521cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIpLeadingZeroStartChecked) {
9531cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
9541cb0ef41Sopenharmony_ci                                              "Host: 01.1.1.1:9229\r\n\r\n";
9551cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
9561cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
9571cb0ef41Sopenharmony_ci  expect_handshake_failure();
9581cb0ef41Sopenharmony_ci}
9591cb0ef41Sopenharmony_ci
9601cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIpLeadingZeroMidChecked) {
9611cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
9621cb0ef41Sopenharmony_ci                                              "Host: 1.1.001.1:9229\r\n\r\n";
9631cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
9641cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
9651cb0ef41Sopenharmony_ci  expect_handshake_failure();
9661cb0ef41Sopenharmony_ci}
9671cb0ef41Sopenharmony_ci
9681cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIpLeadingZeroEndChecked) {
9691cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
9701cb0ef41Sopenharmony_ci                                              "Host: 1.1.1.01:9229\r\n\r\n";
9711cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
9721cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
9731cb0ef41Sopenharmony_ci  expect_handshake_failure();
9741cb0ef41Sopenharmony_ci}
9751cb0ef41Sopenharmony_ci
9761cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIPNonRoutable) {
9771cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
9781cb0ef41Sopenharmony_ci                                              "Host: 0.0.0.0:9229\r\n\r\n";
9791cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
9801cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
9811cb0ef41Sopenharmony_ci  expect_handshake_failure();
9821cb0ef41Sopenharmony_ci}
9831cb0ef41Sopenharmony_ci
9841cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIPv6NonRoutable) {
9851cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
9861cb0ef41Sopenharmony_ci                                              "Host: [::]:9229\r\n\r\n";
9871cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
9881cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
9891cb0ef41Sopenharmony_ci  expect_handshake_failure();
9901cb0ef41Sopenharmony_ci}
9911cb0ef41Sopenharmony_ci
9921cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIPv6NonRoutableDual) {
9931cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
9941cb0ef41Sopenharmony_ci                                              "Host: [::0.0.0.0]:9229\r\n\r\n";
9951cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
9961cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
9971cb0ef41Sopenharmony_ci  expect_handshake_failure();
9981cb0ef41Sopenharmony_ci}
9991cb0ef41Sopenharmony_ci
10001cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIPv4InSquareBrackets) {
10011cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
10021cb0ef41Sopenharmony_ci                                              "Host: [127.0.0.1]:9229\r\n\r\n";
10031cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
10041cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
10051cb0ef41Sopenharmony_ci  expect_handshake_failure();
10061cb0ef41Sopenharmony_ci}
10071cb0ef41Sopenharmony_ci
10081cb0ef41Sopenharmony_ciTEST_F(InspectorSocketTest, HostIPv6InvalidAbbreviation) {
10091cb0ef41Sopenharmony_ci  const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
10101cb0ef41Sopenharmony_ci                                              "Host: [:::1]:9229\r\n\r\n";
10111cb0ef41Sopenharmony_ci  send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
10121cb0ef41Sopenharmony_ci                 INVALID_HOST_IP_REQUEST.length());
10131cb0ef41Sopenharmony_ci  expect_handshake_failure();
10141cb0ef41Sopenharmony_ci}
10151cb0ef41Sopenharmony_ci
10161cb0ef41Sopenharmony_ci}  // anonymous namespace
1017