1 /*
2 * Copyright (c) 2023, Emna Rekik
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "server_internal.h"
8
9 #include <string.h>
10
11 #include <zephyr/net/http/service.h>
12 #include <zephyr/net/socket.h>
13 #include <zephyr/ztest.h>
14
15 #define BUFFER_SIZE 256
16 #define MY_IPV4_ADDR "127.0.0.1"
17 #define SERVER_PORT 8080
18 #define TIMEOUT 1000
19
20 static const unsigned char index_html_gz[] = {
21 #include "index.html.gz.inc"
22 };
23
24 static const unsigned char compressed_inc_file[] = {
25 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
26 0x02, 0xff, 0x35, 0x8e, 0xc1, 0x0a, 0xc2, 0x30,
27 0x0c, 0x86, 0xef, 0x7d, 0x8a, 0xec, 0x05, 0x2c,
28 0xbb, 0x87, 0x5c, 0x54, 0xf0, 0xe0, 0x50, 0x58,
29 0x41, 0x3c, 0x4e, 0x17, 0x69, 0x21, 0xa5, 0x65,
30 0x2d, 0x42, 0xdf, 0xde, 0xba, 0x6e, 0x21, 0x10,
31 0xf8, 0xf9, 0xbe, 0x9f, 0x60, 0x77, 0xba, 0x1d,
32 0xcd, 0xf3, 0x7e, 0x06, 0x9b, 0xbd, 0x90, 0xc2,
33 0xfd, 0xf0, 0x34, 0x93, 0x82, 0x3a, 0x98, 0x5d,
34 0x16, 0xa6, 0xa1, 0xc0, 0xe8, 0x7c, 0x14, 0x86,
35 0x91, 0x97, 0x2f, 0x2f, 0xa8, 0x5b, 0xae, 0x50,
36 0x37, 0x16, 0x5f, 0x61, 0x2e, 0x9b, 0x62, 0x7b,
37 0x7a, 0xb0, 0xbc, 0x83, 0x67, 0xc8, 0x01, 0x7c,
38 0x81, 0xd4, 0xd4, 0xb4, 0xaa, 0x5d, 0x55, 0xfa,
39 0x8d, 0x8c, 0x64, 0xac, 0x4b, 0x50, 0x77, 0xda,
40 0xa1, 0x8b, 0x19, 0xae, 0xf0, 0x71, 0xc2, 0x07,
41 0xd4, 0xf1, 0xdf, 0xdf, 0x8a, 0xab, 0xb4, 0xbe,
42 0xf6, 0x03, 0xea, 0x2d, 0x11, 0x5c, 0xb2, 0x00,
43 0x00, 0x00,
44 };
45
46 static uint16_t test_http_service_port = SERVER_PORT;
47 HTTP_SERVICE_DEFINE(test_http_service, MY_IPV4_ADDR,
48 &test_http_service_port, 1,
49 10, NULL);
50
51 struct http_resource_detail_static index_html_gz_resource_detail = {
52 .common = {
53 .type = HTTP_RESOURCE_TYPE_STATIC,
54 .bitmask_of_supported_http_methods = BIT(HTTP_GET),
55 },
56 .static_data = index_html_gz,
57 .static_data_len = sizeof(index_html_gz),
58 };
59
60 HTTP_RESOURCE_DEFINE(index_html_gz_resource, test_http_service, "/",
61 &index_html_gz_resource_detail);
62
test_crime(void)63 static void test_crime(void)
64 {
65 int ret, recv_len;
66 int client_fd;
67 int proto = IPPROTO_TCP;
68 char *ptr;
69 const char *data;
70 size_t len;
71 struct sockaddr_in sa;
72 static unsigned char buf[512];
73
74 zassert_ok(http_server_start(), "Failed to start the server");
75
76 ret = zsock_socket(AF_INET, SOCK_STREAM, proto);
77 zassert_not_equal(ret, -1, "failed to create client socket (%d)", errno);
78 client_fd = ret;
79
80 sa.sin_family = AF_INET;
81 sa.sin_port = htons(SERVER_PORT);
82
83 ret = zsock_inet_pton(AF_INET, MY_IPV4_ADDR, &sa.sin_addr.s_addr);
84 zassert_not_equal(-1, ret, "inet_pton() failed (%d)", errno);
85 zassert_not_equal(0, ret, "%s is not a valid IPv4 address", MY_IPV4_ADDR);
86 zassert_equal(1, ret, "inet_pton() failed to convert %s", MY_IPV4_ADDR);
87
88 memset(buf, '\0', sizeof(buf));
89 ptr = (char *)zsock_inet_ntop(AF_INET, &sa.sin_addr, buf, sizeof(buf));
90 zassert_not_equal(ptr, NULL, "inet_ntop() failed (%d)", errno);
91
92 ret = zsock_connect(client_fd, (struct sockaddr *)&sa, sizeof(sa));
93 zassert_not_equal(ret, -1, "failed to connect (%s/%d)", strerror(errno), errno);
94
95 char *http1_request = "GET / HTTP/1.1\r\n"
96 "Host: 127.0.0.1:8080\r\n"
97 "Accept: */*\r\n"
98 "Accept-Encoding: deflate, gzip, br\r\n"
99 "\r\n";
100
101 ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
102 zassert_not_equal(ret, -1, "send() failed (%d)", errno);
103
104 memset(buf, 0, sizeof(buf));
105 recv_len = zsock_recv(client_fd, buf, sizeof(buf), 0);
106 zassert_not_equal(recv_len, -1, "recv() failed (%d)", errno);
107
108 len = sizeof(index_html_gz);
109
110 while (recv_len < len) {
111 ret = zsock_recv(client_fd, buf + recv_len, sizeof(buf) - recv_len, 0);
112 zassert_not_equal(ret, -1, "recv() failed (%d)", errno);
113
114 recv_len += ret;
115 }
116
117 data = strstr(buf, "\r\n\r\n");
118 zassert_not_null(data, "Header not found");
119
120 data += 4;
121
122 zassert_equal(len, sizeof(compressed_inc_file), "Invalid compressed file size");
123
124 ret = memcmp(data, compressed_inc_file, len);
125 zassert_equal(ret, 0,
126 "inc_file and compressed_inc_file contents are not identical (%d)", ret);
127
128 ret = zsock_close(client_fd);
129 zassert_not_equal(-1, ret, "close() failed on the client fd (%d)", errno);
130
131 zassert_ok(http_server_stop(), "Failed to stop the server");
132 }
133
ZTEST(framework_tests_crime,test_gen_gz_inc_file)134 ZTEST(framework_tests_crime, test_gen_gz_inc_file)
135 {
136 test_crime();
137 }
138
139 ZTEST_SUITE(framework_tests_crime, NULL, NULL, NULL, NULL, NULL);
140