• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "inspector_socket.h"
2 #include "util-inl.h"
3 #include "gtest/gtest.h"
4 
5 #include <queue>
6 
7 #define PORT 9444
8 
9 namespace {
10 
11 using node::inspector::InspectorSocket;
12 
13 static const int MAX_LOOP_ITERATIONS = 10000;
14 
15 static uv_loop_t loop;
16 
17 class Timeout {
18  public:
Timeout(uv_loop_t * loop)19   explicit Timeout(uv_loop_t* loop) : timed_out(false), done_(false) {
20     uv_timer_init(loop, &timer_);
21     uv_timer_start(&timer_, Timeout::set_flag, 5000, 0);
22   }
23 
~Timeout()24   ~Timeout() {
25     uv_timer_stop(&timer_);
26     uv_close(reinterpret_cast<uv_handle_t*>(&timer_), mark_done);
27     while (!done_) {
28       uv_run(&loop, UV_RUN_NOWAIT);
29     }
30   }
31 
32   bool timed_out;
33 
34  private:
set_flag(uv_timer_t * timer)35   static void set_flag(uv_timer_t* timer) {
36     Timeout* t = node::ContainerOf(&Timeout::timer_, timer);
37     t->timed_out = true;
38   }
39 
mark_done(uv_handle_t * timer)40   static void mark_done(uv_handle_t* timer) {
41     Timeout* t = node::ContainerOf(&Timeout::timer_,
42         reinterpret_cast<uv_timer_t*>(timer));
43     t->done_ = true;
44   }
45 
46   bool done_;
47   uv_timer_t timer_;
48 };
49 
50 #define SPIN_WHILE(condition)                                                  \
51   {                                                                            \
52     Timeout timeout(&loop);                                                    \
53     while ((condition) && !timeout.timed_out) {                                \
54       uv_run(&loop, UV_RUN_NOWAIT);                                            \
55     }                                                                          \
56     ASSERT_FALSE((condition));                                                 \
57   }
58 
59 enum inspector_handshake_event {
60   kInspectorHandshakeHttpGet,
61   kInspectorHandshakeUpgraded,
62   kInspectorHandshakeNoEvents
63 };
64 
65 static bool waiting_to_close = true;
66 
handle_closed(uv_handle_t * handle)67 void handle_closed(uv_handle_t* handle) {
68   waiting_to_close = false;
69 }
70 
really_close(uv_handle_t * handle)71 static void really_close(uv_handle_t* handle) {
72   waiting_to_close = true;
73   if (!uv_is_closing(handle)) {
74     uv_close(handle, handle_closed);
75     SPIN_WHILE(waiting_to_close);
76   }
77 }
78 
buffer_alloc_cb(uv_handle_t * stream,size_t len,uv_buf_t * buf)79 static void buffer_alloc_cb(uv_handle_t* stream, size_t len, uv_buf_t* buf) {
80   buf->base = new char[len];
81   buf->len = len;
82 }
83 
84 class TestInspectorDelegate;
85 
86 static TestInspectorDelegate* delegate = nullptr;
87 
88 // Gtest asserts can't be used in dtor directly.
assert_is_delegate(TestInspectorDelegate * d)89 static void assert_is_delegate(TestInspectorDelegate* d) {
90   GTEST_ASSERT_EQ(delegate, d);
91 }
92 
93 class TestInspectorDelegate : public InspectorSocket::Delegate {
94  public:
95   using delegate_fn = void(*)(inspector_handshake_event, const std::string&,
96                               bool* should_continue);
97 
TestInspectorDelegate()98   TestInspectorDelegate() : inspector_ready(false),
99                             last_event(kInspectorHandshakeNoEvents),
100                             handshake_events(0),
101                             handshake_delegate_(stop_if_stop_path),
102                             fail_on_ws_frame_(false) { }
103 
~TestInspectorDelegate()104   ~TestInspectorDelegate() override {
105     assert_is_delegate(this);
106     delegate = nullptr;
107   }
108 
OnHttpGet(const std::string & host,const std::string & path)109   void OnHttpGet(const std::string& host, const std::string& path) override {
110     process(kInspectorHandshakeHttpGet, path);
111   }
112 
OnSocketUpgrade(const std::string & host,const std::string & path,const std::string & ws_key)113   void OnSocketUpgrade(const std::string& host, const std::string& path,
114                        const std::string& ws_key) override {
115     ws_key_ = ws_key;
116     process(kInspectorHandshakeUpgraded, path);
117   }
118 
OnWsFrame(const std::vector<char> & buffer)119   void OnWsFrame(const std::vector<char>& buffer) override {
120     ASSERT_FALSE(fail_on_ws_frame_);
121     frames.push(buffer);
122   }
123 
SetDelegate(delegate_fn d)124   void SetDelegate(delegate_fn d) {
125     handshake_delegate_ = d;
126   }
127 
SetInspector(InspectorSocket::Pointer inspector)128   void SetInspector(InspectorSocket::Pointer inspector) {
129     socket_ = std::move(inspector);
130   }
131 
Write(const char * buf,size_t len)132   void Write(const char* buf, size_t len) {
133     socket_->Write(buf, len);
134   }
135 
ExpectReadError()136   void ExpectReadError() {
137     SPIN_WHILE(frames.empty() || !frames.back().empty());
138   }
139 
ExpectData(const char * data,size_t len)140   void ExpectData(const char* data, size_t len) {
141     const char* cur = data;
142     const char* end = data + len;
143     while (cur < end) {
144       SPIN_WHILE(frames.empty());
145       const std::vector<char>& frame = frames.front();
146       EXPECT_FALSE(frame.empty());
147       auto c = frame.begin();
148       for (; c < frame.end() && cur < end; c++) {
149         GTEST_ASSERT_EQ(*cur, *c) << "Character #" << cur - data;
150         cur = cur + 1;
151       }
152       EXPECT_EQ(c, frame.end());
153       frames.pop();
154     }
155   }
156 
FailOnWsFrame()157   void FailOnWsFrame() {
158     fail_on_ws_frame_ = true;
159   }
160 
WaitForDispose()161   void WaitForDispose() {
162     SPIN_WHILE(delegate != nullptr);
163   }
164 
Close()165   void Close() {
166     socket_.reset();
167   }
168 
169   bool inspector_ready;
170   std::string last_path;  // NOLINT(runtime/string)
171   inspector_handshake_event last_event;
172   int handshake_events;
173   std::queue<std::vector<char>> frames;
174 
175  private:
stop_if_stop_path(enum inspector_handshake_event state,const std::string & path,bool * cont)176   static void stop_if_stop_path(enum inspector_handshake_event state,
177                               const std::string& path, bool* cont) {
178     *cont = path.empty() || path != "/close";
179   }
180 
181   void process(inspector_handshake_event event, const std::string& path);
182 
183   delegate_fn handshake_delegate_;
184   InspectorSocket::Pointer socket_;
185   std::string ws_key_;
186   bool fail_on_ws_frame_;
187 };
188 
189 static bool connected = false;
190 static uv_tcp_t server, client_socket;
191 static const char SERVER_CLOSE_FRAME[] = {'\x88', '\x00'};
192 
193 struct read_expects {
194   const char* expected;
195   size_t expected_len;
196   size_t pos;
197   bool read_expected;
198   bool callback_called;
199 };
200 
201 static const char HANDSHAKE_REQ[] = "GET /ws/path HTTP/1.1\r\n"
202                                     "Host: localhost:9229\r\n"
203                                     "Upgrade: websocket\r\n"
204                                     "Connection: Upgrade\r\n"
205                                     "Sec-WebSocket-Key: aaa==\r\n"
206                                     "Sec-WebSocket-Version: 13\r\n\r\n";
207 
process(inspector_handshake_event event,const std::string & path)208 void TestInspectorDelegate::process(inspector_handshake_event event,
209                                     const std::string& path) {
210   inspector_ready = event == kInspectorHandshakeUpgraded;
211   last_event = event;
212   if (path.empty()) {
213     last_path = "@@@ Nothing received @@@";
214   } else {
215     last_path = path;
216   }
217   handshake_events++;
218   bool should_continue = true;
219   handshake_delegate_(event, path, &should_continue);
220   if (should_continue) {
221     if (inspector_ready)
222       socket_->AcceptUpgrade(ws_key_);
223   } else {
224     socket_->CancelHandshake();
225   }
226 }
227 
on_new_connection(uv_stream_t * server,int status)228 static void on_new_connection(uv_stream_t* server, int status) {
229   GTEST_ASSERT_EQ(0, status);
230   connected = true;
231   delegate = new TestInspectorDelegate();
232   delegate->SetInspector(
233       InspectorSocket::Accept(server,
234                               InspectorSocket::DelegatePointer(delegate)));
235   GTEST_ASSERT_NE(nullptr, delegate);
236 }
237 
write_done(uv_write_t * req,int status)238 void write_done(uv_write_t* req, int status) { req->data = nullptr; }
239 
do_write(const char * data,int len)240 static void do_write(const char* data, int len) {
241   uv_write_t req;
242   bool done = false;
243   req.data = &done;
244   uv_buf_t buf[1];
245   buf[0].base = const_cast<char*>(data);
246   buf[0].len = len;
247   GTEST_ASSERT_EQ(0,
248                   uv_write(&req, reinterpret_cast<uv_stream_t*>(&client_socket),
249                            buf, 1, write_done));
250   SPIN_WHILE(req.data);
251 }
252 
check_data_cb(read_expects * expectation,ssize_t nread,const uv_buf_t * buf,bool * retval)253 static void check_data_cb(read_expects* expectation, ssize_t nread,
254                           const uv_buf_t* buf, bool* retval) {
255   *retval = false;
256   EXPECT_TRUE(nread >= 0 && nread != UV_EOF);
257   ssize_t i;
258   char c, actual;
259   CHECK_GT(expectation->expected_len, 0);
260   for (i = 0; i < nread && expectation->pos <= expectation->expected_len; i++) {
261     c = expectation->expected[expectation->pos++];
262     actual = buf->base[i];
263     if (c != actual) {
264       fprintf(stderr, "Unexpected character at position %zd\n",
265               expectation->pos - 1);
266       GTEST_ASSERT_EQ(c, actual);
267     }
268   }
269   GTEST_ASSERT_EQ(i, nread);
270   delete[] buf->base;
271   if (expectation->pos == expectation->expected_len) {
272     expectation->read_expected = true;
273     *retval = true;
274   }
275 }
276 
check_data_cb(uv_stream_t * stream,ssize_t nread,const uv_buf_t * buf)277 static void check_data_cb(uv_stream_t* stream, ssize_t nread,
278                           const uv_buf_t* buf) {
279   bool retval = false;
280   read_expects* expects = static_cast<read_expects*>(stream->data);
281   expects->callback_called = true;
282   check_data_cb(expects, nread, buf, &retval);
283   if (retval) {
284     stream->data = nullptr;
285     uv_read_stop(stream);
286   }
287 }
288 
prepare_expects(const char * data,size_t len)289 static read_expects prepare_expects(const char* data, size_t len) {
290   read_expects expectation;
291   expectation.expected = data;
292   expectation.expected_len = len;
293   expectation.pos = 0;
294   expectation.read_expected = false;
295   expectation.callback_called = false;
296   return expectation;
297 }
298 
fail_callback(uv_stream_t * stream,ssize_t nread,const uv_buf_t * buf)299 static void fail_callback(uv_stream_t* stream, ssize_t nread,
300                           const uv_buf_t* buf) {
301   if (nread < 0) {
302     fprintf(stderr, "IO error: %s\n", uv_strerror(nread));
303   } else {
304     fprintf(stderr, "Read %zd bytes\n", nread);
305   }
306   ASSERT_TRUE(false);  // Shouldn't have been called
307 }
308 
expect_nothing_on_client()309 static void expect_nothing_on_client() {
310   uv_stream_t* stream = reinterpret_cast<uv_stream_t*>(&client_socket);
311   int err = uv_read_start(stream, buffer_alloc_cb, fail_callback);
312   GTEST_ASSERT_EQ(0, err);
313   for (int i = 0; i < MAX_LOOP_ITERATIONS; i++)
314     uv_run(&loop, UV_RUN_NOWAIT);
315   uv_read_stop(stream);
316 }
317 
expect_on_client(const char * data,size_t len)318 static void expect_on_client(const char* data, size_t len) {
319   read_expects expectation = prepare_expects(data, len);
320   client_socket.data = &expectation;
321   uv_read_start(reinterpret_cast<uv_stream_t*>(&client_socket),
322                 buffer_alloc_cb, check_data_cb);
323   SPIN_WHILE(!expectation.read_expected);
324 }
325 
expect_handshake()326 static void expect_handshake() {
327   const char UPGRADE_RESPONSE[] =
328       "HTTP/1.1 101 Switching Protocols\r\n"
329       "Upgrade: websocket\r\n"
330       "Connection: Upgrade\r\n"
331       "Sec-WebSocket-Accept: Dt87H1OULVZnSJo/KgMUYI7xPCg=\r\n\r\n";
332   expect_on_client(UPGRADE_RESPONSE, sizeof(UPGRADE_RESPONSE) - 1);
333 }
334 
expect_handshake_failure()335 static void expect_handshake_failure() {
336   const char UPGRADE_RESPONSE[] =
337       "HTTP/1.0 400 Bad Request\r\n"
338       "Content-Type: text/html; charset=UTF-8\r\n\r\n"
339       "WebSockets request was expected\r\n";
340   expect_on_client(UPGRADE_RESPONSE, sizeof(UPGRADE_RESPONSE) - 1);
341 }
342 
on_connection(uv_connect_t * connect,int status)343 static void on_connection(uv_connect_t* connect, int status) {
344   GTEST_ASSERT_EQ(0, status);
345   connect->data = connect;
346 }
347 
348 class InspectorSocketTest : public ::testing::Test {
349  protected:
SetUp()350   void SetUp() override {
351     connected = false;
352     GTEST_ASSERT_EQ(0, uv_loop_init(&loop));
353     server = uv_tcp_t();
354     client_socket = uv_tcp_t();
355     sockaddr_in addr;
356     uv_tcp_init(&loop, &server);
357     uv_tcp_init(&loop, &client_socket);
358     GTEST_ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", PORT, &addr));
359     uv_tcp_bind(&server, reinterpret_cast<const struct sockaddr*>(&addr), 0);
360     GTEST_ASSERT_EQ(0, uv_listen(reinterpret_cast<uv_stream_t*>(&server),
361                                  1, on_new_connection));
362     uv_connect_t connect;
363     connect.data = nullptr;
364     GTEST_ASSERT_EQ(0, uv_tcp_connect(&connect, &client_socket,
365                                       reinterpret_cast<const sockaddr*>(&addr),
366                                       on_connection));
367     uv_tcp_nodelay(&client_socket, 1);  // The buffering messes up the test
368     SPIN_WHILE(!connect.data || !connected);
369     really_close(reinterpret_cast<uv_handle_t*>(&server));
370   }
371 
TearDown()372   void TearDown() override {
373     really_close(reinterpret_cast<uv_handle_t*>(&client_socket));
374     SPIN_WHILE(delegate != nullptr);
375     const int err = uv_loop_close(&loop);
376     if (err != 0) {
377       uv_print_all_handles(&loop, stderr);
378     }
379     EXPECT_EQ(0, err);
380   }
381 };
382 
TEST_F(InspectorSocketTest,ReadsAndWritesInspectorMessage)383 TEST_F(InspectorSocketTest, ReadsAndWritesInspectorMessage) {
384   ASSERT_TRUE(connected);
385   ASSERT_FALSE(delegate->inspector_ready);
386   do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
387   SPIN_WHILE(!delegate->inspector_ready);
388   expect_handshake();
389 
390   // 2. Brief exchange
391   const char SERVER_MESSAGE[] = "abcd";
392   const char CLIENT_FRAME[] = {'\x81', '\x04', 'a', 'b', 'c', 'd'};
393   delegate->Write(SERVER_MESSAGE, sizeof(SERVER_MESSAGE) - 1);
394   expect_on_client(CLIENT_FRAME, sizeof(CLIENT_FRAME));
395 
396   const char SERVER_FRAME[] = {'\x81', '\x84', '\x7F', '\xC2', '\x66',
397                                '\x31', '\x4E', '\xF0', '\x55', '\x05'};
398   const char CLIENT_MESSAGE[] = "1234";
399   do_write(SERVER_FRAME, sizeof(SERVER_FRAME));
400   delegate->ExpectData(CLIENT_MESSAGE, sizeof(CLIENT_MESSAGE) - 1);
401 
402   // 3. Close
403   const char CLIENT_CLOSE_FRAME[] = {'\x88', '\x80', '\x2D',
404                                      '\x0E', '\x1E', '\xFA'};
405   const char SERVER_CLOSE_FRAME[] = {'\x88', '\x00'};
406   do_write(CLIENT_CLOSE_FRAME, sizeof(CLIENT_CLOSE_FRAME));
407   expect_on_client(SERVER_CLOSE_FRAME, sizeof(SERVER_CLOSE_FRAME));
408   GTEST_ASSERT_EQ(0, uv_is_active(
409                          reinterpret_cast<uv_handle_t*>(&client_socket)));
410 }
411 
TEST_F(InspectorSocketTest,BufferEdgeCases)412 TEST_F(InspectorSocketTest, BufferEdgeCases) {
413   do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
414   expect_handshake();
415 
416   const char MULTIPLE_REQUESTS[] = {
417       '\x81', '\xCB', '\x76', '\xCA', '\x06', '\x0C', '\x0D', '\xE8', '\x6F',
418       '\x68', '\x54', '\xF0', '\x37', '\x3E', '\x5A', '\xE8', '\x6B', '\x69',
419       '\x02', '\xA2', '\x69', '\x68', '\x54', '\xF0', '\x24', '\x5B', '\x19',
420       '\xB8', '\x6D', '\x69', '\x04', '\xE4', '\x75', '\x69', '\x02', '\x8B',
421       '\x73', '\x78', '\x19', '\xA9', '\x69', '\x62', '\x18', '\xAF', '\x65',
422       '\x78', '\x22', '\xA5', '\x51', '\x63', '\x04', '\xA1', '\x63', '\x7E',
423       '\x05', '\xE8', '\x2A', '\x2E', '\x06', '\xAB', '\x74', '\x6D', '\x1B',
424       '\xB9', '\x24', '\x36', '\x0D', '\xE8', '\x70', '\x6D', '\x1A', '\xBF',
425       '\x63', '\x2E', '\x4C', '\xBE', '\x74', '\x79', '\x13', '\xB7', '\x7B',
426       '\x81', '\xA2', '\xFC', '\x9E', '\x0D', '\x15', '\x87', '\xBC', '\x64',
427       '\x71', '\xDE', '\xA4', '\x3C', '\x26', '\xD0', '\xBC', '\x60', '\x70',
428       '\x88', '\xF6', '\x62', '\x71', '\xDE', '\xA4', '\x2F', '\x42', '\x93',
429       '\xEC', '\x66', '\x70', '\x8E', '\xB0', '\x68', '\x7B', '\x9D', '\xFC',
430       '\x61', '\x70', '\xDE', '\xE3', '\x81', '\xA4', '\x4E', '\x37', '\xB0',
431       '\x22', '\x35', '\x15', '\xD9', '\x46', '\x6C', '\x0D', '\x81', '\x16',
432       '\x62', '\x15', '\xDD', '\x47', '\x3A', '\x5F', '\xDF', '\x46', '\x6C',
433       '\x0D', '\x92', '\x72', '\x3C', '\x58', '\xD6', '\x4B', '\x22', '\x52',
434       '\xC2', '\x0C', '\x2B', '\x59', '\xD1', '\x40', '\x22', '\x52', '\x92',
435       '\x5F', '\x81', '\xCB', '\xCD', '\xF0', '\x30', '\xC5', '\xB6', '\xD2',
436       '\x59', '\xA1', '\xEF', '\xCA', '\x01', '\xF0', '\xE1', '\xD2', '\x5D',
437       '\xA0', '\xB9', '\x98', '\x5F', '\xA1', '\xEF', '\xCA', '\x12', '\x95',
438       '\xBF', '\x9F', '\x56', '\xAC', '\xA1', '\x95', '\x42', '\xEB', '\xBE',
439       '\x95', '\x44', '\x96', '\xAC', '\x9D', '\x40', '\xA9', '\xA4', '\x9E',
440       '\x57', '\x8C', '\xA3', '\x84', '\x55', '\xB7', '\xBB', '\x91', '\x5C',
441       '\xE7', '\xE1', '\xD2', '\x40', '\xA4', '\xBF', '\x91', '\x5D', '\xB6',
442       '\xEF', '\xCA', '\x4B', '\xE7', '\xA4', '\x9E', '\x44', '\xA0', '\xBF',
443       '\x86', '\x51', '\xA9', '\xEF', '\xCA', '\x01', '\xF5', '\xFD', '\x8D',
444       '\x4D', '\x81', '\xA9', '\x74', '\x6B', '\x72', '\x43', '\x0F', '\x49',
445       '\x1B', '\x27', '\x56', '\x51', '\x43', '\x75', '\x58', '\x49', '\x1F',
446       '\x26', '\x00', '\x03', '\x1D', '\x27', '\x56', '\x51', '\x50', '\x10',
447       '\x11', '\x19', '\x04', '\x2A', '\x17', '\x0E', '\x25', '\x2C', '\x06',
448       '\x00', '\x17', '\x31', '\x5A', '\x0E', '\x1C', '\x22', '\x16', '\x07',
449       '\x17', '\x61', '\x09', '\x81', '\xB8', '\x7C', '\x1A', '\xEA', '\xEB',
450       '\x07', '\x38', '\x83', '\x8F', '\x5E', '\x20', '\xDB', '\xDC', '\x50',
451       '\x38', '\x87', '\x8E', '\x08', '\x72', '\x85', '\x8F', '\x5E', '\x20',
452       '\xC8', '\xA5', '\x19', '\x6E', '\x9D', '\x84', '\x0E', '\x71', '\xC4',
453       '\x88', '\x1D', '\x74', '\xAF', '\x86', '\x09', '\x76', '\x8B', '\x9F',
454       '\x19', '\x54', '\x8F', '\x9F', '\x0B', '\x75', '\x98', '\x80', '\x3F',
455       '\x75', '\x84', '\x8F', '\x15', '\x6E', '\x83', '\x84', '\x12', '\x69',
456       '\xC8', '\x96'};
457 
458   const char EXPECT[] = {
459       "{\"id\":12,\"method\":\"Worker.setAutoconnectToWorkers\","
460       "\"params\":{\"value\":true}}"
461       "{\"id\":13,\"method\":\"Worker.enable\"}"
462       "{\"id\":14,\"method\":\"Profiler.enable\"}"
463       "{\"id\":15,\"method\":\"Profiler.setSamplingInterval\","
464       "\"params\":{\"interval\":100}}"
465       "{\"id\":16,\"method\":\"ServiceWorker.enable\"}"
466       "{\"id\":17,\"method\":\"Network.canEmulateNetworkConditions\"}"};
467 
468   do_write(MULTIPLE_REQUESTS, sizeof(MULTIPLE_REQUESTS));
469   delegate->ExpectData(EXPECT, sizeof(EXPECT) - 1);
470 }
471 
TEST_F(InspectorSocketTest,AcceptsRequestInSeveralWrites)472 TEST_F(InspectorSocketTest, AcceptsRequestInSeveralWrites) {
473   ASSERT_TRUE(connected);
474   ASSERT_FALSE(delegate->inspector_ready);
475   // Specifically, break up the request in the "Sec-WebSocket-Key" header name
476   // and value
477   const int write1 = 95;
478   const int write2 = 5;
479   const int write3 = sizeof(HANDSHAKE_REQ) - write1 - write2 - 1;
480   do_write(const_cast<char*>(HANDSHAKE_REQ), write1);
481   ASSERT_FALSE(delegate->inspector_ready);
482   do_write(const_cast<char*>(HANDSHAKE_REQ) + write1, write2);
483   ASSERT_FALSE(delegate->inspector_ready);
484   do_write(const_cast<char*>(HANDSHAKE_REQ) + write1 + write2, write3);
485   SPIN_WHILE(!delegate->inspector_ready);
486   expect_handshake();
487   GTEST_ASSERT_EQ(uv_is_active(reinterpret_cast<uv_handle_t*>(&client_socket)),
488                   0);
489 }
490 
TEST_F(InspectorSocketTest,ExtraTextBeforeRequest)491 TEST_F(InspectorSocketTest, ExtraTextBeforeRequest) {
492   delegate->last_event = kInspectorHandshakeUpgraded;
493   char UNCOOL_BRO[] = "Text before the first req, shouldn't be her\r\n";
494   do_write(const_cast<char*>(UNCOOL_BRO), sizeof(UNCOOL_BRO) - 1);
495   expect_handshake_failure();
496   GTEST_ASSERT_EQ(nullptr, delegate);
497 }
498 
TEST_F(InspectorSocketTest,RequestWithoutKey)499 TEST_F(InspectorSocketTest, RequestWithoutKey) {
500   const char BROKEN_REQUEST[] = "GET / HTTP/1.1\r\n"
501                                 "Host: localhost:9229\r\n"
502                                 "Upgrade: websocket\r\n"
503                                 "Connection: Upgrade\r\n"
504                                 "Sec-WebSocket-Version: 13\r\n\r\n";
505 
506   do_write(const_cast<char*>(BROKEN_REQUEST), sizeof(BROKEN_REQUEST) - 1);
507   expect_handshake_failure();
508 }
509 
TEST_F(InspectorSocketTest,KillsConnectionOnProtocolViolation)510 TEST_F(InspectorSocketTest, KillsConnectionOnProtocolViolation) {
511   ASSERT_TRUE(connected);
512   ASSERT_FALSE(delegate->inspector_ready);
513   do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
514   SPIN_WHILE(!delegate->inspector_ready);
515   ASSERT_TRUE(delegate->inspector_ready);
516   expect_handshake();
517   const char SERVER_FRAME[] = "I'm not a good WS frame. Nope!";
518   do_write(SERVER_FRAME, sizeof(SERVER_FRAME));
519   SPIN_WHILE(delegate != nullptr);
520   GTEST_ASSERT_EQ(uv_is_active(reinterpret_cast<uv_handle_t*>(&client_socket)),
521                   0);
522 }
523 
TEST_F(InspectorSocketTest,CanStopReadingFromInspector)524 TEST_F(InspectorSocketTest, CanStopReadingFromInspector) {
525   ASSERT_TRUE(connected);
526   ASSERT_FALSE(delegate->inspector_ready);
527   do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
528   expect_handshake();
529   ASSERT_TRUE(delegate->inspector_ready);
530 
531   // 2. Brief exchange
532   const char SERVER_FRAME[] = {'\x81', '\x84', '\x7F', '\xC2', '\x66',
533                                '\x31', '\x4E', '\xF0', '\x55', '\x05'};
534   const char CLIENT_MESSAGE[] = "1234";
535   do_write(SERVER_FRAME, sizeof(SERVER_FRAME));
536   delegate->ExpectData(CLIENT_MESSAGE, sizeof(CLIENT_MESSAGE) - 1);
537 
538   do_write(SERVER_FRAME, sizeof(SERVER_FRAME));
539   GTEST_ASSERT_EQ(uv_is_active(
540                       reinterpret_cast<uv_handle_t*>(&client_socket)), 0);
541 }
542 
TEST_F(InspectorSocketTest,CloseDoesNotNotifyReadCallback)543 TEST_F(InspectorSocketTest, CloseDoesNotNotifyReadCallback) {
544   do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
545   expect_handshake();
546 
547   delegate->Close();
548   char CLOSE_FRAME[] = {'\x88', '\x00'};
549   expect_on_client(CLOSE_FRAME, sizeof(CLOSE_FRAME));
550   const char CLIENT_CLOSE_FRAME[] = {'\x88', '\x80', '\x2D',
551                                      '\x0E', '\x1E', '\xFA'};
552   delegate->FailOnWsFrame();
553   do_write(CLIENT_CLOSE_FRAME, sizeof(CLIENT_CLOSE_FRAME));
554   SPIN_WHILE(delegate != nullptr);
555 }
556 
TEST_F(InspectorSocketTest,CloseWorksWithoutReadEnabled)557 TEST_F(InspectorSocketTest, CloseWorksWithoutReadEnabled) {
558   do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
559   expect_handshake();
560   delegate->Close();
561   char CLOSE_FRAME[] = {'\x88', '\x00'};
562   expect_on_client(CLOSE_FRAME, sizeof(CLOSE_FRAME));
563   const char CLIENT_CLOSE_FRAME[] = {'\x88', '\x80', '\x2D',
564                                      '\x0E', '\x1E', '\xFA'};
565   do_write(CLIENT_CLOSE_FRAME, sizeof(CLIENT_CLOSE_FRAME));
566 }
567 
568 // Make sure buffering works
send_in_chunks(const char * data,size_t len)569 static void send_in_chunks(const char* data, size_t len) {
570   const int step = 7;
571   size_t i = 0;
572   // Do not send it all at once - test the buffering!
573   for (; i < len - step; i += step) {
574     do_write(data + i, step);
575   }
576   if (i < len) {
577     do_write(data + i, len - i);
578   }
579 }
580 
581 static const char TEST_SUCCESS[] = "Test Success\n\n";
582 static int ReportsHttpGet_eventsCount = 0;
583 
ReportsHttpGet_handshake(enum inspector_handshake_event state,const std::string & path,bool * cont)584 static void ReportsHttpGet_handshake(enum inspector_handshake_event state,
585                                      const std::string& path, bool* cont) {
586   *cont = true;
587   enum inspector_handshake_event expected_state = kInspectorHandshakeHttpGet;
588   std::string expected_path;
589   switch (delegate->handshake_events) {
590   case 1:
591     expected_path = "/some/path";
592     break;
593   case 2:
594     expected_path = "/respond/withtext";
595     delegate->Write(TEST_SUCCESS, sizeof(TEST_SUCCESS) - 1);
596     break;
597   case 3:
598     expected_path = "/some/path2";
599     break;
600   case 4:
601     expected_path = "/close";
602     *cont = false;
603     break;
604   default:
605     ASSERT_TRUE(false);
606   }
607   EXPECT_EQ(expected_state, state);
608   EXPECT_EQ(expected_path, path);
609   ReportsHttpGet_eventsCount = delegate->handshake_events;
610 }
611 
TEST_F(InspectorSocketTest,ReportsHttpGet)612 TEST_F(InspectorSocketTest, ReportsHttpGet) {
613   delegate->SetDelegate(ReportsHttpGet_handshake);
614 
615   const char GET_REQ[] = "GET /some/path HTTP/1.1\r\n"
616                          "Host: localhost:9229\r\n"
617                          "Sec-WebSocket-Key: aaa==\r\n"
618                          "Sec-WebSocket-Version: 13\r\n\r\n";
619   send_in_chunks(GET_REQ, sizeof(GET_REQ) - 1);
620 
621   expect_nothing_on_client();
622   const char WRITE_REQUEST[] = "GET /respond/withtext HTTP/1.1\r\n"
623                                "Host: localhost:9229\r\n\r\n";
624   send_in_chunks(WRITE_REQUEST, sizeof(WRITE_REQUEST) - 1);
625 
626   expect_on_client(TEST_SUCCESS, sizeof(TEST_SUCCESS) - 1);
627   const char GET_REQS[] = "GET /some/path2 HTTP/1.1\r\n"
628                           "Host: localhost:9229\r\n"
629                           "Sec-WebSocket-Key: aaa==\r\n"
630                           "Sec-WebSocket-Version: 13\r\n\r\n"
631                           "GET /close HTTP/1.1\r\n"
632                           "Host: localhost:9229\r\n"
633                           "Sec-WebSocket-Key: aaa==\r\n"
634                           "Sec-WebSocket-Version: 13\r\n\r\n";
635   send_in_chunks(GET_REQS, sizeof(GET_REQS) - 1);
636   expect_handshake_failure();
637   EXPECT_EQ(4, ReportsHttpGet_eventsCount);
638   EXPECT_EQ(nullptr, delegate);
639 }
640 
641 static int HandshakeCanBeCanceled_eventCount = 0;
642 
643 static
HandshakeCanBeCanceled_handshake(enum inspector_handshake_event state,const std::string & path,bool * cont)644 void HandshakeCanBeCanceled_handshake(enum inspector_handshake_event state,
645                                       const std::string& path, bool* cont) {
646   switch (delegate->handshake_events - 1) {
647   case 0:
648     EXPECT_EQ(kInspectorHandshakeUpgraded, state);
649     EXPECT_EQ("/ws/path", path);
650     break;
651   default:
652     EXPECT_TRUE(false);
653     break;
654   }
655   *cont = false;
656   HandshakeCanBeCanceled_eventCount = delegate->handshake_events;
657 }
658 
TEST_F(InspectorSocketTest,HandshakeCanBeCanceled)659 TEST_F(InspectorSocketTest, HandshakeCanBeCanceled) {
660   delegate->SetDelegate(HandshakeCanBeCanceled_handshake);
661 
662   do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
663 
664   expect_handshake_failure();
665   EXPECT_EQ(1, HandshakeCanBeCanceled_eventCount);
666   EXPECT_EQ(nullptr, delegate);
667 }
668 
GetThenHandshake_handshake(enum inspector_handshake_event state,const std::string & path,bool * cont)669 static void GetThenHandshake_handshake(enum inspector_handshake_event state,
670                                        const std::string& path, bool* cont) {
671   *cont = true;
672   std::string expected_path = "/ws/path";
673   switch (delegate->handshake_events - 1) {
674   case 0:
675     EXPECT_EQ(kInspectorHandshakeHttpGet, state);
676     expected_path = "/respond/withtext";
677     delegate->Write(TEST_SUCCESS, sizeof(TEST_SUCCESS) - 1);
678     break;
679   case 1:
680     EXPECT_EQ(kInspectorHandshakeUpgraded, state);
681     break;
682   default:
683     EXPECT_TRUE(false);
684     break;
685   }
686   EXPECT_EQ(expected_path, path);
687 }
688 
TEST_F(InspectorSocketTest,GetThenHandshake)689 TEST_F(InspectorSocketTest, GetThenHandshake) {
690   delegate->SetDelegate(GetThenHandshake_handshake);
691   const char WRITE_REQUEST[] = "GET /respond/withtext HTTP/1.1\r\n"
692                                "Host: localhost:9229\r\n\r\n";
693   send_in_chunks(WRITE_REQUEST, sizeof(WRITE_REQUEST) - 1);
694 
695   expect_on_client(TEST_SUCCESS, sizeof(TEST_SUCCESS) - 1);
696 
697   do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
698   expect_handshake();
699   EXPECT_EQ(2, delegate->handshake_events);
700 }
701 
TEST_F(InspectorSocketTest,WriteBeforeHandshake)702 TEST_F(InspectorSocketTest, WriteBeforeHandshake) {
703   const char MESSAGE1[] = "Message 1";
704   const char MESSAGE2[] = "Message 2";
705   const char EXPECTED[] = "Message 1Message 2";
706 
707   delegate->Write(MESSAGE1, sizeof(MESSAGE1) - 1);
708   delegate->Write(MESSAGE2, sizeof(MESSAGE2) - 1);
709   expect_on_client(EXPECTED, sizeof(EXPECTED) - 1);
710   really_close(reinterpret_cast<uv_handle_t*>(&client_socket));
711   SPIN_WHILE(delegate != nullptr);
712 }
713 
TEST_F(InspectorSocketTest,CleanupSocketAfterEOF)714 TEST_F(InspectorSocketTest, CleanupSocketAfterEOF) {
715   do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
716   expect_handshake();
717 
718   for (int i = 0; i < MAX_LOOP_ITERATIONS; ++i) {
719     uv_run(&loop, UV_RUN_NOWAIT);
720   }
721 
722   uv_close(reinterpret_cast<uv_handle_t*>(&client_socket), nullptr);
723   SPIN_WHILE(delegate != nullptr);
724 }
725 
TEST_F(InspectorSocketTest,EOFBeforeHandshake)726 TEST_F(InspectorSocketTest, EOFBeforeHandshake) {
727   const char MESSAGE[] = "We'll send EOF afterwards";
728   delegate->Write(MESSAGE, sizeof(MESSAGE) - 1);
729   expect_on_client(MESSAGE, sizeof(MESSAGE) - 1);
730   uv_close(reinterpret_cast<uv_handle_t*>(&client_socket), nullptr);
731   SPIN_WHILE(delegate != nullptr);
732 }
733 
fill_message(std::string * buffer)734 static void fill_message(std::string* buffer) {
735   for (size_t i = 0; i < buffer->size(); i += 1) {
736     (*buffer)[i] = 'a' + (i % ('z' - 'a'));
737   }
738 }
739 
mask_message(const std::string & message,char * buffer,const char mask[])740 static void mask_message(const std::string& message,
741                          char* buffer, const char mask[]) {
742   const size_t mask_len = 4;
743   for (size_t i = 0; i < message.size(); i += 1) {
744     buffer[i] = message[i] ^ mask[i % mask_len];
745   }
746 }
747 
TEST_F(InspectorSocketTest,Send1Mb)748 TEST_F(InspectorSocketTest, Send1Mb) {
749   ASSERT_TRUE(connected);
750   ASSERT_FALSE(delegate->inspector_ready);
751   do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
752   SPIN_WHILE(!delegate->inspector_ready);
753   expect_handshake();
754 
755   // 2. Brief exchange
756   std::string message(1000000, '\0');
757   fill_message(&message);
758 
759   // 1000000 is 0xF4240 hex
760   const char EXPECTED_FRAME_HEADER[] = {
761     '\x81', '\x7f', '\x00', '\x00', '\x00', '\x00', '\x00', '\x0F',
762     '\x42', '\x40'
763   };
764   std::string expected(EXPECTED_FRAME_HEADER, sizeof(EXPECTED_FRAME_HEADER));
765   expected.append(message);
766 
767   delegate->Write(&message[0], message.size());
768   expect_on_client(&expected[0], expected.size());
769 
770   char MASK[4] = {'W', 'h', 'O', 'a'};
771 
772   const char FRAME_TO_SERVER_HEADER[] = {
773     '\x81', '\xff', '\x00', '\x00', '\x00', '\x00', '\x00', '\x0F',
774     '\x42', '\x40', MASK[0], MASK[1], MASK[2], MASK[3]
775   };
776 
777   std::string outgoing(FRAME_TO_SERVER_HEADER, sizeof(FRAME_TO_SERVER_HEADER));
778   outgoing.resize(outgoing.size() + message.size());
779   mask_message(message, &outgoing[sizeof(FRAME_TO_SERVER_HEADER)], MASK);
780 
781   do_write(&outgoing[0], outgoing.size());
782   delegate->ExpectData(&message[0], message.size());
783 
784   // 3. Close
785   const char CLIENT_CLOSE_FRAME[] = {'\x88', '\x80', '\x2D',
786                                      '\x0E', '\x1E', '\xFA'};
787   do_write(CLIENT_CLOSE_FRAME, sizeof(CLIENT_CLOSE_FRAME));
788   expect_on_client(SERVER_CLOSE_FRAME, sizeof(SERVER_CLOSE_FRAME));
789   GTEST_ASSERT_EQ(0, uv_is_active(
790                          reinterpret_cast<uv_handle_t*>(&client_socket)));
791 }
792 
TEST_F(InspectorSocketTest,ErrorCleansUpTheSocket)793 TEST_F(InspectorSocketTest, ErrorCleansUpTheSocket) {
794   do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
795   expect_handshake();
796   const char NOT_A_GOOD_FRAME[] = {'H', 'e', 'l', 'l', 'o'};
797   do_write(NOT_A_GOOD_FRAME, sizeof(NOT_A_GOOD_FRAME));
798   SPIN_WHILE(delegate != nullptr);
799 }
800 
TEST_F(InspectorSocketTest,NoCloseResponseFromClient)801 TEST_F(InspectorSocketTest, NoCloseResponseFromClient) {
802   ASSERT_TRUE(connected);
803   ASSERT_FALSE(delegate->inspector_ready);
804   do_write(const_cast<char*>(HANDSHAKE_REQ), sizeof(HANDSHAKE_REQ) - 1);
805   SPIN_WHILE(!delegate->inspector_ready);
806   expect_handshake();
807 
808   // 2. Brief exchange
809   const char SERVER_MESSAGE[] = "abcd";
810   const char CLIENT_FRAME[] = {'\x81', '\x04', 'a', 'b', 'c', 'd'};
811   delegate->Write(SERVER_MESSAGE, sizeof(SERVER_MESSAGE) - 1);
812   expect_on_client(CLIENT_FRAME, sizeof(CLIENT_FRAME));
813 
814   delegate->Close();
815   expect_on_client(SERVER_CLOSE_FRAME, sizeof(SERVER_CLOSE_FRAME));
816   uv_close(reinterpret_cast<uv_handle_t*>(&client_socket), nullptr);
817   GTEST_ASSERT_EQ(0, uv_is_active(
818                   reinterpret_cast<uv_handle_t*>(&client_socket)));
819   delegate->WaitForDispose();
820 }
821 
822 static bool delegate_called = false;
823 
shouldnt_be_called(enum inspector_handshake_event state,const std::string & path,bool * cont)824 void shouldnt_be_called(enum inspector_handshake_event state,
825                         const std::string& path, bool* cont) {
826   delegate_called = true;
827 }
828 
expect_failure_no_delegate(const std::string & request)829 void expect_failure_no_delegate(const std::string& request) {
830   delegate->SetDelegate(shouldnt_be_called);
831   delegate_called = false;
832   send_in_chunks(request.c_str(), request.length());
833   expect_handshake_failure();
834   SPIN_WHILE(delegate != nullptr);
835   ASSERT_FALSE(delegate_called);
836 }
837 
TEST_F(InspectorSocketTest,HostCheckedForGET)838 TEST_F(InspectorSocketTest, HostCheckedForGET) {
839   const char GET_REQUEST[] = "GET /respond/withtext HTTP/1.1\r\n"
840                              "Host: notlocalhost:9229\r\n\r\n";
841   expect_failure_no_delegate(GET_REQUEST);
842 }
843 
TEST_F(InspectorSocketTest,HostCheckedForUPGRADE)844 TEST_F(InspectorSocketTest, HostCheckedForUPGRADE) {
845   const char UPGRADE_REQUEST[] = "GET /ws/path HTTP/1.1\r\n"
846                                  "Host: nonlocalhost:9229\r\n"
847                                  "Upgrade: websocket\r\n"
848                                  "Connection: Upgrade\r\n"
849                                  "Sec-WebSocket-Key: aaa==\r\n"
850                                  "Sec-WebSocket-Version: 13\r\n\r\n";
851   expect_failure_no_delegate(UPGRADE_REQUEST);
852 }
853 
TEST_F(InspectorSocketTest,HostIPChecked)854 TEST_F(InspectorSocketTest, HostIPChecked) {
855   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
856                                               "Host: 10.0.2.555:9229\r\n\r\n";
857   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
858                  INVALID_HOST_IP_REQUEST.length());
859   expect_handshake_failure();
860 }
861 
TEST_F(InspectorSocketTest,HostNegativeIPChecked)862 TEST_F(InspectorSocketTest, HostNegativeIPChecked) {
863   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
864                                               "Host: 10.0.-23.255:9229\r\n\r\n";
865   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
866                  INVALID_HOST_IP_REQUEST.length());
867   expect_handshake_failure();
868 }
869 
TEST_F(InspectorSocketTest,HostIpOctetOutOfIntRangeChecked)870 TEST_F(InspectorSocketTest, HostIpOctetOutOfIntRangeChecked) {
871   const std::string INVALID_HOST_IP_REQUEST =
872       "GET /json HTTP/1.1\r\n"
873       "Host: 127.0.0.4294967296:9229\r\n\r\n";
874   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
875                  INVALID_HOST_IP_REQUEST.length());
876   expect_handshake_failure();
877 }
878 
TEST_F(InspectorSocketTest,HostIpOctetFarOutOfIntRangeChecked)879 TEST_F(InspectorSocketTest, HostIpOctetFarOutOfIntRangeChecked) {
880   const std::string INVALID_HOST_IP_REQUEST =
881       "GET /json HTTP/1.1\r\n"
882       "Host: 127.0.0.18446744073709552000:9229\r\n\r\n";
883   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
884                  INVALID_HOST_IP_REQUEST.length());
885   expect_handshake_failure();
886 }
887 
TEST_F(InspectorSocketTest,HostIpEmptyOctetStartChecked)888 TEST_F(InspectorSocketTest, HostIpEmptyOctetStartChecked) {
889   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
890                                               "Host: .0.0.1:9229\r\n\r\n";
891   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
892                  INVALID_HOST_IP_REQUEST.length());
893   expect_handshake_failure();
894 }
895 
TEST_F(InspectorSocketTest,HostIpEmptyOctetMidChecked)896 TEST_F(InspectorSocketTest, HostIpEmptyOctetMidChecked) {
897   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
898                                               "Host: 127..0.1:9229\r\n\r\n";
899   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
900                  INVALID_HOST_IP_REQUEST.length());
901   expect_handshake_failure();
902 }
903 
TEST_F(InspectorSocketTest,HostIpEmptyOctetEndChecked)904 TEST_F(InspectorSocketTest, HostIpEmptyOctetEndChecked) {
905   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
906                                               "Host: 127.0.0.:9229\r\n\r\n";
907   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
908                  INVALID_HOST_IP_REQUEST.length());
909   expect_handshake_failure();
910 }
911 
TEST_F(InspectorSocketTest,HostIpTooFewOctetsChecked)912 TEST_F(InspectorSocketTest, HostIpTooFewOctetsChecked) {
913   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
914                                               "Host: 127.0.1:9229\r\n\r\n";
915   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
916                  INVALID_HOST_IP_REQUEST.length());
917   expect_handshake_failure();
918 }
919 
TEST_F(InspectorSocketTest,HostIpTooManyOctetsChecked)920 TEST_F(InspectorSocketTest, HostIpTooManyOctetsChecked) {
921   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
922                                               "Host: 127.0.0.0.1:9229\r\n\r\n";
923   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
924                  INVALID_HOST_IP_REQUEST.length());
925   expect_handshake_failure();
926 }
927 
TEST_F(InspectorSocketTest,HostIpInvalidOctalOctetStartChecked)928 TEST_F(InspectorSocketTest, HostIpInvalidOctalOctetStartChecked) {
929   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
930                                               "Host: 08.1.1.1:9229\r\n\r\n";
931   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
932                  INVALID_HOST_IP_REQUEST.length());
933   expect_handshake_failure();
934 }
935 
TEST_F(InspectorSocketTest,HostIpInvalidOctalOctetMidChecked)936 TEST_F(InspectorSocketTest, HostIpInvalidOctalOctetMidChecked) {
937   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
938                                               "Host: 1.09.1.1:9229\r\n\r\n";
939   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
940                  INVALID_HOST_IP_REQUEST.length());
941   expect_handshake_failure();
942 }
943 
TEST_F(InspectorSocketTest,HostIpInvalidOctalOctetEndChecked)944 TEST_F(InspectorSocketTest, HostIpInvalidOctalOctetEndChecked) {
945   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
946                                               "Host: 1.1.1.009:9229\r\n\r\n";
947   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
948                  INVALID_HOST_IP_REQUEST.length());
949   expect_handshake_failure();
950 }
951 
TEST_F(InspectorSocketTest,HostIpLeadingZeroStartChecked)952 TEST_F(InspectorSocketTest, HostIpLeadingZeroStartChecked) {
953   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
954                                               "Host: 01.1.1.1:9229\r\n\r\n";
955   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
956                  INVALID_HOST_IP_REQUEST.length());
957   expect_handshake_failure();
958 }
959 
TEST_F(InspectorSocketTest,HostIpLeadingZeroMidChecked)960 TEST_F(InspectorSocketTest, HostIpLeadingZeroMidChecked) {
961   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
962                                               "Host: 1.1.001.1:9229\r\n\r\n";
963   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
964                  INVALID_HOST_IP_REQUEST.length());
965   expect_handshake_failure();
966 }
967 
TEST_F(InspectorSocketTest,HostIpLeadingZeroEndChecked)968 TEST_F(InspectorSocketTest, HostIpLeadingZeroEndChecked) {
969   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
970                                               "Host: 1.1.1.01:9229\r\n\r\n";
971   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
972                  INVALID_HOST_IP_REQUEST.length());
973   expect_handshake_failure();
974 }
975 
TEST_F(InspectorSocketTest,HostIPNonRoutable)976 TEST_F(InspectorSocketTest, HostIPNonRoutable) {
977   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
978                                               "Host: 0.0.0.0:9229\r\n\r\n";
979   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
980                  INVALID_HOST_IP_REQUEST.length());
981   expect_handshake_failure();
982 }
983 
TEST_F(InspectorSocketTest,HostIPv6NonRoutable)984 TEST_F(InspectorSocketTest, HostIPv6NonRoutable) {
985   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
986                                               "Host: [::]:9229\r\n\r\n";
987   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
988                  INVALID_HOST_IP_REQUEST.length());
989   expect_handshake_failure();
990 }
991 
TEST_F(InspectorSocketTest,HostIPv6NonRoutableDual)992 TEST_F(InspectorSocketTest, HostIPv6NonRoutableDual) {
993   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
994                                               "Host: [::0.0.0.0]:9229\r\n\r\n";
995   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
996                  INVALID_HOST_IP_REQUEST.length());
997   expect_handshake_failure();
998 }
999 
TEST_F(InspectorSocketTest,HostIPv4InSquareBrackets)1000 TEST_F(InspectorSocketTest, HostIPv4InSquareBrackets) {
1001   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
1002                                               "Host: [127.0.0.1]:9229\r\n\r\n";
1003   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
1004                  INVALID_HOST_IP_REQUEST.length());
1005   expect_handshake_failure();
1006 }
1007 
TEST_F(InspectorSocketTest,HostIPv6InvalidAbbreviation)1008 TEST_F(InspectorSocketTest, HostIPv6InvalidAbbreviation) {
1009   const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
1010                                               "Host: [:::1]:9229\r\n\r\n";
1011   send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
1012                  INVALID_HOST_IP_REQUEST.length());
1013   expect_handshake_failure();
1014 }
1015 
1016 }  // anonymous namespace
1017