1 /*
2   +----------------------------------------------------------------------+
3   | Swoole                                                               |
4   +----------------------------------------------------------------------+
5   | This source file is subject to version 2.0 of the Apache license,    |
6   | that is bundled with this package in the file LICENSE, and is        |
7   | available through the world-wide-web at the following url:           |
8   | http://www.apache.org/licenses/LICENSE-2.0.html                      |
9   | If you did not receive a copy of the Apache2.0 license and are unable|
10   | to obtain it through the world-wide-web, please send a note to       |
11   | license@swoole.com so we can mail you a copy immediately.            |
12   +----------------------------------------------------------------------+
13   | @link     https://www.swoole.com/                                    |
14   | @contact  team@swoole.com                                            |
15   | @license  https://github.com/swoole/swoole-src/blob/master/LICENSE   |
16   | @author   Tianfeng Han  <mikan.tenny@gmail.com>                      |
17   +----------------------------------------------------------------------+
18 */
19 
20 #include "test_process.h"
21 #include "test_coroutine.h"
22 #include "test_server.h"
23 
24 using namespace swoole::test;
25 
26 using swoole::Protocol;
27 using swoole::String;
28 using swoole::coroutine::Socket;
29 using swoole::coroutine::System;
30 using swoole::test::Server;
31 
TEST(coroutine_socket,connect_refused)32 TEST(coroutine_socket, connect_refused) {
33     coroutine::run([](void *arg) {
34         Socket sock(SW_SOCK_TCP);
35         bool retval = sock.connect("127.0.0.1", 9801);
36         ASSERT_EQ(retval, false);
37         ASSERT_EQ(sock.errCode, ECONNREFUSED);
38     });
39 }
40 
TEST(coroutine_socket,connect_timeout)41 TEST(coroutine_socket, connect_timeout) {
42     coroutine::run([](void *arg) {
43         Socket sock(SW_SOCK_TCP);
44         sock.set_timeout(0.5);
45         bool retval = sock.connect("192.0.0.1", 9801);
46         ASSERT_EQ(retval, false);
47         ASSERT_EQ(sock.errCode, ETIMEDOUT);
48     });
49 }
50 
TEST(coroutine_socket,connect_with_dns)51 TEST(coroutine_socket, connect_with_dns) {
52     coroutine::run([](void *arg) {
53         Socket sock(SW_SOCK_TCP);
54         bool retval = sock.connect("www.baidu.com", 80);
55         ASSERT_EQ(retval, true);
56         ASSERT_EQ(sock.errCode, 0);
57     });
58 }
59 
TEST(coroutine_socket,recv_success)60 TEST(coroutine_socket, recv_success) {
61     pid_t pid;
62 
63     Process proc([](Process *proc) {
64         on_receive_lambda_type receive_fn = [](ON_RECEIVE_PARAMS) {
65             SERVER_THIS->send(req->info.fd, req->data, req->info.len);
66         };
67 
68         Server serv(TEST_HOST, TEST_PORT, swoole::Server::MODE_BASE, SW_SOCK_TCP);
69         serv.on("onReceive", (void *) receive_fn);
70         serv.start();
71     });
72 
73     pid = proc.start();
74 
75     sleep(1);  // wait for the test server to start
76 
77     coroutine::run([](void *arg) {
78         Socket sock(SW_SOCK_TCP);
79         bool retval = sock.connect(TEST_HOST, TEST_PORT, -1);
80         ASSERT_EQ(retval, true);
81         ASSERT_EQ(sock.errCode, 0);
82         sock.send(SW_STRS("hello world\n"));
83         char buf[128];
84         int n = sock.recv(buf, sizeof(buf));
85         buf[n] = 0;
86         ASSERT_EQ(strcmp(buf, "hello world\n"), 0);
87     });
88 
89     kill(pid, SIGTERM);
90     int status;
91     wait(&status);
92 }
93 
TEST(coroutine_socket,recv_fail)94 TEST(coroutine_socket, recv_fail) {
95     pid_t pid;
96 
97     Process proc([](Process *proc) {
98         on_receive_lambda_type receive_fn = [](ON_RECEIVE_PARAMS) { SERVER_THIS->close(req->info.fd, 0); };
99 
100         Server serv(TEST_HOST, TEST_PORT, swoole::Server::MODE_BASE, SW_SOCK_TCP);
101         serv.on("onReceive", (void *) receive_fn);
102         serv.start();
103     });
104 
105     pid = proc.start();
106 
107     sleep(1);  // wait for the test server to start
108 
109     coroutine::run([](void *arg) {
110         Socket sock(SW_SOCK_TCP);
111         bool retval = sock.connect(TEST_HOST, TEST_PORT, -1);
112         ASSERT_EQ(retval, true);
113         ASSERT_EQ(sock.errCode, 0);
114         sock.send("close", 6);
115         char buf[128];
116         int n = sock.recv(buf, sizeof(buf));
117         ASSERT_EQ(n, 0);
118     });
119 
120     kill(pid, SIGTERM);
121     int status;
122     wait(&status);
123 }
124 
TEST(coroutine_socket,bind_success)125 TEST(coroutine_socket, bind_success) {
126     coroutine::run([](void *arg) {
127         Socket sock(SW_SOCK_TCP);
128         bool retval = sock.bind("127.0.0.1", 9909);
129         ASSERT_EQ(retval, true);
130     });
131 }
132 
TEST(coroutine_socket,bind_fail)133 TEST(coroutine_socket, bind_fail) {
134     coroutine::run([](void *arg) {
135         Socket sock(SW_SOCK_TCP);
136         bool retval = sock.bind("192.111.11.1", 9909);
137         ASSERT_EQ(retval, false);
138         ASSERT_EQ(sock.errCode, EADDRNOTAVAIL);
139     });
140 }
141 
TEST(coroutine_socket,listen)142 TEST(coroutine_socket, listen) {
143     coroutine::run([](void *arg) {
144         Socket sock(SW_SOCK_TCP);
145         bool retval = sock.bind("127.0.0.1", 9909);
146         ASSERT_EQ(retval, true);
147         ASSERT_EQ(sock.listen(128), true);
148     });
149 }
150 
TEST(coroutine_socket,accept)151 TEST(coroutine_socket, accept) {
152     coroutine::run({[](void *arg) {
153                         Socket sock(SW_SOCK_TCP);
154                         bool retval = sock.bind("127.0.0.1", 9909);
155                         ASSERT_EQ(retval, true);
156                         ASSERT_EQ(sock.listen(128), true);
157 
158                         Socket *conn = sock.accept();
159                         ASSERT_NE(conn, nullptr);
160                     },
161 
162                     [](void *arg) {
163                         Socket sock(SW_SOCK_TCP);
164                         bool retval = sock.connect("127.0.0.1", 9909, -1);
165                         ASSERT_EQ(retval, true);
166                         ASSERT_EQ(sock.errCode, 0);
167                         sock.close();
168                     }});
169 }
170 
171 #define CRLF "\r\n"
172 #define EOF_PACKET "hello world" CRLF
173 #define EOF_PACKET_2 "php&swoole, java&golang" CRLF
174 #define RECV_TIMEOUT 10.0
175 
socket_set_eof_protocol(Socket & sock)176 static void socket_set_eof_protocol(Socket &sock) {
177     memcpy(sock.protocol.package_eof, SW_STRL(CRLF));
178     sock.protocol.package_eof_len = 2;
179     sock.open_eof_check = true;
180 }
181 
TEST(coroutine_socket,eof_1)182 TEST(coroutine_socket, eof_1) {
183     coroutine::run({[](void *arg) {
184                         Socket sock(SW_SOCK_TCP);
185                         bool retval = sock.bind("127.0.0.1", 9909);
186                         ASSERT_EQ(retval, true);
187                         ASSERT_EQ(sock.listen(128), true);
188 
189                         Socket *conn = sock.accept();
190                         char buf[1024];
191                         ssize_t l = conn->recv(buf, sizeof(buf));
192                         EXPECT_EQ(string(buf, l), string("start\r\n"));
193                         conn->send(EOF_PACKET);
194                     },
195 
196                     [](void *arg) {
197                         Socket sock(SW_SOCK_TCP);
198                         bool retval = sock.connect("127.0.0.1", 9909, -1);
199                         ASSERT_EQ(retval, true);
200                         ASSERT_EQ(sock.errCode, 0);
201                         sock.send("start\r\n");
202 
203                         socket_set_eof_protocol(sock);
204 
205                         ssize_t l = sock.recv_packet(RECV_TIMEOUT);
206                         size_t eof_packet_len = strlen(EOF_PACKET);
207                         auto buf = sock.get_read_buffer();
208 
209                         ASSERT_EQ(l, eof_packet_len);
210                         ASSERT_EQ(string(buf->str, l), string(EOF_PACKET));
211                         ASSERT_EQ(buf->length, eof_packet_len);
212                         ASSERT_EQ(buf->offset, eof_packet_len);
213                     }});
214 }
215 
TEST(coroutine_socket,eof_2)216 TEST(coroutine_socket, eof_2) {
217     coroutine::run({[](void *arg) {
218                         Socket sock(SW_SOCK_TCP);
219                         bool retval = sock.bind("127.0.0.1", 9909);
220                         ASSERT_EQ(retval, true);
221                         ASSERT_EQ(sock.listen(128), true);
222 
223                         Socket *conn = sock.accept();
224                         char buf[1024];
225                         ssize_t l = conn->recv(buf, sizeof(buf));
226                         EXPECT_EQ(string(buf, l), string("start\r\n"));
227                         conn->send(EOF_PACKET EOF_PACKET_2);
228                     },
229 
230                     [](void *arg) {
231                         Socket sock(SW_SOCK_TCP);
232                         bool retval = sock.connect("127.0.0.1", 9909, -1);
233                         ASSERT_EQ(retval, true);
234                         ASSERT_EQ(sock.errCode, 0);
235                         sock.send("start\r\n");
236 
237                         socket_set_eof_protocol(sock);
238 
239                         // packet 1
240                         {
241                             ssize_t l = sock.recv_packet(RECV_TIMEOUT);
242                             size_t eof_packet_len = strlen(EOF_PACKET);
243                             auto buf = sock.get_read_buffer();
244 
245                             ASSERT_EQ(l, eof_packet_len);
246                             ASSERT_EQ(string(buf->str, l), string(EOF_PACKET));
247                             ASSERT_EQ(buf->length, strlen(EOF_PACKET EOF_PACKET_2));
248                             ASSERT_EQ(buf->offset, eof_packet_len);
249                         }
250                         // packet 2
251                         {
252                             ssize_t l = sock.recv_packet(RECV_TIMEOUT);
253                             size_t eof_packet_len = strlen(EOF_PACKET_2);
254                             auto buf = sock.get_read_buffer();
255 
256                             ASSERT_EQ(l, eof_packet_len);
257                             ASSERT_EQ(string(buf->str, l), string(EOF_PACKET_2));
258                             ASSERT_EQ(buf->length, strlen(EOF_PACKET_2));
259                             ASSERT_EQ(buf->offset, eof_packet_len);
260                         }
261                     }});
262 }
263 
TEST(coroutine_socket,eof_3)264 TEST(coroutine_socket, eof_3) {
265     coroutine::run({[](void *arg) {
266                         Socket sock(SW_SOCK_TCP);
267                         bool retval = sock.bind("127.0.0.1", 9909);
268                         ASSERT_EQ(retval, true);
269                         ASSERT_EQ(sock.listen(128), true);
270 
271                         Socket *conn = sock.accept();
272                         char buf[1024];
273                         ssize_t l = conn->recv(buf, sizeof(buf));
274                         EXPECT_EQ(string(buf, l), string("start\r\n"));
275                         conn->shutdown();
276                     },
277 
278                     [](void *arg) {
279                         Socket sock(SW_SOCK_TCP);
280                         bool retval = sock.connect("127.0.0.1", 9909, -1);
281                         ASSERT_EQ(retval, true);
282                         ASSERT_EQ(sock.errCode, 0);
283                         sock.send("start\r\n");
284 
285                         socket_set_eof_protocol(sock);
286 
287                         ssize_t l = sock.recv_packet(RECV_TIMEOUT);
288                         ASSERT_EQ(l, 0);
289                     }});
290 }
291 
TEST(coroutine_socket,eof_4)292 TEST(coroutine_socket, eof_4) {
293     coroutine::run({[](void *arg) {
294                         Socket sock(SW_SOCK_TCP);
295                         bool retval = sock.bind("127.0.0.1", 9909);
296                         ASSERT_EQ(retval, true);
297                         ASSERT_EQ(sock.listen(128), true);
298 
299                         Socket *conn = sock.accept();
300                         char buf[1024];
301                         ssize_t l = conn->recv(buf, sizeof(buf));
302                         EXPECT_EQ(string(buf, l), string("start\r\n"));
303                         conn->send(EOF_PACKET, strlen(EOF_PACKET) - strlen(CRLF));  // no eof
304                         conn->shutdown();
305                     },
306 
307                     [](void *arg) {
308                         Socket sock(SW_SOCK_TCP);
309                         bool retval = sock.connect("127.0.0.1", 9909, -1);
310                         ASSERT_EQ(retval, true);
311                         ASSERT_EQ(sock.errCode, 0);
312                         sock.send("start\r\n");
313 
314                         socket_set_eof_protocol(sock);
315 
316                         ssize_t l = sock.recv_packet(RECV_TIMEOUT);
317                         ASSERT_EQ(l, 0);
318 
319                         auto buf = sock.get_read_buffer();
320                         ASSERT_EQ(string(buf->str, 10), string(EOF_PACKET, 10));
321                     }});
322 }
323 
TEST(coroutine_socket,eof_5)324 TEST(coroutine_socket, eof_5) {
325     coroutine::run({[](void *arg) {
326                         Socket sock(SW_SOCK_TCP);
327                         bool retval = sock.bind("127.0.0.1", 9909);
328                         ASSERT_EQ(retval, true);
329                         ASSERT_EQ(sock.listen(128), true);
330 
331                         Socket *conn = sock.accept();
332                         char buf[1024];
333                         ssize_t l = conn->recv(buf, sizeof(buf));
334                         EXPECT_EQ(string(buf, l), string("start\r\n"));
335 
336                         swString *s = swoole::make_string(128 * 1024);
337                         s->repeat("A", 1, 128 * 1024 - 16);
338                         s->append(SW_STRL(CRLF));
339 
340                         conn->send_all(s->str, s->length);
341                     },
342 
343                     [](void *arg) {
344                         Socket sock(SW_SOCK_TCP);
345                         bool retval = sock.connect("127.0.0.1", 9909, -1);
346                         ASSERT_EQ(retval, true);
347                         ASSERT_EQ(sock.errCode, 0);
348                         sock.send("start\r\n");
349 
350                         socket_set_eof_protocol(sock);
351 
352                         ssize_t l = sock.recv_packet(RECV_TIMEOUT);
353                         ASSERT_EQ(l, 128 * 1024 - 14);
354                     }});
355 }
356 
TEST(coroutine_socket,eof_6)357 TEST(coroutine_socket, eof_6) {
358     coroutine::run({[](void *arg) {
359                         Socket sock(SW_SOCK_TCP);
360                         bool retval = sock.bind("127.0.0.1", 9909);
361                         ASSERT_EQ(retval, true);
362                         ASSERT_EQ(sock.listen(128), true);
363 
364                         Socket *conn = sock.accept();
365                         char buf[1024];
366                         ssize_t l = conn->recv(buf, sizeof(buf));
367                         EXPECT_EQ(string(buf, l), string("start\r\n"));
368 
369                         swString s(128 * 1024);
370                         s.repeat("A", 1, 128 * 1024 - 16);
371                         s.append(SW_STRL(CRLF));
372 
373                         conn->send_all(s.value(), s.get_length());
374                     },
375 
376                     [](void *arg) {
377                         Socket sock(SW_SOCK_TCP);
378                         bool retval = sock.connect("127.0.0.1", 9909, -1);
379                         ASSERT_EQ(retval, true);
380                         ASSERT_EQ(sock.errCode, 0);
381                         sock.send("start\r\n");
382 
383                         socket_set_eof_protocol(sock);
384                         sock.protocol.package_max_length = 1024 * 64;
385 
386                         ssize_t l = sock.recv_packet(RECV_TIMEOUT);
387                         ASSERT_EQ(l, -1);
388                         ASSERT_EQ(sock.errCode, SW_ERROR_PACKAGE_LENGTH_TOO_LARGE);
389                     }});
390 }
391 
socket_set_length_protocol_1(Socket & sock)392 static void socket_set_length_protocol_1(Socket &sock) {
393     sock.protocol = {};
394 
395     sock.protocol.package_length_type = 'n';
396     sock.protocol.package_length_size = swoole_type_size(sock.protocol.package_length_type);
397     sock.protocol.package_body_offset = 2;
398     sock.protocol.get_package_length = Protocol::default_length_func;
399     sock.protocol.package_max_length = 65535;
400 
401     sock.open_length_check = true;
402 }
403 
socket_set_length_protocol_2(Socket & sock)404 static void socket_set_length_protocol_2(Socket &sock) {
405     sock.protocol = {};
406 
407     sock.protocol.package_length_type = 'N';
408     sock.protocol.package_length_size = swoole_type_size(sock.protocol.package_length_type);
409     sock.protocol.package_body_offset = 4;
410     sock.protocol.get_package_length = Protocol::default_length_func;
411     sock.protocol.package_max_length = 2 * 1024 * 1024;
412 
413     sock.open_length_check = true;
414 }
415 
TEST(coroutine_socket,length_1)416 TEST(coroutine_socket, length_1) {
417     coroutine::run({[](void *arg) {
418                         Socket sock(SW_SOCK_TCP);
419                         bool retval = sock.bind("127.0.0.1", 9502);
420                         ASSERT_EQ(retval, true);
421                         ASSERT_EQ(sock.listen(128), true);
422 
423                         Socket *conn = sock.accept();
424                         char buf[1024];
425                         ssize_t l = swoole_random_bytes(buf + 2, sizeof(buf) - 2);
426                         *(uint16_t *) buf = htons(l);
427 
428                         conn->send(buf, l + 2);
429                     },
430 
431                     [](void *arg) {
432                         Socket sock(SW_SOCK_TCP);
433                         bool retval = sock.connect("127.0.0.1", 9502, -1);
434                         ASSERT_EQ(retval, true);
435                         ASSERT_EQ(sock.errCode, 0);
436 
437                         socket_set_length_protocol_1(sock);
438 
439                         ssize_t l = sock.recv_packet(RECV_TIMEOUT);
440                         auto buf = sock.get_read_buffer();
441 
442                         ASSERT_EQ(l, 1024);
443                         ASSERT_EQ(buf->length, l);
444                         ASSERT_EQ(buf->offset, l);
445                     }});
446 }
447 
TEST(coroutine_socket,length_2)448 TEST(coroutine_socket, length_2) {
449     coroutine::run({[](void *arg) {
450                         Socket sock(SW_SOCK_TCP);
451                         bool retval = sock.bind("127.0.0.1", 9502);
452                         ASSERT_EQ(retval, true);
453                         ASSERT_EQ(sock.listen(128), true);
454 
455                         Socket *conn = sock.accept();
456                         char buf[1024];
457                         *(uint16_t *) buf = htons(0);
458 
459                         conn->send(buf, 2);
460                     },
461 
462                     [](void *arg) {
463                         Socket sock(SW_SOCK_TCP);
464                         bool retval = sock.connect("127.0.0.1", 9502, -1);
465                         ASSERT_EQ(retval, true);
466                         ASSERT_EQ(sock.errCode, 0);
467 
468                         socket_set_length_protocol_1(sock);
469 
470                         ssize_t l = sock.recv_packet(RECV_TIMEOUT);
471                         auto buf = sock.get_read_buffer();
472 
473                         ASSERT_EQ(l, 2);
474                         ASSERT_EQ(buf->length, 2);
475                         ASSERT_EQ(buf->offset, 2);
476                     }});
477 }
478 
TEST(coroutine_socket,length_3)479 TEST(coroutine_socket, length_3) {
480     coroutine::run({[](void *arg) {
481                         Socket sock(SW_SOCK_TCP);
482                         bool retval = sock.bind("127.0.0.1", 9502);
483                         ASSERT_EQ(retval, true);
484                         ASSERT_EQ(sock.listen(128), true);
485 
486                         Socket *conn = sock.accept();
487                         char buf[1024];
488                         memset(buf, 'A', sizeof(buf));
489                         *(uint16_t *) buf = htons(65530);
490 
491                         conn->send(buf, sizeof(buf));
492                     },
493 
494                     [](void *arg) {
495                         Socket sock(SW_SOCK_TCP);
496                         bool retval = sock.connect("127.0.0.1", 9502, -1);
497                         ASSERT_EQ(retval, true);
498                         ASSERT_EQ(sock.errCode, 0);
499 
500                         socket_set_length_protocol_1(sock);
501                         sock.protocol.package_max_length = 4096;
502 
503                         ssize_t l = sock.recv_packet(RECV_TIMEOUT);
504                         ASSERT_EQ(l, -1);
505                         ASSERT_EQ(sock.errCode, SW_ERROR_PACKAGE_LENGTH_TOO_LARGE);
506                     }});
507 }
508 
509 static string pkt_1;
510 static string pkt_2;
511 
length_protocol_server_func(void * arg)512 static void length_protocol_server_func(void *arg) {
513     Socket sock(SW_SOCK_TCP);
514     bool retval = sock.bind("127.0.0.1", 9502);
515     ASSERT_EQ(retval, true);
516     ASSERT_EQ(sock.listen(128), true);
517 
518     Socket *conn = sock.accept();
519     String strbuf(256 * 1024);
520 
521     uint32_t pack_len;
522 
523     size_t l_1 = swoole_rand(65536, 65536 * 2);
524     pack_len = htonl(l_1);
525     strbuf.append((char *) &pack_len, sizeof(pack_len));
526     strbuf.append_random_bytes(l_1);
527 
528     pkt_1 = string(strbuf.str, l_1 + 4);
529 
530     size_t l_2 = swoole_rand(65536, 65536 * 2);
531     pack_len = htonl(l_2);
532     strbuf.append((char *) &pack_len, sizeof(pack_len));
533     strbuf.append_random_bytes(l_2);
534 
535     pkt_2 = string(strbuf.str + pkt_1.length(), l_2 + 4);
536 
537     conn->send_all(strbuf.str, strbuf.length);
538 }
539 
TEST(coroutine_socket,length_4)540 TEST(coroutine_socket, length_4) {
541     coroutine::run({length_protocol_server_func,
542 
543                     [](void *arg) {
544                         Socket sock(SW_SOCK_TCP);
545                         bool retval = sock.connect("127.0.0.1", 9502, -1);
546                         ASSERT_EQ(retval, true);
547                         ASSERT_EQ(sock.errCode, 0);
548 
549                         socket_set_length_protocol_2(sock);
550 
551                         size_t bytes = 0;
552                         for (int i = 0; i < 2; i++) {
553                             ssize_t l = sock.recv_packet(RECV_TIMEOUT);
554                             bytes += l;
555                             auto buf = sock.get_read_buffer();
556                             uint32_t unpack_len = ntohl(*(uint32_t *) buf->str);
557 
558                             if (i == 0) {
559                                 ASSERT_EQ(pkt_1, string(buf->str, buf->length));
560                             } else {
561                                 ASSERT_EQ(pkt_2, string(buf->str, buf->length));
562                             }
563 
564                             ASSERT_EQ(unpack_len, l - 4);
565                             ASSERT_EQ(buf->length, l);
566                             ASSERT_EQ(buf->offset, l);
567                         }
568                         ASSERT_GE(bytes, 65536 * 2);
569                     }});
570 }
571 
TEST(coroutine_socket,length_5)572 TEST(coroutine_socket, length_5) {
573     coroutine::run({length_protocol_server_func,
574 
575                     [](void *arg) {
576                         Socket sock(SW_SOCK_TCP);
577                         bool retval = sock.connect("127.0.0.1", 9502, -1);
578                         ASSERT_EQ(retval, true);
579                         ASSERT_EQ(sock.errCode, 0);
580 
581                         socket_set_length_protocol_2(sock);
582 
583                         size_t bytes = 0;
584                         for (int i = 0; i < 2; i++) {
585                             ssize_t l = sock.recv_packet(RECV_TIMEOUT);
586                             bytes += l;
587                             char *data = sock.pop_packet();
588                             uint32_t unpack_len = ntohl(*(uint32_t *) data);
589                             ASSERT_EQ(unpack_len, l - 4);
590 
591                             if (i == 0) {
592                                 ASSERT_EQ(pkt_1, string(data, l));
593                             } else {
594                                 ASSERT_EQ(pkt_2, string(data, l));
595                             }
596                         }
597                         ASSERT_GE(bytes, 65536 * 2);
598                     }});
599 }
600 
TEST(coroutine_socket,length_7)601 TEST(coroutine_socket, length_7) {
602     coroutine::run({[](void *arg) {
603                         Socket sock(SW_SOCK_TCP);
604                         bool retval = sock.bind("127.0.0.1", 9502);
605                         ASSERT_EQ(retval, true);
606                         ASSERT_EQ(sock.listen(128), true);
607 
608                         Socket *conn = sock.accept();
609                         char buf[1024];
610                         *(uint32_t *) buf = htons(0);
611 
612                         conn->send(buf, 2);
613                         System::sleep(0.01);
614                         conn->send(buf + 2, 2);
615                     },
616 
617                     [](void *arg) {
618                         Socket sock(SW_SOCK_TCP);
619                         bool retval = sock.connect("127.0.0.1", 9502, -1);
620                         ASSERT_EQ(retval, true);
621                         ASSERT_EQ(sock.errCode, 0);
622 
623                         socket_set_length_protocol_2(sock);
624 
625                         ssize_t l = sock.recv_packet(RECV_TIMEOUT);
626                         auto buf = sock.get_read_buffer();
627 
628                         ASSERT_EQ(l, 4);
629                         ASSERT_EQ(buf->length, 4);
630                         ASSERT_EQ(buf->offset, 4);
631                     }});
632 }
633 
TEST(coroutine_socket,event_hup)634 TEST(coroutine_socket, event_hup) {
635     coroutine::run({[](void *arg) {
636         Socket sock(SW_SOCK_TCP);
637         bool retval = sock.bind("127.0.0.1", 9502);
638         ASSERT_EQ(retval, true);
639         ASSERT_EQ(sock.listen(128), true);
640 
641         Socket *conn = sock.accept();
642         System::sleep(0.05);
643         char buf[1024];
644         auto ret_n = conn->recv(buf, sizeof(buf));
645         ASSERT_EQ(ret_n, 0);
646         delete conn;
647     },
648 
649     [](void *arg) {
650         Socket sock(SW_SOCK_TCP);
651         bool retval = sock.connect("127.0.0.1", 9502, -1);
652         ASSERT_EQ(retval, true);
653         ASSERT_EQ(sock.errCode, 0);
654 
655         auto buf = sock.get_read_buffer();
656         swoole::Coroutine::create([&sock](void *args) {
657             System::sleep(0.01);
658             sock.shutdown(SHUT_RDWR);
659         });
660         auto n = sock.recv_all(buf->str, buf->size);
661         ASSERT_EQ(sock.get_socket()->event_hup, 1);
662         ASSERT_EQ(n, 0);
663     }});
664 }
665 
TEST(coroutine_socket,recv_line)666 TEST(coroutine_socket, recv_line) {
667     coroutine::run({[](void *arg) {
668         Socket sock(SW_SOCK_TCP);
669         bool retval = sock.bind("127.0.0.1", 9909);
670         ASSERT_EQ(retval, true);
671         ASSERT_EQ(sock.listen(128), true);
672 
673         Socket *conn = sock.accept();
674         conn->send("hello world\n");
675         conn->send("\r");
676         char buf[256];
677         memset(buf, 'A', 128);
678         memset(buf + 128, 'B', 125);
679         conn->send(buf, 253);
680         delete conn;
681     },
682 
683     [](void *arg) {
684         Socket sock(SW_SOCK_TCP);
685         bool retval = sock.connect("127.0.0.1", 9909, -1);
686         ASSERT_EQ(retval, true);
687         ASSERT_EQ(sock.errCode, 0);
688 
689         size_t n;
690         auto buf = sock.get_read_buffer();
691 
692         n = sock.recv_line(buf->str, 128);
693         ASSERT_EQ(n, 12);
694         ASSERT_MEMEQ(buf->str, "hello world\n", 12);
695 
696         n = sock.recv_line(buf->str, 128);
697         ASSERT_EQ(n, 1);
698         ASSERT_MEMEQ(buf->str, "\r", 1);
699 
700         char buf_2[256];
701         memset(buf_2, 'A', 128);
702         memset(buf_2 + 128, 'B', 125);
703 
704         n = sock.recv_line(buf->str, 128);
705         ASSERT_EQ(n, 128);
706         ASSERT_MEMEQ(buf->str, buf_2, 128);
707 
708         n = sock.recv_line(buf->str, 128);
709         ASSERT_EQ(n, 125);
710         ASSERT_MEMEQ(buf->str, buf_2 + 128, 125);
711 
712         n = sock.recv_line(buf->str, 128);
713         ASSERT_EQ(n, 0);
714     }});
715 }
716