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