1 /*
2  * Copyright (c) 2023, Emna Rekik
3  * Copyright (c) 2024 Nordic Semiconductor ASA
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include "server_internal.h"
9 
10 #include <string.h>
11 #include <strings.h>
12 
13 #include <zephyr/net/http/service.h>
14 #include <zephyr/net/socket.h>
15 #include <zephyr/posix/sys/eventfd.h>
16 #include <zephyr/ztest.h>
17 
18 #define BUFFER_SIZE                    1024
19 #define SERVER_IPV4_ADDR               "127.0.0.1"
20 #define SERVER_PORT                    8080
21 #define TIMEOUT_S                      1
22 
23 #define UPGRADE_STREAM_ID              1
24 #define TEST_STREAM_ID_1               3
25 #define TEST_STREAM_ID_2               5
26 
27 #define TEST_DYNAMIC_POST_PAYLOAD "Test dynamic POST"
28 #define TEST_DYNAMIC_GET_PAYLOAD "Test dynamic GET"
29 #define TEST_STATIC_PAYLOAD "Hello, World!"
30 #define TEST_STATIC_FS_PAYLOAD "Hello, World from static file!"
31 
32 /* Random base64 encoded data */
33 #define TEST_LONG_PAYLOAD_CHUNK_1                                                                  \
34 	"Z3479c2x8gXgzvDpvt4YuQePsvmsur1J1U+lLKzkyGCQgtWEysRjnO63iZvN/Zaag5YlliAkcaWi"             \
35 	"Alb8zI4SxK+JB3kfpkcAA6c8m2PfkP6D5+Vrcy9O6ituR8gb0tm8o9CwTeUhf8H6q2kB5BO1ZZxm"             \
36 	"G9c3VO9BLLTC8LMG8isyzB1wT+EB8YTv4YaNc9mXJmXNt3pycZ4Thg20rPfhZsvleIeUYZZQJArx"             \
37 	"ufSBYR4v6mAEm/qdFqIwe9k6dtJEfR5guFoAWbR4jMrJreshyvByrZSy+aP1S93Fvob9hNn6ouSc"
38 #define TEST_LONG_PAYLOAD_CHUNK_2                                                                  \
39 	"a0UIx0JKhFKvnM23kcavlMzwD+MerSiPUDYKSjtnjhhZmW3GonTpUWMEuDGZNkbrAZ3fbuWRbHi0"             \
40 	"1GufXYWGw/Jk6H6GV5WWWF9a71dng6gsH21zD1dqYIo46hofi4mfJ8Spo9a4Ch04ARNFSMhuLwYv"             \
41 	"eOprXUybMUiBVlTansXL2mdH2BgCPu4u65kIyAxcQpiXNGSJ3EjEIGIa"
42 
43 static const char long_payload[] = TEST_LONG_PAYLOAD_CHUNK_1 TEST_LONG_PAYLOAD_CHUNK_2;
44 BUILD_ASSERT(sizeof(long_payload) - 1 > CONFIG_HTTP_SERVER_CLIENT_BUFFER_SIZE,
45 	     "long_payload should be longer than client buffer to test payload being sent to "
46 	     "application across multiple calls to dynamic resource callback");
47 
48 /* Individual HTTP2 frames, used to compose requests.
49  *
50  * Headers and data frames can be composed based on a "real" request by copying the frame from a
51  * wireshark capture (Copy --> ...as a hex stream) and formatting into a C array initializer using
52  * xxd:
53  *
54  *   echo "<frame_as_hex_stream>" | xxd -r -p | xxd -i
55  *
56  * For example:
57  *   $ echo "01234567" | xxd -r -p | xxd -i
58  *     0x01, 0x23, 0x45, 0x67
59  */
60 #define TEST_HTTP2_MAGIC \
61 	0x50, 0x52, 0x49, 0x20, 0x2a, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x32, \
62 	0x2e, 0x30, 0x0d, 0x0a, 0x0d, 0x0a, 0x53, 0x4d, 0x0d, 0x0a, 0x0d, 0x0a
63 #define TEST_HTTP2_SETTINGS \
64 	0x00, 0x00, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x00,	0x00, \
65 	0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00, 0x04, 0x00, 0x00, 0xff, 0xff
66 #define TEST_HTTP2_SETTINGS_ACK \
67 	0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00
68 #define TEST_HTTP2_GOAWAY \
69 	0x00, 0x00, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00, \
70 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
71 #define TEST_HTTP2_HEADERS_GET_ROOT_STREAM_1 \
72 	0x00, 0x00, 0x21, 0x01, 0x05, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
73 	0x82, 0x84, 0x86, 0x41, 0x8a, 0x0b, 0xe2, 0x5c, 0x0b, 0x89, 0x70, 0xdc, \
74 	0x78, 0x0f, 0x03, 0x53, 0x03, 0x2a, 0x2f, 0x2a, 0x90, 0x7a, 0x8a, 0xaa, \
75 	0x69, 0xd2, 0x9a, 0xc4, 0xc0, 0x57, 0x68, 0x0b, 0x83
76 #define TEST_HTTP2_HEADERS_GET_INDEX_STREAM_2 \
77 	0x00, 0x00, 0x21, 0x01, 0x05, 0x00, 0x00, 0x00, TEST_STREAM_ID_2, \
78 	0x82, 0x85, 0x86, 0x41, 0x8a, 0x0b, 0xe2, 0x5c, 0x0b, 0x89, 0x70, 0xdc, \
79 	0x78, 0x0f, 0x03, 0x53, 0x03, 0x2a, 0x2f, 0x2a, 0x90, 0x7a, 0x8a, 0xaa, \
80 	0x69, 0xd2, 0x9a, 0xc4, 0xc0, 0x57, 0x68, 0x0b, 0x83
81 #define TEST_HTTP2_HEADERS_GET_DYNAMIC_STREAM_1 \
82 	0x00, 0x00, 0x2b, 0x01, 0x05, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
83 	0x82, 0x86, 0x41, 0x87, 0x0b, 0xe2, 0x5c, 0x0b, 0x89, 0x70, 0xff, 0x04, \
84 	0x86, 0x62, 0x4f, 0x55, 0x0e, 0x93, 0x13, 0x7a, 0x88, 0x25, 0xb6, 0x50, \
85 	0xc3, 0xcb, 0xbc, 0xb8, 0x3f, 0x53, 0x03, 0x2a, 0x2f, 0x2a, 0x5f, 0x87, \
86 	0x49, 0x7c, 0xa5, 0x8a, 0xe8, 0x19, 0xaa
87 #define TEST_HTTP2_HEADERS_GET_DYNAMIC_STREAM_1_PADDED \
88 	0x00, 0x00, 0x3d, 0x01, 0x0d, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, 0x11,\
89 	0x82, 0x86, 0x41, 0x87, 0x0b, 0xe2, 0x5c, 0x0b, 0x89, 0x70, 0xff, 0x04, \
90 	0x86, 0x62, 0x4f, 0x55, 0x0e, 0x93, 0x13, 0x7a, 0x88, 0x25, 0xb6, 0x50, \
91 	0xc3, 0xcb, 0xbc, 0xb8, 0x3f, 0x53, 0x03, 0x2a, 0x2f, 0x2a, 0x5f, 0x87, \
92 	0x49, 0x7c, 0xa5, 0x8a, 0xe8, 0x19, 0xaa, \
93 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
94 	0x00, 0x00, 0x00, 0x00, 0x00
95 #define TEST_HTTP2_HEADERS_GET_HEADER_CAPTURE1_STREAM_1 \
96 	0x00, 0x00, 0x39, 0x01, 0x05, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
97 	0x82, 0x04, 0x8b, 0x62, 0x72, 0x8e, 0x42, 0xd9, 0x11, 0x07, 0x5a, 0x6d, \
98 	0xb0, 0xbf, 0x86, 0x41, 0x87, 0x0b, 0xe2, 0x5c, 0x0b, 0x89, 0x70, 0xff, \
99 	0x7a, 0x88, 0x25, 0xb6, 0x50, 0xc3, 0xab, 0xbc, 0x15, 0xc1, 0x53, 0x03, \
100 	0x2a, 0x2f, 0x2a, 0x40, 0x88, 0x49, 0x50, 0x95, 0xa7, 0x28, 0xe4, 0x2d, \
101 	0x9f, 0x87, 0x49, 0x50, 0x98, 0xbb, 0x8e, 0x8b, 0x4b
102 #define TEST_HTTP2_HEADERS_GET_HEADER_CAPTURE2_STREAM_1 \
103 	0x00, 0x00, 0x5a, 0x01, 0x05, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
104 	0x82, 0x04, 0x8b, 0x62, 0x72, 0x8e, 0x42, 0xd9, 0x11, 0x07, 0x5a, 0x6d, \
105 	0xb0, 0xbf, 0x86, 0x41, 0x87, 0x0b, 0xe2, 0x5c, 0x0b, 0x89, 0x70, 0xff, \
106 	0x7a, 0xa9, 0x18, 0xc6, 0x31, 0x8c, 0x63, 0x18, 0xc6, 0x31, 0x8c, 0x63, \
107 	0x18, 0xc6, 0x31, 0x8c, 0x63, 0x18, 0xc6, 0x31, 0x8c, 0x63, 0x18, 0xc6, \
108 	0x31, 0x8c, 0x63, 0x18, 0xc6, 0x31, 0x8c, 0x63, 0x18, 0xc6, 0x31, 0x8c, \
109 	0x63, 0x18, 0xc6, 0x31, 0x8c, 0x63, 0x1f, 0x53, 0x03, 0x2a, 0x2f, 0x2a, \
110 	0x40, 0x88, 0x49, 0x50, 0x95, 0xa7, 0x28, 0xe4, 0x2d, 0x9f, 0x87, 0x49, \
111 	0x50, 0x98, 0xbb, 0x8e, 0x8b, 0x4b
112 #define TEST_HTTP2_HEADERS_GET_HEADER_CAPTURE3_STREAM_1 \
113 	0x00, 0x00, 0x4c, 0x01, 0x05, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
114 	0x82, 0x04, 0x8b, 0x62, 0x72, 0x8e, 0x42, 0xd9, 0x11, 0x07, 0x5a, 0x6d, \
115 	0xb0, 0xbf, 0x86, 0x41, 0x87, 0x0b, 0xe2, 0x5c, 0x0b, 0x89, 0x70, 0xff, \
116 	0x7a, 0x88, 0x25, 0xb6, 0x50, 0xc3, 0xab, 0xbc, 0x15, 0xc1, 0x53, 0x03, \
117 	0x2a, 0x2f, 0x2a, 0x40, 0x88, 0x49, 0x50, 0x95, 0xa7, 0x28, 0xe4, 0x2d, \
118 	0x9f, 0x87, 0x49, 0x50, 0x98, 0xbb, 0x8e, 0x8b, 0x4b, 0x40, 0x88, 0x49, \
119 	0x50, 0x95, 0xa7, 0x28, 0xe4, 0x2d, 0x82, 0x88, 0x49, 0x50, 0x98, 0xbb, \
120 	0x8e, 0x8b, 0x4a, 0x2f
121 #define TEST_HTTP2_HEADERS_POST_HEADER_CAPTURE_WITH_TESTHEADER_STREAM_1 \
122 	0x00, 0x00, 0x4b, 0x01, 0x04, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
123 	0x83, 0x04, 0x8b, 0x62, 0x72, 0x8e, 0x42, 0xd9, 0x11, 0x07, 0x5a, 0x6d, \
124 	0xb0, 0xbf, 0x86, 0x41, 0x87, 0x0b, 0xe2, 0x5c, 0x0b, 0x89, 0x70, 0xff, \
125 	0x7a, 0x88, 0x25, 0xb6, 0x50, 0xc3, 0xab, 0xbc, 0x15, 0xc1, 0x53, 0x03, \
126 	0x2a, 0x2f, 0x2a, 0x40, 0x88, 0x49, 0x50, 0x95, 0xa7, 0x28, 0xe4, 0x2d, \
127 	0x9f, 0x87, 0x49, 0x50, 0x98, 0xbb, 0x8e, 0x8b, 0x4b, 0x5f, 0x8b, 0x1d, \
128 	0x75, 0xd0, 0x62, 0x0d, 0x26, 0x3d, 0x4c, 0x74, 0x41, 0xea, 0x0f, 0x0d, \
129 	0x02, 0x31, 0x30
130 #define TEST_HTTP2_HEADERS_POST_HEADER_CAPTURE2_NO_TESTHEADER_STREAM_2 \
131 	0x00, 0x00, 0x39, 0x01, 0x04, 0x00, 0x00, 0x00, TEST_STREAM_ID_2, \
132 	0x83, 0x04, 0x8b, 0x62, 0x72, 0x8e, 0x42, 0xd9, 0x11, 0x07, 0x5a, 0x6d, \
133 	0xb0, 0xa2, 0x86, 0x41, 0x87, 0x0b, 0xe2, 0x5c, 0x0b, 0x89, 0x70, 0xff, \
134 	0x7a, 0x88, 0x25, 0xb6, 0x50, 0xc3, 0xab, 0xbc, 0x15, 0xc1, 0x53, 0x03, \
135 	0x2a, 0x2f, 0x2a, 0x5f, 0x8b, 0x1d, 0x75, 0xd0, 0x62, 0x0d, 0x26, 0x3d, \
136 	0x4c, 0x74, 0x41, 0xea, 0x0f, 0x0d, 0x02, 0x31, 0x30
137 #define TEST_HTTP2_HEADERS_GET_RESPONSE_HEADERS_STREAM_1 \
138 	0x00, 0x00, 0x28, 0x01, 0x05, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
139 	0x82, 0x04, 0x8c, 0x62, 0xc2, 0xa2, 0xb3, 0xd4, 0x82, 0xc5, 0x39, 0x47, \
140 	0x21, 0x6c, 0x47, 0x86, 0x41, 0x87, 0x0b, 0xe2, 0x5c, 0x0b, 0x89, 0x70, \
141 	0xff, 0x7a, 0x88, 0x25, 0xb6, 0x50, 0xc3, 0xab, 0xbc, 0x15, 0xc1, 0x53, \
142 	0x03, 0x2a, 0x2f, 0x2a
143 #define TEST_HTTP2_HEADERS_POST_RESPONSE_HEADERS_STREAM_1 \
144 	0x00, 0x00, 0x28, 0x01, 0x04, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
145 	0x83, 0x04, 0x8c, 0x62, 0xc2, 0xa2, 0xb3, 0xd4, 0x82, 0xc5, 0x39, 0x47, \
146 	0x21, 0x6c, 0x47, 0x86, 0x41, 0x87, 0x0b, 0xe2, 0x5c, 0x0b, 0x89, 0x70, \
147 	0xff, 0x7a, 0x88, 0x25, 0xb6, 0x50, 0xc3, 0xab, 0xbc, 0x15, 0xc1, 0x53, \
148 	0x03, 0x2a, 0x2f, 0x2a
149 #define TEST_HTTP2_HEADERS_POST_DYNAMIC_STREAM_1 \
150 	0x00, 0x00, 0x30, 0x01, 0x04, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
151 	0x83, 0x86, 0x41, 0x87, 0x0b, 0xe2, 0x5c, 0x0b, 0x89, 0x70, 0xff, 0x04, \
152 	0x86, 0x62, 0x4f, 0x55, 0x0e, 0x93, 0x13, 0x7a, 0x88, 0x25, 0xb6, 0x50, \
153 	0xc3, 0xcb, 0xbc, 0xb8, 0x3f, 0x53, 0x03, 0x2a, 0x2f, 0x2a, 0x5f, 0x87, \
154 	0x49, 0x7c, 0xa5, 0x8a, 0xe8, 0x19, 0xaa, 0x0f, 0x0d, 0x02, 0x31, 0x37
155 #define TEST_HTTP2_HEADERS_POST_DYNAMIC_STREAM_1_PRIORITY \
156 	0x00, 0x00, 0x35, 0x01, 0x24, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
157 	0x00, 0x00, 0x00, 0x00, 0x64, \
158 	0x83, 0x86, 0x41, 0x87, 0x0b, 0xe2, 0x5c, 0x0b, 0x89, 0x70, 0xff, 0x04, \
159 	0x86, 0x62, 0x4f, 0x55, 0x0e, 0x93, 0x13, 0x7a, 0x88, 0x25, 0xb6, 0x50, \
160 	0xc3, 0xcb, 0xbc, 0xb8, 0x3f, 0x53, 0x03, 0x2a, 0x2f, 0x2a, 0x5f, 0x87, \
161 	0x49, 0x7c, 0xa5, 0x8a, 0xe8, 0x19, 0xaa, 0x0f, 0x0d, 0x02, 0x31, 0x37
162 #define TEST_HTTP2_HEADERS_POST_DYNAMIC_STREAM_1_PRIORITY_PADDED \
163 	0x00, 0x00, 0x40, 0x01, 0x2c, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
164 	0x0a, 0x00, 0x00, 0x00, 0x00, 0xc8,\
165 	0x83, 0x86, 0x41, 0x87, 0x0b, 0xe2, 0x5c, 0x0b, 0x89, 0x70, 0xff, 0x04, \
166 	0x86, 0x62, 0x4f, 0x55, 0x0e, 0x93, 0x13, 0x7a, 0x88, 0x25, 0xb6, 0x50, \
167 	0xc3, 0xcb, 0xbc, 0xb8, 0x3f, 0x53, 0x03, 0x2a, 0x2f, 0x2a, 0x5f, 0x87, \
168 	0x49, 0x7c, 0xa5, 0x8a, 0xe8, 0x19, 0xaa, 0x0f, 0x0d, 0x02, 0x31, 0x37, \
169 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
170 #define TEST_HTTP2_PARTIAL_HEADERS_POST_DYNAMIC_STREAM_1 \
171 	0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
172 	0x83, 0x86, 0x41, 0x87, 0x0b, 0xe2, 0x5c, 0x0b, 0x89, 0x70, 0xff, 0x04, \
173 	0x86, 0x62, 0x4f, 0x55, 0x0e, 0x93, 0x13, 0x7a, 0x88, 0x25, 0xb6, 0x50, \
174 	0xc3, 0xcb, 0xbc, 0xb8, 0x3f, 0x53, 0x03, 0x2a
175 #define TEST_HTTP2_CONTINUATION_POST_DYNAMIC_STREAM_1 \
176 	0x00, 0x00, 0x10, 0x09, 0x04, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
177 	0x2f, 0x2a, 0x5f, 0x87, 0x49, 0x7c, 0xa5, 0x8a, 0xe8, 0x19, 0xaa, 0x0f, \
178 	0x0d, 0x02, 0x31, 0x37
179 #define TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1 \
180 	0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
181 	0x54, 0x65, 0x73, 0x74, 0x20, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, \
182 	0x20, 0x50, 0x4f, 0x53, 0x54
183 #define TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1_PADDED \
184 	0x00, 0x00, 0x34, 0x00, 0x09, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, 0x22, \
185 	0x54, 0x65, 0x73, 0x74, 0x20, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, \
186 	0x20, 0x50, 0x4f, 0x53, 0x54, \
187 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
188 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
189 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
190 #define TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1_NO_END_STREAM \
191 	0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
192 	0x54, 0x65, 0x73, 0x74, 0x20, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, \
193 	0x20, 0x50, 0x4f, 0x53, 0x54
194 #define TEST_HTTP2_DATA_POST_HEADER_CAPTURE_STREAM_1                                               \
195 	0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
196 	0x7b, 0x22, 0x74, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x31, 0x7d
197 #define TEST_HTTP2_DATA_POST_HEADER_CAPTURE_STREAM_2                                               \
198 	0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, TEST_STREAM_ID_2, \
199 	0x7b, 0x22, 0x74, 0x65,	0x73, 0x74, 0x22, 0x3a, 0x31, 0x7d
200 #define TEST_HTTP2_TRAILING_HEADER_STREAM_1 \
201 	0x00, 0x00, 0x0c, 0x01, 0x05, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
202 	0x40, 0x84, 0x92, 0xda, 0x69, 0xf5, 0x85, 0x9c, 0xa3, 0x90, 0xb6, 0x7f
203 #define TEST_HTTP2_RST_STREAM_STREAM_1 \
204 	0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
205 	0xaa, 0xaa, 0xaa, 0xaa
206 #define TEST_HTTP2_HEADERS_PUT_DYNAMIC_STREAM_1 \
207 	0x00, 0x00, 0x34, 0x01, 0x04, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
208 	0x42, 0x03, 0x50, 0x55, 0x54, 0x86, 0x41, 0x87, 0x0b, 0xe2, 0x5c, 0x0b, \
209 	0x89, 0x70, 0xff, 0x04, 0x86, 0x62, 0x4f, 0x55, 0x0e, 0x93, 0x13, 0x7a, \
210 	0x88, 0x25, 0xb6, 0x50, 0xc3, 0xcb, 0xbc, 0xb8, 0x3f, 0x53, 0x03, 0x2a, \
211 	0x2f, 0x2a, 0x5f, 0x87, 0x49, 0x7c, 0xa5, 0x8a, 0xe8, 0x19, 0xaa, 0x0f, \
212 	0x0d, 0x02, 0x31, 0x37
213 #define TEST_HTTP2_HEADERS_PATCH_DYNAMIC_STREAM_1 \
214 	0x00, 0x00, 0x36, 0x01, 0x04, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
215 	0x42, 0x05, 0x50, 0x41, 0x54, 0x43, 0x48, 0x86, 0x41, 0x87, 0x0b, 0xe2, \
216 	0x5c, 0x0b, 0x89, 0x70, 0xff, 0x04, 0x86, 0x62, 0x4f, 0x55, 0x0e, 0x93, \
217 	0x13, 0x7a, 0x88, 0x25, 0xb6, 0x50, 0xc3, 0xcb, 0xbc, 0xb8, 0x3f, 0x53, \
218 	0x03, 0x2a, 0x2f, 0x2a, 0x5f, 0x87, 0x49, 0x7c, 0xa5, 0x8a, 0xe8, 0x19, \
219 	0xaa, 0x0f, 0x0d, 0x02, 0x31, 0x37
220 #define TEST_HTTP2_DATA_PUT_DYNAMIC_STREAM_1 TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1
221 #define TEST_HTTP2_DATA_PATCH_DYNAMIC_STREAM_1 TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1
222 #define TEST_HTTP2_HEADERS_DELETE_DYNAMIC_STREAM_1 \
223 	0x00, 0x00, 0x32, 0x01, 0x05, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
224 	0x42, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x86, 0x41, 0x87, 0x0b, \
225 	0xe2, 0x5c, 0x0b, 0x89, 0x70, 0xff, 0x04, 0x86, 0x62, 0x4f, 0x55, 0x0e, \
226 	0x93, 0x13, 0x7a, 0x88, 0x25, 0xb6, 0x50, 0xc3, 0xcb, 0xbc, 0xb8, 0x3f, \
227 	0x53, 0x03, 0x2a, 0x2f, 0x2a, 0x5f, 0x87, 0x49, 0x7c, 0xa5, 0x8a, 0xe8, \
228 	0x19, 0xaa
229 #define TEST_HTTP2_HEADERS_POST_ROOT_STREAM_1 \
230 	0x00, 0x00, 0x21, 0x01, 0x05, 0x00, 0x00, 0x00, TEST_STREAM_ID_1, \
231 	0x83, 0x84, 0x86, 0x41, 0x8a, 0x0b, 0xe2, 0x5c, 0x0b, 0x89, 0x70, 0xdc, \
232 	0x78, 0x0f, 0x03, 0x53, 0x03, 0x2a, 0x2f, 0x2a, 0x90, 0x7a, 0x8a, 0xaa, \
233 	0x69, 0xd2, 0x9a, 0xc4, 0xc0, 0x57, 0x68, 0x0b, 0x83
234 #define TEST_HTTP2_DATA_POST_ROOT_STREAM_1 TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1
235 
236 static uint16_t test_http_service_port = SERVER_PORT;
237 HTTP_SERVICE_DEFINE(test_http_service, SERVER_IPV4_ADDR,
238 		    &test_http_service_port, 1, 10, NULL, NULL);
239 
240 static const char static_resource_payload[] = TEST_STATIC_PAYLOAD;
241 struct http_resource_detail_static static_resource_detail = {
242 	.common = {
243 			.type = HTTP_RESOURCE_TYPE_STATIC,
244 			.bitmask_of_supported_http_methods = BIT(HTTP_GET),
245 		},
246 	.static_data = static_resource_payload,
247 	.static_data_len = sizeof(static_resource_payload) - 1,
248 };
249 
250 HTTP_RESOURCE_DEFINE(static_resource, test_http_service, "/",
251 		     &static_resource_detail);
252 
253 static uint8_t dynamic_payload[32];
254 static size_t dynamic_payload_len = sizeof(dynamic_payload);
255 static bool dynamic_error;
256 
dynamic_cb(struct http_client_ctx * client,enum http_data_status status,const struct http_request_ctx * request_ctx,struct http_response_ctx * response_ctx,void * user_data)257 static int dynamic_cb(struct http_client_ctx *client, enum http_data_status status,
258 		      const struct http_request_ctx *request_ctx,
259 		      struct http_response_ctx *response_ctx, void *user_data)
260 {
261 	static size_t offset;
262 
263 	if (status == HTTP_SERVER_DATA_ABORTED) {
264 		offset = 0;
265 		return 0;
266 	}
267 
268 	if (dynamic_error) {
269 		return -ENOMEM;
270 	}
271 
272 	switch (client->method) {
273 	case HTTP_GET:
274 		response_ctx->body = dynamic_payload;
275 		response_ctx->body_len = dynamic_payload_len;
276 		response_ctx->final_chunk = true;
277 		break;
278 	case HTTP_DELETE:
279 		response_ctx->body = NULL;
280 		response_ctx->body_len = 0;
281 		response_ctx->final_chunk = true;
282 		break;
283 	case HTTP_POST:
284 	case HTTP_PUT:
285 	case HTTP_PATCH:
286 		if (request_ctx->data_len + offset > sizeof(dynamic_payload)) {
287 			return -ENOMEM;
288 		}
289 
290 		if (request_ctx->data_len > 0) {
291 			memcpy(dynamic_payload + offset, request_ctx->data, request_ctx->data_len);
292 			offset += request_ctx->data_len;
293 		}
294 
295 		if (status == HTTP_SERVER_DATA_FINAL) {
296 			/* All data received, reset progress. */
297 			dynamic_payload_len = offset;
298 			offset = 0;
299 		}
300 
301 		break;
302 	default:
303 		return -ENOTSUP;
304 	}
305 
306 	return 0;
307 }
308 
309 struct http_resource_detail_dynamic dynamic_detail = {
310 	.common = {
311 		.type = HTTP_RESOURCE_TYPE_DYNAMIC,
312 		.bitmask_of_supported_http_methods =
313 			BIT(HTTP_GET) | BIT(HTTP_DELETE) | BIT(HTTP_POST) |
314 			BIT(HTTP_PUT) | BIT(HTTP_PATCH),
315 		.content_type = "text/plain",
316 	},
317 	.cb = dynamic_cb,
318 	.user_data = NULL,
319 };
320 
321 HTTP_RESOURCE_DEFINE(dynamic_resource, test_http_service, "/dynamic",
322 		     &dynamic_detail);
323 
324 struct test_headers_clone {
325 	uint8_t buffer[CONFIG_HTTP_SERVER_CAPTURE_HEADER_BUFFER_SIZE];
326 	struct http_header headers[CONFIG_HTTP_SERVER_CAPTURE_HEADER_COUNT];
327 	size_t count;
328 	enum http_header_status status;
329 };
330 
dynamic_request_headers_cb(struct http_client_ctx * client,enum http_data_status status,const struct http_request_ctx * request_ctx,struct http_response_ctx * response_ctx,void * user_data)331 static int dynamic_request_headers_cb(struct http_client_ctx *client, enum http_data_status status,
332 				      const struct http_request_ctx *request_ctx,
333 				      struct http_response_ctx *response_ctx, void *user_data)
334 {
335 	ptrdiff_t offset;
336 	struct http_header *hdrs_src;
337 	struct http_header *hdrs_dst;
338 	struct test_headers_clone *clone = (struct test_headers_clone *)user_data;
339 
340 	if (request_ctx->header_count != 0) {
341 		/* Copy the captured header info to static buffer for later assertions in testcase.
342 		 * Don't assume that the buffer inside client context remains valid after return
343 		 * from the callback. Also need to update pointers within structure with an offset
344 		 * to point at new buffer.
345 		 */
346 		memcpy(clone->buffer, &client->header_capture_ctx, sizeof(clone->buffer));
347 
348 		clone->count = request_ctx->header_count;
349 		clone->status = request_ctx->headers_status;
350 
351 		hdrs_src = request_ctx->headers;
352 		hdrs_dst = clone->headers;
353 		offset = clone->buffer - client->header_capture_ctx.buffer;
354 
355 		for (int i = 0; i < request_ctx->header_count; i++) {
356 			if (hdrs_src[i].name != NULL) {
357 				hdrs_dst[i].name = hdrs_src[i].name + offset;
358 			}
359 
360 			if (hdrs_src[i].value != NULL) {
361 				hdrs_dst[i].value = hdrs_src[i].value + offset;
362 			}
363 		}
364 	}
365 
366 	return 0;
367 }
368 
369 /* Define two resources for testing header capture, so that we can check concurrent streams */
370 static struct test_headers_clone request_headers_clone;
371 static struct test_headers_clone request_headers_clone2;
372 
373 struct http_resource_detail_dynamic dynamic_request_headers_detail = {
374 	.common = {
375 			.type = HTTP_RESOURCE_TYPE_DYNAMIC,
376 			.bitmask_of_supported_http_methods = BIT(HTTP_GET) | BIT(HTTP_POST),
377 			.content_type = "text/plain",
378 		},
379 	.cb = dynamic_request_headers_cb,
380 	.user_data = &request_headers_clone,
381 };
382 
383 struct http_resource_detail_dynamic dynamic_request_headers_detail2 = {
384 	.common = {
385 			.type = HTTP_RESOURCE_TYPE_DYNAMIC,
386 			.bitmask_of_supported_http_methods = BIT(HTTP_GET) | BIT(HTTP_POST),
387 			.content_type = "text/plain",
388 		},
389 	.cb = dynamic_request_headers_cb,
390 	.user_data = &request_headers_clone2,
391 };
392 
393 HTTP_RESOURCE_DEFINE(dynamic_request_headers_resource, test_http_service, "/header_capture",
394 		     &dynamic_request_headers_detail);
395 
396 HTTP_RESOURCE_DEFINE(dynamic_request_headers_resource2, test_http_service, "/header_capture2",
397 		     &dynamic_request_headers_detail2);
398 
399 HTTP_SERVER_REGISTER_HEADER_CAPTURE(capture_user_agent, "User-Agent");
400 HTTP_SERVER_REGISTER_HEADER_CAPTURE(capture_test_header, "Test-Header");
401 HTTP_SERVER_REGISTER_HEADER_CAPTURE(capture_test_header2, "Test-Header2");
402 
403 enum dynamic_response_headers_variant {
404 	/* No application defined response code, headers or data */
405 	DYNAMIC_RESPONSE_HEADERS_VARIANT_NONE,
406 
407 	/* Send a 422 response code */
408 	DYNAMIC_RESPONSE_HEADERS_VARIANT_422,
409 
410 	/* Send an extra header on top of server defaults */
411 	DYNAMIC_RESPONSE_HEADERS_VARIANT_EXTRA_HEADER,
412 
413 	/* Override the default Content-Type header */
414 	DYNAMIC_RESPONSE_HEADERS_VARIANT_OVERRIDE_HEADER,
415 
416 	/* Send body data combined with header data in a single callback */
417 	DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_COMBINED,
418 
419 	/* Send body data in a separate callback to header data */
420 	DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_SEPARATE,
421 
422 	/* Long body data split across multiple callbacks */
423 	DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_LONG,
424 };
425 
426 static uint8_t dynamic_response_headers_variant;
427 static uint8_t dynamic_response_headers_buffer[sizeof(long_payload)];
428 
dynamic_response_headers_cb(struct http_client_ctx * client,enum http_data_status status,const struct http_request_ctx * request_ctx,struct http_response_ctx * response_ctx,void * user_data)429 static int dynamic_response_headers_cb(struct http_client_ctx *client, enum http_data_status status,
430 				       const struct http_request_ctx *request_ctx,
431 				       struct http_response_ctx *response_ctx, void *user_data)
432 {
433 	static bool request_continuation;
434 	static size_t offset;
435 
436 	static const struct http_header extra_headers[] = {
437 		{.name = "Test-Header", .value = "test_data"},
438 	};
439 
440 	static const struct http_header override_headers[] = {
441 		{.name = "Content-Type", .value = "application/json"},
442 	};
443 
444 	if (status != HTTP_SERVER_DATA_FINAL &&
445 	    dynamic_response_headers_variant != DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_LONG) {
446 		/* Long body variant is the only one which needs to take some action before final
447 		 * data has been received from server
448 		 */
449 		return 0;
450 	}
451 
452 	switch (dynamic_response_headers_variant) {
453 	case DYNAMIC_RESPONSE_HEADERS_VARIANT_NONE:
454 		break;
455 
456 	case DYNAMIC_RESPONSE_HEADERS_VARIANT_422:
457 		response_ctx->status = 422;
458 		response_ctx->final_chunk = true;
459 		break;
460 
461 	case DYNAMIC_RESPONSE_HEADERS_VARIANT_EXTRA_HEADER:
462 		response_ctx->headers = extra_headers;
463 		response_ctx->header_count = ARRAY_SIZE(extra_headers);
464 		response_ctx->final_chunk = true;
465 		break;
466 
467 	case DYNAMIC_RESPONSE_HEADERS_VARIANT_OVERRIDE_HEADER:
468 		response_ctx->headers = override_headers;
469 		response_ctx->header_count = ARRAY_SIZE(extra_headers);
470 		response_ctx->final_chunk = true;
471 		break;
472 
473 	case DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_SEPARATE:
474 		if (!request_continuation) {
475 			/* Send headers in first callback */
476 			response_ctx->headers = extra_headers;
477 			response_ctx->header_count = ARRAY_SIZE(extra_headers);
478 			request_continuation = true;
479 		} else {
480 			/* Send body in subsequent callback */
481 			response_ctx->body = TEST_DYNAMIC_GET_PAYLOAD;
482 			response_ctx->body_len = strlen(response_ctx->body);
483 			response_ctx->final_chunk = true;
484 			request_continuation = false;
485 		}
486 		break;
487 
488 	case DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_COMBINED:
489 		response_ctx->headers = extra_headers;
490 		response_ctx->header_count = ARRAY_SIZE(extra_headers);
491 		response_ctx->body = TEST_DYNAMIC_GET_PAYLOAD;
492 		response_ctx->body_len = strlen(response_ctx->body);
493 		response_ctx->final_chunk = true;
494 		break;
495 
496 	case DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_LONG:
497 		if (client->method == HTTP_GET) {
498 			/* Send GET payload split across multiple callbacks */
499 			size_t send_len = (offset == 0) ? strlen(TEST_LONG_PAYLOAD_CHUNK_1)
500 							: strlen(TEST_LONG_PAYLOAD_CHUNK_2);
501 
502 			response_ctx->body = long_payload + offset;
503 			response_ctx->body_len = send_len;
504 			offset += send_len;
505 
506 			if (offset == strlen(long_payload)) {
507 				offset = 0;
508 				response_ctx->final_chunk = true;
509 			}
510 		} else if (client->method == HTTP_POST) {
511 			/* Copy POST payload into buffer for later comparison */
512 			zassert(offset + request_ctx->data_len <=
513 					sizeof(dynamic_response_headers_buffer),
514 				"POST data too long for buffer");
515 			memcpy(dynamic_response_headers_buffer + offset, request_ctx->data,
516 			       request_ctx->data_len);
517 			offset += request_ctx->data_len;
518 
519 			if (status == HTTP_SERVER_DATA_FINAL) {
520 				offset = 0;
521 			}
522 		} else {
523 			zassert(false, "unexpected HTTP method");
524 		}
525 		break;
526 	}
527 
528 	return 0;
529 }
530 
531 struct http_resource_detail_dynamic dynamic_response_headers_detail = {
532 	.common = {
533 		.type = HTTP_RESOURCE_TYPE_DYNAMIC,
534 		.bitmask_of_supported_http_methods = BIT(HTTP_GET) | BIT(HTTP_POST),
535 		.content_type = "text/plain",
536 	},
537 	.cb = dynamic_response_headers_cb,
538 	.user_data = NULL
539 };
540 
541 HTTP_RESOURCE_DEFINE(dynamic_response_headers_resource, test_http_service, "/response_headers",
542 		     &dynamic_response_headers_detail);
543 
544 static int client_fd = -1;
545 static uint8_t buf[BUFFER_SIZE];
546 
547 /* This function ensures that there's at least as much data as requested in
548  * the buffer.
549  */
test_read_data(size_t * offset,size_t need)550 static void test_read_data(size_t *offset, size_t need)
551 {
552 	int ret;
553 
554 	while (*offset < need) {
555 		ret = zsock_recv(client_fd, buf + *offset, sizeof(buf) - *offset, 0);
556 		zassert_not_equal(ret, -1, "recv() failed (%d)", errno);
557 		*offset += ret;
558 		if (ret == 0) {
559 			break;
560 		}
561 	};
562 
563 	zassert_true(*offset >= need, "Not all requested data received");
564 }
565 
566 /* This function moves the remaining data in the buffer to the beginning. */
test_consume_data(size_t * offset,size_t consume)567 static void test_consume_data(size_t *offset, size_t consume)
568 {
569 	zassert_true(*offset >= consume, "Cannot consume more data than received");
570 	*offset -= consume;
571 	memmove(buf, buf + consume, *offset);
572 }
573 
expect_http1_switching_protocols(size_t * offset)574 static void expect_http1_switching_protocols(size_t *offset)
575 {
576 	static const char switching_protocols[] =
577 		"HTTP/1.1 101 Switching Protocols\r\n"
578 		"Connection: Upgrade\r\n"
579 		"Upgrade: h2c\r\n"
580 		"\r\n";
581 
582 	test_read_data(offset, sizeof(switching_protocols) - 1);
583 	zassert_mem_equal(buf, switching_protocols, sizeof(switching_protocols) - 1,
584 			  "Received data doesn't match expected response");
585 	test_consume_data(offset, sizeof(switching_protocols) - 1);
586 }
587 
test_get_frame_header(size_t * offset,struct http2_frame * frame)588 static void test_get_frame_header(size_t *offset, struct http2_frame *frame)
589 {
590 	test_read_data(offset, HTTP2_FRAME_HEADER_SIZE);
591 
592 	frame->length = sys_get_be24(&buf[HTTP2_FRAME_LENGTH_OFFSET]);
593 	frame->type = buf[HTTP2_FRAME_TYPE_OFFSET];
594 	frame->flags = buf[HTTP2_FRAME_FLAGS_OFFSET];
595 	frame->stream_identifier = sys_get_be32(
596 				&buf[HTTP2_FRAME_STREAM_ID_OFFSET]);
597 	frame->stream_identifier &= HTTP2_FRAME_STREAM_ID_MASK;
598 
599 	test_consume_data(offset, HTTP2_FRAME_HEADER_SIZE);
600 }
601 
expect_http2_settings_frame(size_t * offset,bool ack)602 static void expect_http2_settings_frame(size_t *offset, bool ack)
603 {
604 	struct http2_frame frame;
605 
606 	test_get_frame_header(offset, &frame);
607 
608 	zassert_equal(frame.type, HTTP2_SETTINGS_FRAME, "Expected settings frame");
609 	zassert_equal(frame.stream_identifier, 0, "Settings frame stream ID must be 0");
610 
611 	if (ack) {
612 		zassert_equal(frame.length, 0, "Invalid settings frame length");
613 		zassert_equal(frame.flags, HTTP2_FLAG_SETTINGS_ACK,
614 			      "Expected settings ACK flag");
615 	} else {
616 		zassert_equal(frame.length % sizeof(struct http2_settings_field), 0,
617 			      "Invalid settings frame length");
618 		zassert_equal(frame.flags, 0, "Expected no settings flags");
619 
620 		/* Consume settings payload */
621 		test_read_data(offset, frame.length);
622 		test_consume_data(offset, frame.length);
623 	}
624 }
625 
expect_contains_header(const uint8_t * buffer,size_t len,const struct http_header * header)626 static void expect_contains_header(const uint8_t *buffer, size_t len,
627 				   const struct http_header *header)
628 {
629 	int ret;
630 	bool found = false;
631 	struct http_hpack_header_buf header_buf;
632 	size_t consumed = 0;
633 
634 	while (consumed < len) {
635 		ret = http_hpack_decode_header(buffer + consumed, len, &header_buf);
636 		zassert_true(ret >= 0, "Failed to decode header");
637 		zassert_true(consumed + ret <= len, "Frame length exceeded");
638 
639 		if (strncasecmp(header_buf.name, header->name, header_buf.name_len) == 0 &&
640 		    strncasecmp(header_buf.value, header->value, header_buf.value_len) == 0) {
641 			found = true;
642 			break;
643 		}
644 
645 		consumed += ret;
646 	}
647 
648 	zassert_true(found, "Header '%s: %s' not found", header->name, header->value);
649 }
650 
expect_http2_headers_frame(size_t * offset,int stream_id,uint8_t flags,const struct http_header * headers,size_t headers_count)651 static void expect_http2_headers_frame(size_t *offset, int stream_id, uint8_t flags,
652 				       const struct http_header *headers, size_t headers_count)
653 {
654 	struct http2_frame frame;
655 
656 	test_get_frame_header(offset, &frame);
657 
658 	zassert_equal(frame.type, HTTP2_HEADERS_FRAME, "Expected headers frame, got frame type %u",
659 		      frame.type);
660 	zassert_equal(frame.stream_identifier, stream_id,
661 		      "Invalid headers frame stream ID");
662 	zassert_equal(frame.flags, flags, "Unexpected flags received (expected %x got %x)", flags,
663 		      frame.flags);
664 
665 	/* Consume headers payload */
666 	test_read_data(offset, frame.length);
667 
668 	for (size_t i = 0; i < headers_count; i++) {
669 		expect_contains_header(buf, frame.length, &headers[i]);
670 	}
671 
672 	test_consume_data(offset, frame.length);
673 }
674 
675 /* "payload" may be NULL to skip data frame content validation. */
expect_http2_data_frame(size_t * offset,int stream_id,const uint8_t * payload,size_t payload_len,uint8_t flags)676 static void expect_http2_data_frame(size_t *offset, int stream_id,
677 				    const uint8_t *payload, size_t payload_len,
678 				    uint8_t flags)
679 {
680 	struct http2_frame frame;
681 
682 	test_get_frame_header(offset, &frame);
683 
684 	zassert_equal(frame.type, HTTP2_DATA_FRAME, "Expected data frame");
685 	zassert_equal(frame.stream_identifier, stream_id,
686 		      "Invalid data frame stream ID");
687 	zassert_equal(frame.flags, flags, "Unexpected flags received");
688 	if (payload != NULL) {
689 		zassert_equal(frame.length, payload_len,
690 			      "Unexpected data frame length");
691 	}
692 
693 	/* Verify data payload */
694 	test_read_data(offset, frame.length);
695 	if (payload != NULL) {
696 		zassert_mem_equal(buf, payload, payload_len,
697 				  "Unexpected data payload");
698 	}
699 	test_consume_data(offset, frame.length);
700 }
701 
expect_http2_window_update_frame(size_t * offset,int stream_id)702 static void expect_http2_window_update_frame(size_t *offset, int stream_id)
703 {
704 	struct http2_frame frame;
705 
706 	test_get_frame_header(offset, &frame);
707 
708 	zassert_equal(frame.type, HTTP2_WINDOW_UPDATE_FRAME,
709 		      "Expected window update frame");
710 	zassert_equal(frame.stream_identifier, stream_id,
711 		      "Invalid window update frame stream ID (expected %d got %d)", stream_id,
712 		      frame.stream_identifier);
713 	zassert_equal(frame.flags, 0, "Unexpected flags received");
714 	zassert_equal(frame.length, sizeof(uint32_t),
715 		      "Unexpected window update frame length");
716 
717 
718 	/* Consume window update payload */
719 	test_read_data(offset, frame.length);
720 	test_consume_data(offset, frame.length);
721 }
722 
ZTEST(server_function_tests,test_http2_get_concurrent_streams)723 ZTEST(server_function_tests, test_http2_get_concurrent_streams)
724 {
725 	static const uint8_t request_get_2_streams[] = {
726 		TEST_HTTP2_MAGIC,
727 		TEST_HTTP2_SETTINGS,
728 		TEST_HTTP2_SETTINGS_ACK,
729 		TEST_HTTP2_HEADERS_GET_ROOT_STREAM_1,
730 		TEST_HTTP2_HEADERS_GET_INDEX_STREAM_2,
731 		TEST_HTTP2_GOAWAY,
732 	};
733 	size_t offset = 0;
734 	int ret;
735 
736 	ret = zsock_send(client_fd, request_get_2_streams,
737 			 sizeof(request_get_2_streams), 0);
738 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
739 
740 	memset(buf, 0, sizeof(buf));
741 
742 	/* Settings frame is expected twice (server settings + settings ACK) */
743 	expect_http2_settings_frame(&offset, false);
744 	expect_http2_settings_frame(&offset, true);
745 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1, HTTP2_FLAG_END_HEADERS, NULL, 0);
746 	expect_http2_data_frame(&offset, TEST_STREAM_ID_1, TEST_STATIC_PAYLOAD,
747 				strlen(TEST_STATIC_PAYLOAD),
748 				HTTP2_FLAG_END_STREAM);
749 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_2, HTTP2_FLAG_END_HEADERS, NULL, 0);
750 	expect_http2_data_frame(&offset, TEST_STREAM_ID_2, NULL, 0,
751 				HTTP2_FLAG_END_STREAM);
752 }
753 
ZTEST(server_function_tests,test_http2_static_get)754 ZTEST(server_function_tests, test_http2_static_get)
755 {
756 	static const uint8_t request_get_static_simple[] = {
757 		TEST_HTTP2_MAGIC,
758 		TEST_HTTP2_SETTINGS,
759 		TEST_HTTP2_SETTINGS_ACK,
760 		TEST_HTTP2_HEADERS_GET_ROOT_STREAM_1,
761 		TEST_HTTP2_GOAWAY,
762 	};
763 	size_t offset = 0;
764 	int ret;
765 
766 	ret = zsock_send(client_fd, request_get_static_simple,
767 			 sizeof(request_get_static_simple), 0);
768 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
769 
770 	memset(buf, 0, sizeof(buf));
771 
772 	expect_http2_settings_frame(&offset, false);
773 	expect_http2_settings_frame(&offset, true);
774 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1, HTTP2_FLAG_END_HEADERS, NULL, 0);
775 	expect_http2_data_frame(&offset, TEST_STREAM_ID_1, TEST_STATIC_PAYLOAD,
776 				strlen(TEST_STATIC_PAYLOAD),
777 				HTTP2_FLAG_END_STREAM);
778 }
779 
ZTEST(server_function_tests,test_http1_static_upgrade_get)780 ZTEST(server_function_tests, test_http1_static_upgrade_get)
781 {
782 	static const char http1_request[] =
783 		"GET / HTTP/1.1\r\n"
784 		"Host: 127.0.0.1:8080\r\n"
785 		"Accept: */*\r\n"
786 		"Accept-Encoding: deflate, gzip, br\r\n"
787 		"Connection: Upgrade, HTTP2-Settings\r\n"
788 		"Upgrade: h2c\r\n"
789 		"HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA\r\n"
790 		"\r\n";
791 	size_t offset = 0;
792 	int ret;
793 
794 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
795 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
796 
797 	memset(buf, 0, sizeof(buf));
798 
799 	/* Verify HTTP1 switching protocols response. */
800 	expect_http1_switching_protocols(&offset);
801 
802 	/* Verify HTTP2 frames. */
803 	expect_http2_settings_frame(&offset, false);
804 	expect_http2_headers_frame(&offset, UPGRADE_STREAM_ID, HTTP2_FLAG_END_HEADERS, NULL, 0);
805 	expect_http2_data_frame(&offset, UPGRADE_STREAM_ID, TEST_STATIC_PAYLOAD,
806 				strlen(TEST_STATIC_PAYLOAD),
807 				HTTP2_FLAG_END_STREAM);
808 }
809 
ZTEST(server_function_tests,test_http1_static_get)810 ZTEST(server_function_tests, test_http1_static_get)
811 {
812 	static const char http1_request[] =
813 		"GET / HTTP/1.1\r\n"
814 		"Host: 127.0.0.1:8080\r\n"
815 		"User-Agent: curl/7.68.0\r\n"
816 		"Accept: */*\r\n"
817 		"Accept-Encoding: deflate, gzip, br\r\n"
818 		"\r\n";
819 	static const char expected_response[] =
820 		"HTTP/1.1 200 OK\r\n"
821 		"Content-Type: text/html\r\n"
822 		"Content-Length: 13\r\n"
823 		"\r\n"
824 		TEST_STATIC_PAYLOAD;
825 	size_t offset = 0;
826 	int ret;
827 
828 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
829 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
830 
831 	memset(buf, 0, sizeof(buf));
832 
833 	test_read_data(&offset, sizeof(expected_response) - 1);
834 	zassert_mem_equal(buf, expected_response, sizeof(expected_response) - 1,
835 			  "Received data doesn't match expected response");
836 }
837 
838 /* Common code to verify POST/PUT/PATCH */
common_verify_http2_dynamic_post_request(const uint8_t * request,size_t request_len)839 static void common_verify_http2_dynamic_post_request(const uint8_t *request,
840 						     size_t request_len)
841 {
842 	size_t offset = 0;
843 	int ret;
844 
845 	ret = zsock_send(client_fd, request, request_len, 0);
846 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
847 
848 	memset(buf, 0, sizeof(buf));
849 
850 	expect_http2_settings_frame(&offset, false);
851 	expect_http2_settings_frame(&offset, true);
852 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1,
853 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM, NULL, 0);
854 
855 	zassert_equal(dynamic_payload_len, strlen(TEST_DYNAMIC_POST_PAYLOAD),
856 		      "Wrong dynamic resource length");
857 	zassert_mem_equal(dynamic_payload, TEST_DYNAMIC_POST_PAYLOAD,
858 			  dynamic_payload_len, "Wrong dynamic resource data");
859 }
860 
ZTEST(server_function_tests,test_http2_dynamic_post)861 ZTEST(server_function_tests, test_http2_dynamic_post)
862 {
863 	static const uint8_t request_post_dynamic[] = {
864 		TEST_HTTP2_MAGIC,
865 		TEST_HTTP2_SETTINGS,
866 		TEST_HTTP2_SETTINGS_ACK,
867 		TEST_HTTP2_HEADERS_POST_DYNAMIC_STREAM_1,
868 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1,
869 		TEST_HTTP2_GOAWAY,
870 	};
871 
872 	common_verify_http2_dynamic_post_request(request_post_dynamic,
873 						 sizeof(request_post_dynamic));
874 }
875 
876 /* Common code to verify POST/PUT/PATCH */
common_verify_http1_dynamic_upgrade_post(const uint8_t * method)877 static void common_verify_http1_dynamic_upgrade_post(const uint8_t *method)
878 {
879 	static const char http1_request[] =
880 		" /dynamic HTTP/1.1\r\n"
881 		"Host: 127.0.0.1:8080\r\n"
882 		"User-Agent: curl/7.68.0\r\n"
883 		"Accept: */*\r\n"
884 		"Content-Length: 17\r\n"
885 		"Connection: Upgrade, HTTP2-Settings\r\n"
886 		"Upgrade: h2c\r\n"
887 		"HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA\r\n"
888 		"\r\n"
889 		TEST_DYNAMIC_POST_PAYLOAD;
890 	size_t offset = 0;
891 	int ret;
892 
893 	ret = zsock_send(client_fd, method, strlen(method), 0);
894 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
895 
896 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
897 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
898 
899 	memset(buf, 0, sizeof(buf));
900 
901 	/* Verify HTTP1 switching protocols response. */
902 	expect_http1_switching_protocols(&offset);
903 
904 	/* Verify HTTP2 frames. */
905 	expect_http2_settings_frame(&offset, false);
906 	expect_http2_headers_frame(&offset, UPGRADE_STREAM_ID,
907 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM, NULL, 0);
908 
909 	zassert_equal(dynamic_payload_len, strlen(TEST_DYNAMIC_POST_PAYLOAD),
910 		      "Wrong dynamic resource length");
911 	zassert_mem_equal(dynamic_payload, TEST_DYNAMIC_POST_PAYLOAD,
912 			  dynamic_payload_len, "Wrong dynamic resource data");
913 }
914 
ZTEST(server_function_tests,test_http1_dynamic_upgrade_post)915 ZTEST(server_function_tests, test_http1_dynamic_upgrade_post)
916 {
917 	common_verify_http1_dynamic_upgrade_post("POST");
918 }
919 
920 /* Common code to verify POST/PUT/PATCH */
common_verify_http1_dynamic_post(const uint8_t * method)921 static void common_verify_http1_dynamic_post(const uint8_t *method)
922 {
923 	static const char http1_request[] =
924 		" /dynamic HTTP/1.1\r\n"
925 		"Host: 127.0.0.1:8080\r\n"
926 		"User-Agent: curl/7.68.0\r\n"
927 		"Accept: */*\r\n"
928 		"Content-Length: 17\r\n"
929 		"\r\n"
930 		TEST_DYNAMIC_POST_PAYLOAD;
931 	static const char expected_response[] = "HTTP/1.1 200\r\n"
932 						"Transfer-Encoding: chunked\r\n"
933 						"Content-Type: text/plain\r\n"
934 						"\r\n"
935 						"0\r\n\r\n";
936 	size_t offset = 0;
937 	int ret;
938 
939 	ret = zsock_send(client_fd, method, strlen(method), 0);
940 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
941 
942 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
943 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
944 
945 	memset(buf, 0, sizeof(buf));
946 
947 	test_read_data(&offset, sizeof(expected_response) - 1);
948 	zassert_mem_equal(buf, expected_response, sizeof(expected_response) - 1,
949 			  "Received data doesn't match expected response");
950 
951 	zassert_equal(dynamic_payload_len, strlen(TEST_DYNAMIC_POST_PAYLOAD),
952 		      "Wrong dynamic resource length");
953 	zassert_mem_equal(dynamic_payload, TEST_DYNAMIC_POST_PAYLOAD,
954 			  dynamic_payload_len, "Wrong dynamic resource data");
955 }
956 
ZTEST(server_function_tests,test_http1_dynamic_post)957 ZTEST(server_function_tests, test_http1_dynamic_post)
958 {
959 	common_verify_http1_dynamic_post("POST");
960 }
961 
common_verify_http2_dynamic_get_request(const uint8_t * request,size_t request_len)962 static void common_verify_http2_dynamic_get_request(const uint8_t *request,
963 						    size_t request_len)
964 {
965 	size_t offset = 0;
966 	int ret;
967 
968 	dynamic_payload_len = strlen(TEST_DYNAMIC_GET_PAYLOAD);
969 	memcpy(dynamic_payload, TEST_DYNAMIC_GET_PAYLOAD, dynamic_payload_len);
970 
971 	ret = zsock_send(client_fd, request, request_len, 0);
972 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
973 
974 	memset(buf, 0, sizeof(buf));
975 
976 	expect_http2_settings_frame(&offset, false);
977 	expect_http2_settings_frame(&offset, true);
978 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1, HTTP2_FLAG_END_HEADERS, NULL, 0);
979 	expect_http2_data_frame(&offset, TEST_STREAM_ID_1, TEST_DYNAMIC_GET_PAYLOAD,
980 				strlen(TEST_DYNAMIC_GET_PAYLOAD), HTTP2_FLAG_END_STREAM);
981 }
982 
ZTEST(server_function_tests,test_http2_dynamic_get)983 ZTEST(server_function_tests, test_http2_dynamic_get)
984 {
985 	static const uint8_t request_get_dynamic[] = {
986 		TEST_HTTP2_MAGIC,
987 		TEST_HTTP2_SETTINGS,
988 		TEST_HTTP2_SETTINGS_ACK,
989 		TEST_HTTP2_HEADERS_GET_DYNAMIC_STREAM_1,
990 		TEST_HTTP2_GOAWAY,
991 	};
992 
993 	common_verify_http2_dynamic_get_request(request_get_dynamic,
994 						sizeof(request_get_dynamic));
995 }
996 
ZTEST(server_function_tests,test_http1_dynamic_upgrade_get)997 ZTEST(server_function_tests, test_http1_dynamic_upgrade_get)
998 {
999 	static const char http1_request[] =
1000 		"GET /dynamic HTTP/1.1\r\n"
1001 		"Host: 127.0.0.1:8080\r\n"
1002 		"User-Agent: curl/7.68.0\r\n"
1003 		"Accept: */*\r\n"
1004 		"Accept-Encoding: deflate, gzip, br\r\n"
1005 		"Connection: Upgrade, HTTP2-Settings\r\n"
1006 		"Upgrade: h2c\r\n"
1007 		"HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA\r\n"
1008 		"\r\n";
1009 	size_t offset = 0;
1010 	int ret;
1011 
1012 	dynamic_payload_len = strlen(TEST_DYNAMIC_GET_PAYLOAD);
1013 	memcpy(dynamic_payload, TEST_DYNAMIC_GET_PAYLOAD, dynamic_payload_len);
1014 
1015 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
1016 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1017 
1018 	memset(buf, 0, sizeof(buf));
1019 
1020 	/* Verify HTTP1 switching protocols response. */
1021 	expect_http1_switching_protocols(&offset);
1022 
1023 	/* Verify HTTP2 frames. */
1024 	expect_http2_settings_frame(&offset, false);
1025 	expect_http2_headers_frame(&offset, UPGRADE_STREAM_ID, HTTP2_FLAG_END_HEADERS, NULL, 0);
1026 	expect_http2_data_frame(&offset, UPGRADE_STREAM_ID, TEST_DYNAMIC_GET_PAYLOAD,
1027 				strlen(TEST_DYNAMIC_GET_PAYLOAD), HTTP2_FLAG_END_STREAM);
1028 }
1029 
ZTEST(server_function_tests,test_http1_dynamic_get)1030 ZTEST(server_function_tests, test_http1_dynamic_get)
1031 {
1032 	static const char http1_request[] =
1033 		"GET /dynamic HTTP/1.1\r\n"
1034 		"Host: 127.0.0.1:8080\r\n"
1035 		"User-Agent: curl/7.68.0\r\n"
1036 		"Accept: */*\r\n"
1037 		"Accept-Encoding: deflate, gzip, br\r\n"
1038 		"\r\n";
1039 	static const char expected_response[] = "HTTP/1.1 200\r\n"
1040 						"Transfer-Encoding: chunked\r\n"
1041 						"Content-Type: text/plain\r\n"
1042 						"\r\n"
1043 						"10\r\n" TEST_DYNAMIC_GET_PAYLOAD "\r\n"
1044 						"0\r\n\r\n";
1045 	size_t offset = 0;
1046 	int ret;
1047 
1048 	dynamic_payload_len = strlen(TEST_DYNAMIC_GET_PAYLOAD);
1049 	memcpy(dynamic_payload, TEST_DYNAMIC_GET_PAYLOAD, dynamic_payload_len);
1050 
1051 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
1052 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1053 
1054 	memset(buf, 0, sizeof(buf));
1055 
1056 	test_read_data(&offset, sizeof(expected_response) - 1);
1057 	zassert_mem_equal(buf, expected_response, sizeof(expected_response) - 1,
1058 			  "Received data doesn't match expected response");
1059 }
1060 
ZTEST(server_function_tests,test_http2_dynamic_put)1061 ZTEST(server_function_tests, test_http2_dynamic_put)
1062 {
1063 	static const uint8_t request_put_dynamic[] = {
1064 		TEST_HTTP2_MAGIC,
1065 		TEST_HTTP2_SETTINGS,
1066 		TEST_HTTP2_SETTINGS_ACK,
1067 		TEST_HTTP2_HEADERS_PUT_DYNAMIC_STREAM_1,
1068 		TEST_HTTP2_DATA_PUT_DYNAMIC_STREAM_1,
1069 		TEST_HTTP2_GOAWAY,
1070 	};
1071 
1072 	common_verify_http2_dynamic_post_request(request_put_dynamic,
1073 						 sizeof(request_put_dynamic));
1074 }
1075 
ZTEST(server_function_tests,test_http1_dynamic_upgrade_put)1076 ZTEST(server_function_tests, test_http1_dynamic_upgrade_put)
1077 {
1078 	common_verify_http1_dynamic_upgrade_post("PUT");
1079 }
1080 
ZTEST(server_function_tests,test_http1_dynamic_put)1081 ZTEST(server_function_tests, test_http1_dynamic_put)
1082 {
1083 	common_verify_http1_dynamic_post("PUT");
1084 }
1085 
ZTEST(server_function_tests,test_http2_dynamic_patch)1086 ZTEST(server_function_tests, test_http2_dynamic_patch)
1087 {
1088 	static const uint8_t request_patch_dynamic[] = {
1089 		TEST_HTTP2_MAGIC,
1090 		TEST_HTTP2_SETTINGS,
1091 		TEST_HTTP2_SETTINGS_ACK,
1092 		TEST_HTTP2_HEADERS_PATCH_DYNAMIC_STREAM_1,
1093 		TEST_HTTP2_DATA_PATCH_DYNAMIC_STREAM_1,
1094 		TEST_HTTP2_GOAWAY,
1095 	};
1096 
1097 	common_verify_http2_dynamic_post_request(request_patch_dynamic,
1098 						 sizeof(request_patch_dynamic));
1099 }
1100 
ZTEST(server_function_tests,test_http1_dynamic_upgrade_patch)1101 ZTEST(server_function_tests, test_http1_dynamic_upgrade_patch)
1102 {
1103 	common_verify_http1_dynamic_upgrade_post("PATCH");
1104 }
1105 
ZTEST(server_function_tests,test_http1_dynamic_patch)1106 ZTEST(server_function_tests, test_http1_dynamic_patch)
1107 {
1108 	common_verify_http1_dynamic_post("PATCH");
1109 }
1110 
ZTEST(server_function_tests,test_http2_dynamic_delete)1111 ZTEST(server_function_tests, test_http2_dynamic_delete)
1112 {
1113 	static const uint8_t request_delete_dynamic[] = {
1114 		TEST_HTTP2_MAGIC,
1115 		TEST_HTTP2_SETTINGS,
1116 		TEST_HTTP2_SETTINGS_ACK,
1117 		TEST_HTTP2_HEADERS_DELETE_DYNAMIC_STREAM_1,
1118 		TEST_HTTP2_GOAWAY,
1119 	};
1120 	size_t offset = 0;
1121 	int ret;
1122 
1123 	ret = zsock_send(client_fd, request_delete_dynamic,
1124 			 sizeof(request_delete_dynamic), 0);
1125 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1126 
1127 	memset(buf, 0, sizeof(buf));
1128 
1129 	expect_http2_settings_frame(&offset, false);
1130 	expect_http2_settings_frame(&offset, true);
1131 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1,
1132 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM,
1133 				   NULL, 0);
1134 }
1135 
ZTEST(server_function_tests,test_http1_dynamic_upgrade_delete)1136 ZTEST(server_function_tests, test_http1_dynamic_upgrade_delete)
1137 {
1138 	static const char http1_request[] =
1139 		"DELETE /dynamic HTTP/1.1\r\n"
1140 		"Host: 127.0.0.1:8080\r\n"
1141 		"User-Agent: curl/7.68.0\r\n"
1142 		"Connection: Upgrade, HTTP2-Settings\r\n"
1143 		"Upgrade: h2c\r\n"
1144 		"HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA\r\n"
1145 		"\r\n";
1146 	size_t offset = 0;
1147 	int ret;
1148 
1149 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
1150 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1151 
1152 	memset(buf, 0, sizeof(buf));
1153 
1154 	/* Verify HTTP1 switching protocols response. */
1155 	expect_http1_switching_protocols(&offset);
1156 
1157 	/* Verify HTTP2 frames. */
1158 	expect_http2_settings_frame(&offset, false);
1159 	expect_http2_headers_frame(&offset, UPGRADE_STREAM_ID,
1160 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM,
1161 				   NULL, 0);
1162 }
1163 
ZTEST(server_function_tests,test_http1_dynamic_delete)1164 ZTEST(server_function_tests, test_http1_dynamic_delete)
1165 {
1166 	static const char http1_request[] =
1167 		"DELETE /dynamic HTTP/1.1\r\n"
1168 		"Host: 127.0.0.1:8080\r\n"
1169 		"User-Agent: curl/7.68.0\r\n"
1170 		"\r\n";
1171 	static const char expected_response[] = "HTTP/1.1 200\r\n"
1172 						"Transfer-Encoding: chunked\r\n"
1173 						"Content-Type: text/plain\r\n"
1174 						"\r\n"
1175 						"0\r\n\r\n";
1176 	size_t offset = 0;
1177 	int ret;
1178 
1179 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
1180 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1181 
1182 	memset(buf, 0, sizeof(buf));
1183 
1184 	test_read_data(&offset, sizeof(expected_response) - 1);
1185 	zassert_mem_equal(buf, expected_response, sizeof(expected_response) - 1,
1186 			  "Received data doesn't match expected response");
1187 }
1188 
ZTEST(server_function_tests,test_http1_connection_close)1189 ZTEST(server_function_tests, test_http1_connection_close)
1190 {
1191 	static const char http1_request_1[] =
1192 		"GET / HTTP/1.1\r\n"
1193 		"Host: 127.0.0.1:8080\r\n"
1194 		"User-Agent: curl/7.68.0\r\n"
1195 		"Accept: */*\r\n"
1196 		"Accept-Encoding: deflate, gzip, br\r\n"
1197 		"\r\n";
1198 	static const char http1_request_2[] =
1199 		"GET / HTTP/1.1\r\n"
1200 		"Host: 127.0.0.1:8080\r\n"
1201 		"User-Agent: curl/7.68.0\r\n"
1202 		"Accept: */*\r\n"
1203 		"Accept-Encoding: deflate, gzip, br\r\n"
1204 		"Connection: close\r\n"
1205 		"\r\n";
1206 	static const char expected_response[] =
1207 		"HTTP/1.1 200 OK\r\n"
1208 		"Content-Type: text/html\r\n"
1209 		"Content-Length: 13\r\n"
1210 		"\r\n"
1211 		TEST_STATIC_PAYLOAD;
1212 	size_t offset = 0;
1213 	int ret;
1214 
1215 	ret = zsock_send(client_fd, http1_request_1, strlen(http1_request_1), 0);
1216 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1217 
1218 	memset(buf, 0, sizeof(buf));
1219 
1220 	test_read_data(&offset, sizeof(expected_response) - 1);
1221 	zassert_mem_equal(buf, expected_response, sizeof(expected_response) - 1,
1222 			  "Received data doesn't match expected response");
1223 	test_consume_data(&offset, sizeof(expected_response) - 1);
1224 
1225 	/* With no connection: close, the server shall serve another request on
1226 	 * the same connection.
1227 	 */
1228 	ret = zsock_send(client_fd, http1_request_2, strlen(http1_request_2), 0);
1229 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1230 
1231 	memset(buf, 0, sizeof(buf));
1232 
1233 	test_read_data(&offset, sizeof(expected_response) - 1);
1234 	zassert_mem_equal(buf, expected_response, sizeof(expected_response) - 1,
1235 			  "Received data doesn't match expected response");
1236 	test_consume_data(&offset, sizeof(expected_response) - 1);
1237 
1238 	/* Second request included connection: close, so we should expect the
1239 	 * connection to be closed now.
1240 	 */
1241 	ret = zsock_recv(client_fd, buf, sizeof(buf), 0);
1242 	zassert_equal(ret, 0, "Connection should've been closed");
1243 }
1244 
ZTEST(server_function_tests,test_http2_post_data_with_padding)1245 ZTEST(server_function_tests, test_http2_post_data_with_padding)
1246 {
1247 	static const uint8_t request_post_dynamic[] = {
1248 		TEST_HTTP2_MAGIC,
1249 		TEST_HTTP2_SETTINGS,
1250 		TEST_HTTP2_SETTINGS_ACK,
1251 		TEST_HTTP2_HEADERS_POST_DYNAMIC_STREAM_1,
1252 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1_PADDED,
1253 		TEST_HTTP2_GOAWAY,
1254 	};
1255 
1256 	common_verify_http2_dynamic_post_request(request_post_dynamic,
1257 						 sizeof(request_post_dynamic));
1258 }
1259 
ZTEST(server_function_tests,test_http2_post_headers_with_priority)1260 ZTEST(server_function_tests, test_http2_post_headers_with_priority)
1261 {
1262 	static const uint8_t request_post_dynamic[] = {
1263 		TEST_HTTP2_MAGIC,
1264 		TEST_HTTP2_SETTINGS,
1265 		TEST_HTTP2_SETTINGS_ACK,
1266 		TEST_HTTP2_HEADERS_POST_DYNAMIC_STREAM_1_PRIORITY,
1267 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1_PADDED,
1268 		TEST_HTTP2_GOAWAY,
1269 	};
1270 
1271 	common_verify_http2_dynamic_post_request(request_post_dynamic,
1272 						 sizeof(request_post_dynamic));
1273 }
1274 
ZTEST(server_function_tests,test_http2_post_headers_with_priority_and_padding)1275 ZTEST(server_function_tests, test_http2_post_headers_with_priority_and_padding)
1276 {
1277 	static const uint8_t request_post_dynamic[] = {
1278 		TEST_HTTP2_MAGIC,
1279 		TEST_HTTP2_SETTINGS,
1280 		TEST_HTTP2_SETTINGS_ACK,
1281 		TEST_HTTP2_HEADERS_POST_DYNAMIC_STREAM_1_PRIORITY_PADDED,
1282 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1_PADDED,
1283 		TEST_HTTP2_GOAWAY,
1284 	};
1285 
1286 	common_verify_http2_dynamic_post_request(request_post_dynamic,
1287 						 sizeof(request_post_dynamic));
1288 }
1289 
ZTEST(server_function_tests,test_http2_post_headers_with_continuation)1290 ZTEST(server_function_tests, test_http2_post_headers_with_continuation)
1291 {
1292 	static const uint8_t request_post_dynamic[] = {
1293 		TEST_HTTP2_MAGIC,
1294 		TEST_HTTP2_SETTINGS,
1295 		TEST_HTTP2_SETTINGS_ACK,
1296 		TEST_HTTP2_PARTIAL_HEADERS_POST_DYNAMIC_STREAM_1,
1297 		TEST_HTTP2_CONTINUATION_POST_DYNAMIC_STREAM_1,
1298 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1,
1299 		TEST_HTTP2_GOAWAY,
1300 	};
1301 
1302 	common_verify_http2_dynamic_post_request(request_post_dynamic,
1303 						 sizeof(request_post_dynamic));
1304 }
1305 
ZTEST(server_function_tests,test_http2_post_missing_continuation)1306 ZTEST(server_function_tests, test_http2_post_missing_continuation)
1307 {
1308 	static const uint8_t request_post_dynamic[] = {
1309 		TEST_HTTP2_MAGIC,
1310 		TEST_HTTP2_SETTINGS,
1311 		TEST_HTTP2_SETTINGS_ACK,
1312 		TEST_HTTP2_PARTIAL_HEADERS_POST_DYNAMIC_STREAM_1,
1313 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1,
1314 		TEST_HTTP2_GOAWAY,
1315 	};
1316 	size_t offset = 0;
1317 	int ret;
1318 
1319 	memset(buf, 0, sizeof(buf));
1320 
1321 	ret = zsock_send(client_fd, request_post_dynamic,
1322 			 sizeof(request_post_dynamic), 0);
1323 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1324 
1325 	/* Expect settings, but processing headers (and lack of continuation
1326 	 * frame) should break the stream, and trigger disconnect.
1327 	 */
1328 	expect_http2_settings_frame(&offset, false);
1329 	expect_http2_settings_frame(&offset, true);
1330 
1331 	ret = zsock_recv(client_fd, buf, sizeof(buf), 0);
1332 	zassert_equal(ret, 0, "Connection should've been closed");
1333 }
1334 
ZTEST(server_function_tests,test_http2_post_trailing_headers)1335 ZTEST(server_function_tests, test_http2_post_trailing_headers)
1336 {
1337 	static const uint8_t request_post_dynamic[] = {
1338 		TEST_HTTP2_MAGIC,
1339 		TEST_HTTP2_SETTINGS,
1340 		TEST_HTTP2_SETTINGS_ACK,
1341 		TEST_HTTP2_HEADERS_POST_DYNAMIC_STREAM_1,
1342 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1_NO_END_STREAM,
1343 		TEST_HTTP2_TRAILING_HEADER_STREAM_1,
1344 		TEST_HTTP2_GOAWAY,
1345 	};
1346 	size_t offset = 0;
1347 	int ret;
1348 
1349 	ret = zsock_send(client_fd, request_post_dynamic,
1350 			 sizeof(request_post_dynamic), 0);
1351 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1352 
1353 	memset(buf, 0, sizeof(buf));
1354 
1355 	expect_http2_settings_frame(&offset, false);
1356 	expect_http2_settings_frame(&offset, true);
1357 	/* In this case order is reversed, data frame had not END_STREAM flag.
1358 	 * Because of this, reply will only be sent after processing the final
1359 	 * trailing headers frame, but this will be preceded by window update
1360 	 * after processing the data frame.
1361 	 */
1362 	expect_http2_window_update_frame(&offset, TEST_STREAM_ID_1);
1363 	expect_http2_window_update_frame(&offset, 0);
1364 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1,
1365 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM, NULL, 0);
1366 
1367 	zassert_equal(dynamic_payload_len, strlen(TEST_DYNAMIC_POST_PAYLOAD),
1368 		      "Wrong dynamic resource length");
1369 	zassert_mem_equal(dynamic_payload, TEST_DYNAMIC_POST_PAYLOAD,
1370 			  dynamic_payload_len, "Wrong dynamic resource data");
1371 }
1372 
ZTEST(server_function_tests,test_http2_get_headers_with_padding)1373 ZTEST(server_function_tests, test_http2_get_headers_with_padding)
1374 {
1375 	static const uint8_t request_get_dynamic[] = {
1376 		TEST_HTTP2_MAGIC,
1377 		TEST_HTTP2_SETTINGS,
1378 		TEST_HTTP2_SETTINGS_ACK,
1379 		TEST_HTTP2_HEADERS_GET_DYNAMIC_STREAM_1_PADDED,
1380 		TEST_HTTP2_GOAWAY,
1381 	};
1382 
1383 	common_verify_http2_dynamic_get_request(request_get_dynamic,
1384 						sizeof(request_get_dynamic));
1385 }
1386 
ZTEST(server_function_tests,test_http2_rst_stream)1387 ZTEST(server_function_tests, test_http2_rst_stream)
1388 {
1389 	static const uint8_t request_rst_stream[] = {
1390 		TEST_HTTP2_MAGIC,
1391 		TEST_HTTP2_SETTINGS,
1392 		TEST_HTTP2_SETTINGS_ACK,
1393 		TEST_HTTP2_HEADERS_POST_DYNAMIC_STREAM_1,
1394 		TEST_HTTP2_RST_STREAM_STREAM_1,
1395 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1,
1396 		TEST_HTTP2_GOAWAY,
1397 	};
1398 
1399 	size_t offset = 0;
1400 	int ret;
1401 
1402 	memset(buf, 0, sizeof(buf));
1403 
1404 	ret = zsock_send(client_fd, request_rst_stream,
1405 			 sizeof(request_rst_stream), 0);
1406 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1407 
1408 	/* Expect settings, but processing RST_STREAM should close the stream,
1409 	 * so DATA frame should trigger connection error (closed stream) and
1410 	 * disconnect.
1411 	 */
1412 	expect_http2_settings_frame(&offset, false);
1413 	expect_http2_settings_frame(&offset, true);
1414 
1415 	ret = zsock_recv(client_fd, buf, sizeof(buf), 0);
1416 	zassert_equal(ret, 0, "Connection should've been closed");
1417 }
1418 
1419 static const char http1_header_capture_common_response[] = "HTTP/1.1 200\r\n"
1420 							   "Transfer-Encoding: chunked\r\n"
1421 							   "Content-Type: text/plain\r\n"
1422 							   "\r\n"
1423 							   "0\r\n\r\n";
1424 
test_http1_header_capture_common(const char * request)1425 static void test_http1_header_capture_common(const char *request)
1426 {
1427 	size_t offset = 0;
1428 	int ret;
1429 
1430 	ret = zsock_send(client_fd, request, strlen(request), 0);
1431 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1432 
1433 	test_read_data(&offset, sizeof(http1_header_capture_common_response) - 1);
1434 }
1435 
ZTEST(server_function_tests,test_http1_header_capture)1436 ZTEST(server_function_tests, test_http1_header_capture)
1437 {
1438 	static const char request[] = "GET /header_capture HTTP/1.1\r\n"
1439 				      "User-Agent: curl/7.68.0\r\n"
1440 				      "Test-Header: test_value\r\n"
1441 				      "Accept: */*\r\n"
1442 				      "Accept-Encoding: deflate, gzip, br\r\n"
1443 				      "\r\n";
1444 	struct http_header *hdrs = request_headers_clone.headers;
1445 	int ret;
1446 
1447 	test_http1_header_capture_common(request);
1448 
1449 	zassert_equal(request_headers_clone.count, 2,
1450 		      "Didn't capture the expected number of headers");
1451 	zassert_equal(request_headers_clone.status, HTTP_HEADER_STATUS_OK,
1452 		      "Header capture status was not OK");
1453 
1454 	zassert_not_equal(hdrs[0].name, NULL, "First header name is NULL");
1455 	zassert_not_equal(hdrs[0].value, NULL, "First header value is NULL");
1456 	zassert_not_equal(hdrs[1].name, NULL, "Second header name is NULL");
1457 	zassert_not_equal(hdrs[1].value, NULL, "Second header value is NULL");
1458 
1459 	ret = strcmp(hdrs[0].name, "User-Agent");
1460 	zassert_equal(0, ret, "Header strings did not match");
1461 	ret = strcmp(hdrs[0].value, "curl/7.68.0");
1462 	zassert_equal(0, ret, "Header strings did not match");
1463 	ret = strcmp(hdrs[1].name, "Test-Header");
1464 	zassert_equal(0, ret, "Header strings did not match");
1465 	ret = strcmp(hdrs[1].value, "test_value");
1466 	zassert_equal(0, ret, "Header strings did not match");
1467 }
1468 
ZTEST(server_function_tests,test_http1_header_too_long)1469 ZTEST(server_function_tests, test_http1_header_too_long)
1470 {
1471 	static const char request[] =
1472 		"GET /header_capture HTTP/1.1\r\n"
1473 		"User-Agent: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n"
1474 		"Test-Header: test_value\r\n"
1475 		"Accept: */*\r\n"
1476 		"Accept-Encoding: deflate, gzip, br\r\n"
1477 		"\r\n";
1478 	struct http_header *hdrs = request_headers_clone.headers;
1479 	int ret;
1480 
1481 	test_http1_header_capture_common(request);
1482 
1483 	zassert_equal(request_headers_clone.count, 1,
1484 		      "Didn't capture the expected number of headers");
1485 	zassert_equal(request_headers_clone.status, HTTP_HEADER_STATUS_DROPPED,
1486 		      "Header capture status was OK, but should not have been");
1487 
1488 	/* First header too long should not stop second header being captured into first slot */
1489 	zassert_not_equal(hdrs[0].name, NULL, "First header name is NULL");
1490 	zassert_not_equal(hdrs[0].value, NULL, "First header value is NULL");
1491 
1492 	ret = strcmp(hdrs[0].name, "Test-Header");
1493 	zassert_equal(0, ret, "Header strings did not match");
1494 	ret = strcmp(hdrs[0].value, "test_value");
1495 	zassert_equal(0, ret, "Header strings did not match");
1496 }
1497 
ZTEST(server_function_tests,test_http1_header_too_many)1498 ZTEST(server_function_tests, test_http1_header_too_many)
1499 {
1500 	static const char request[] = "GET /header_capture HTTP/1.1\r\n"
1501 				      "User-Agent: curl/7.68.0\r\n"
1502 				      "Test-Header: test_value\r\n"
1503 				      "Test-Header2: test_value2\r\n"
1504 				      "Accept: */*\r\n"
1505 				      "Accept-Encoding: deflate, gzip, br\r\n"
1506 				      "\r\n";
1507 	struct http_header *hdrs = request_headers_clone.headers;
1508 	int ret;
1509 
1510 	test_http1_header_capture_common(request);
1511 
1512 	zassert_equal(request_headers_clone.count, 2,
1513 		      "Didn't capture the expected number of headers");
1514 	zassert_equal(request_headers_clone.status, HTTP_HEADER_STATUS_DROPPED,
1515 		      "Header capture status OK, but should not have been");
1516 
1517 	zassert_not_equal(hdrs[0].name, NULL, "First header name is NULL");
1518 	zassert_not_equal(hdrs[0].value, NULL, "First header value is NULL");
1519 	zassert_not_equal(hdrs[1].name, NULL, "Second header name is NULL");
1520 	zassert_not_equal(hdrs[1].value, NULL, "Second header value is NULL");
1521 
1522 	ret = strcmp(hdrs[0].name, "User-Agent");
1523 	zassert_equal(0, ret, "Header strings did not match");
1524 	ret = strcmp(hdrs[0].value, "curl/7.68.0");
1525 	zassert_equal(0, ret, "Header strings did not match");
1526 	ret = strcmp(hdrs[1].name, "Test-Header");
1527 	zassert_equal(0, ret, "Header strings did not match");
1528 	ret = strcmp(hdrs[1].value, "test_value");
1529 	zassert_equal(0, ret, "Header strings did not match");
1530 }
1531 
common_verify_http2_get_header_capture_request(const uint8_t * request,size_t request_len)1532 static void common_verify_http2_get_header_capture_request(const uint8_t *request,
1533 							   size_t request_len)
1534 {
1535 	size_t offset = 0;
1536 	int ret;
1537 
1538 	dynamic_payload_len = strlen(TEST_DYNAMIC_GET_PAYLOAD);
1539 	memcpy(dynamic_payload, TEST_DYNAMIC_GET_PAYLOAD, dynamic_payload_len);
1540 
1541 	ret = zsock_send(client_fd, request, request_len, 0);
1542 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1543 
1544 	memset(buf, 0, sizeof(buf));
1545 
1546 	expect_http2_settings_frame(&offset, false);
1547 	expect_http2_settings_frame(&offset, true);
1548 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1,
1549 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM, NULL, 0);
1550 }
1551 
ZTEST(server_function_tests,test_http2_header_capture)1552 ZTEST(server_function_tests, test_http2_header_capture)
1553 {
1554 	static const uint8_t request[] = {
1555 		TEST_HTTP2_MAGIC,
1556 		TEST_HTTP2_SETTINGS,
1557 		TEST_HTTP2_SETTINGS_ACK,
1558 		TEST_HTTP2_HEADERS_GET_HEADER_CAPTURE1_STREAM_1,
1559 		TEST_HTTP2_GOAWAY,
1560 	};
1561 	struct http_header *hdrs = request_headers_clone.headers;
1562 	int ret;
1563 
1564 	common_verify_http2_get_header_capture_request(request, sizeof(request));
1565 
1566 	zassert_equal(request_headers_clone.count, 2,
1567 		      "Didn't capture the expected number of headers");
1568 	zassert_equal(request_headers_clone.status, HTTP_HEADER_STATUS_OK,
1569 		      "Header capture status was not OK");
1570 
1571 	zassert_not_equal(hdrs[0].name, NULL, "First header name is NULL");
1572 	zassert_not_equal(hdrs[0].value, NULL, "First header value is NULL");
1573 	zassert_not_equal(hdrs[1].name, NULL, "Second header name is NULL");
1574 	zassert_not_equal(hdrs[1].value, NULL, "Second header value is NULL");
1575 
1576 	ret = strcmp(hdrs[0].name, "User-Agent");
1577 	zassert_equal(0, ret, "Header strings did not match");
1578 	ret = strcmp(hdrs[0].value, "curl/7.81.0");
1579 	zassert_equal(0, ret, "Header strings did not match");
1580 	ret = strcmp(hdrs[1].name, "Test-Header");
1581 	zassert_equal(0, ret, "Header strings did not match");
1582 	ret = strcmp(hdrs[1].value, "test_value");
1583 	zassert_equal(0, ret, "Header strings did not match");
1584 }
1585 
ZTEST(server_function_tests,test_http2_header_too_long)1586 ZTEST(server_function_tests, test_http2_header_too_long)
1587 {
1588 	static const uint8_t request[] = {
1589 		TEST_HTTP2_MAGIC,
1590 		TEST_HTTP2_SETTINGS,
1591 		TEST_HTTP2_SETTINGS_ACK,
1592 		TEST_HTTP2_HEADERS_GET_HEADER_CAPTURE2_STREAM_1,
1593 		TEST_HTTP2_GOAWAY,
1594 	};
1595 	struct http_header *hdrs = request_headers_clone.headers;
1596 	int ret;
1597 
1598 	common_verify_http2_get_header_capture_request(request, sizeof(request));
1599 
1600 	zassert_equal(request_headers_clone.count, 1,
1601 		      "Didn't capture the expected number of headers");
1602 	zassert_equal(request_headers_clone.status, HTTP_HEADER_STATUS_DROPPED,
1603 		      "Header capture status was OK, but should not have been");
1604 
1605 	/* First header too long should not stop second header being captured into first slot */
1606 	zassert_not_equal(hdrs[0].name, NULL, "First header name is NULL");
1607 	zassert_not_equal(hdrs[0].value, NULL, "First header value is NULL");
1608 
1609 	ret = strcmp(hdrs[0].name, "Test-Header");
1610 	zassert_equal(0, ret, "Header strings did not match");
1611 	ret = strcmp(hdrs[0].value, "test_value");
1612 	zassert_equal(0, ret, "Header strings did not match");
1613 }
1614 
ZTEST(server_function_tests,test_http2_header_too_many)1615 ZTEST(server_function_tests, test_http2_header_too_many)
1616 {
1617 	static const uint8_t request[] = {
1618 		TEST_HTTP2_MAGIC,
1619 		TEST_HTTP2_SETTINGS,
1620 		TEST_HTTP2_SETTINGS_ACK,
1621 		TEST_HTTP2_HEADERS_GET_HEADER_CAPTURE3_STREAM_1,
1622 		TEST_HTTP2_GOAWAY,
1623 	};
1624 	struct http_header *hdrs = request_headers_clone.headers;
1625 	int ret;
1626 
1627 	common_verify_http2_get_header_capture_request(request, sizeof(request));
1628 
1629 	zassert_equal(request_headers_clone.count, 2,
1630 		      "Didn't capture the expected number of headers");
1631 	zassert_equal(request_headers_clone.status, HTTP_HEADER_STATUS_DROPPED,
1632 		      "Header capture status OK, but should not have been");
1633 
1634 	zassert_not_equal(hdrs[0].name, NULL, "First header name is NULL");
1635 	zassert_not_equal(hdrs[0].value, NULL, "First header value is NULL");
1636 	zassert_not_equal(hdrs[1].name, NULL, "Second header name is NULL");
1637 	zassert_not_equal(hdrs[1].value, NULL, "Second header value is NULL");
1638 
1639 	ret = strcmp(hdrs[0].name, "User-Agent");
1640 	zassert_equal(0, ret, "Header strings did not match");
1641 	ret = strcmp(hdrs[0].value, "curl/7.81.0");
1642 	zassert_equal(0, ret, "Header strings did not match");
1643 	ret = strcmp(hdrs[1].name, "Test-Header");
1644 	zassert_equal(0, ret, "Header strings did not match");
1645 	ret = strcmp(hdrs[1].value, "test_value");
1646 	zassert_equal(0, ret, "Header strings did not match");
1647 }
1648 
ZTEST(server_function_tests,test_http2_header_concurrent)1649 ZTEST(server_function_tests, test_http2_header_concurrent)
1650 {
1651 	/* Two POST requests which are concurrent, ie. headers1, headers2, data1, data2 */
1652 	static const uint8_t request[] = {
1653 		TEST_HTTP2_MAGIC,
1654 		TEST_HTTP2_SETTINGS,
1655 		TEST_HTTP2_SETTINGS_ACK,
1656 		TEST_HTTP2_HEADERS_POST_HEADER_CAPTURE_WITH_TESTHEADER_STREAM_1,
1657 		TEST_HTTP2_HEADERS_POST_HEADER_CAPTURE2_NO_TESTHEADER_STREAM_2,
1658 		TEST_HTTP2_DATA_POST_HEADER_CAPTURE_STREAM_1,
1659 		TEST_HTTP2_DATA_POST_HEADER_CAPTURE_STREAM_2,
1660 		TEST_HTTP2_GOAWAY,
1661 	};
1662 
1663 	struct http_header *hdrs = request_headers_clone.headers;
1664 	struct http_header *hdrs2 = request_headers_clone2.headers;
1665 	int ret;
1666 	size_t offset = 0;
1667 
1668 	ret = zsock_send(client_fd, request, sizeof(request), 0);
1669 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1670 
1671 	/* Wait for response on both resources before checking captured headers */
1672 	expect_http2_settings_frame(&offset, false);
1673 	expect_http2_settings_frame(&offset, true);
1674 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1,
1675 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM, NULL, 0);
1676 	expect_http2_window_update_frame(&offset, TEST_STREAM_ID_1);
1677 	expect_http2_window_update_frame(&offset, 0);
1678 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_2,
1679 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM, NULL, 0);
1680 
1681 	/* Headers captured on /header_capture path should have two headers including the
1682 	 * Test-Header
1683 	 */
1684 	zassert_equal(request_headers_clone.count, 2,
1685 		      "Didn't capture the expected number of headers");
1686 
1687 	zassert_not_equal(hdrs[0].name, NULL, "First header name is NULL");
1688 	zassert_not_equal(hdrs[0].value, NULL, "First header value is NULL");
1689 	zassert_not_equal(hdrs[1].name, NULL, "Second header name is NULL");
1690 	zassert_not_equal(hdrs[1].value, NULL, "Second header value is NULL");
1691 
1692 	ret = strcmp(hdrs[0].name, "User-Agent");
1693 	zassert_equal(0, ret, "Header strings did not match");
1694 	ret = strcmp(hdrs[0].value, "curl/7.81.0");
1695 	zassert_equal(0, ret, "Header strings did not match");
1696 	ret = strcmp(hdrs[1].name, "Test-Header");
1697 	zassert_equal(0, ret, "Header strings did not match");
1698 	ret = strcmp(hdrs[1].value, "test_value");
1699 	zassert_equal(0, ret, "Header strings did not match");
1700 
1701 	/* Headers captured on the /header_capture2 path should have only one header, not including
1702 	 * the Test-Header
1703 	 */
1704 	zassert_equal(request_headers_clone2.count, 1,
1705 		      "Didn't capture the expected number of headers");
1706 
1707 	zassert_not_equal(hdrs2[0].name, NULL, "First header name is NULL");
1708 	zassert_not_equal(hdrs2[0].value, NULL, "First header value is NULL");
1709 
1710 	ret = strcmp(hdrs2[0].name, "User-Agent");
1711 	zassert_equal(0, ret, "Header strings did not match");
1712 	ret = strcmp(hdrs2[0].value, "curl/7.81.0");
1713 	zassert_equal(0, ret, "Header strings did not match");
1714 }
1715 
test_http1_dynamic_response_headers(const char * request,const char * expected_response)1716 static void test_http1_dynamic_response_headers(const char *request, const char *expected_response)
1717 {
1718 	int ret;
1719 	size_t offset = 0;
1720 
1721 	ret = zsock_send(client_fd, request, strlen(request), 0);
1722 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1723 
1724 	test_read_data(&offset, strlen(expected_response));
1725 	zassert_mem_equal(buf, expected_response, strlen(expected_response));
1726 }
1727 
test_http1_dynamic_response_headers_default(const char * expected_response,bool post)1728 static void test_http1_dynamic_response_headers_default(const char *expected_response, bool post)
1729 {
1730 	static const char http1_get_response_headers_request[] =
1731 		"GET /response_headers HTTP/1.1\r\n"
1732 		"Accept: */*\r\n"
1733 		"\r\n";
1734 	static const char http1_post_response_headers_request[] =
1735 		"POST /response_headers HTTP/1.1\r\n"
1736 		"Accept: */*\r\n"
1737 		"Content-Length: 17\r\n"
1738 		"\r\n" TEST_DYNAMIC_POST_PAYLOAD;
1739 	const char *request =
1740 		post ? http1_post_response_headers_request : http1_get_response_headers_request;
1741 
1742 	test_http1_dynamic_response_headers(request, expected_response);
1743 }
1744 
test_http2_dynamic_response_headers(const uint8_t * request,size_t request_len,const struct http_header * expected_headers,size_t expected_headers_count,bool end_stream,size_t * offset)1745 static void test_http2_dynamic_response_headers(const uint8_t *request, size_t request_len,
1746 						const struct http_header *expected_headers,
1747 						size_t expected_headers_count, bool end_stream,
1748 						size_t *offset)
1749 {
1750 	int ret;
1751 	const uint8_t expected_flags = end_stream ? HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM
1752 						  : HTTP2_FLAG_END_HEADERS;
1753 
1754 	ret = zsock_send(client_fd, request, request_len, 0);
1755 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1756 
1757 	expect_http2_settings_frame(offset, false);
1758 	expect_http2_settings_frame(offset, true);
1759 	expect_http2_headers_frame(offset, TEST_STREAM_ID_1, expected_flags, expected_headers,
1760 				   expected_headers_count);
1761 }
1762 
test_http2_dynamic_response_headers_default(const struct http_header * expected_headers,size_t expected_headers_count,bool post,bool end_stream,size_t * offset)1763 static void test_http2_dynamic_response_headers_default(const struct http_header *expected_headers,
1764 							size_t expected_headers_count, bool post,
1765 							bool end_stream, size_t *offset)
1766 {
1767 	const uint8_t http2_get_response_headers_request[] = {
1768 		TEST_HTTP2_MAGIC,
1769 		TEST_HTTP2_SETTINGS,
1770 		TEST_HTTP2_SETTINGS_ACK,
1771 		TEST_HTTP2_HEADERS_GET_RESPONSE_HEADERS_STREAM_1,
1772 		TEST_HTTP2_GOAWAY,
1773 	};
1774 	const uint8_t http2_post_response_headers_request[] = {
1775 		TEST_HTTP2_MAGIC,
1776 		TEST_HTTP2_SETTINGS,
1777 		TEST_HTTP2_SETTINGS_ACK,
1778 		TEST_HTTP2_HEADERS_POST_RESPONSE_HEADERS_STREAM_1,
1779 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1,
1780 		TEST_HTTP2_GOAWAY,
1781 	};
1782 	const uint8_t *request =
1783 		post ? http2_post_response_headers_request : http2_get_response_headers_request;
1784 	size_t request_len = post ? sizeof(http2_post_response_headers_request)
1785 				  : sizeof(http2_get_response_headers_request);
1786 
1787 	test_http2_dynamic_response_headers(request, request_len, expected_headers,
1788 					    expected_headers_count, end_stream, offset);
1789 }
1790 
test_http1_dynamic_response_header_none(bool post)1791 static void test_http1_dynamic_response_header_none(bool post)
1792 {
1793 	static const char response[] = "HTTP/1.1 200\r\n"
1794 				       "Transfer-Encoding: chunked\r\n"
1795 				       "Content-Type: text/plain\r\n"
1796 				       "\r\n"
1797 				       "0\r\n\r\n";
1798 
1799 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_NONE;
1800 
1801 	test_http1_dynamic_response_headers_default(response, post);
1802 }
1803 
ZTEST(server_function_tests,test_http1_dynamic_get_response_header_none)1804 ZTEST(server_function_tests, test_http1_dynamic_get_response_header_none)
1805 {
1806 	test_http1_dynamic_response_header_none(false);
1807 }
1808 
ZTEST(server_function_tests,test_http1_dynamic_post_response_header_none)1809 ZTEST(server_function_tests, test_http1_dynamic_post_response_header_none)
1810 {
1811 	test_http1_dynamic_response_header_none(true);
1812 }
1813 
test_http2_dynamic_response_header_none(bool post)1814 static void test_http2_dynamic_response_header_none(bool post)
1815 {
1816 	size_t offset = 0;
1817 	const struct http_header expected_headers[] = {
1818 		{.name = ":status", .value = "200"},
1819 		{.name = "content-type", .value = "text/plain"},
1820 	};
1821 
1822 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_NONE;
1823 
1824 	test_http2_dynamic_response_headers_default(expected_headers, ARRAY_SIZE(expected_headers),
1825 						    post, true, &offset);
1826 }
1827 
ZTEST(server_function_tests,test_http2_dynamic_get_response_header_none)1828 ZTEST(server_function_tests, test_http2_dynamic_get_response_header_none)
1829 {
1830 	test_http2_dynamic_response_header_none(false);
1831 }
1832 
ZTEST(server_function_tests,test_http2_dynamic_post_response_header_none)1833 ZTEST(server_function_tests, test_http2_dynamic_post_response_header_none)
1834 {
1835 	test_http2_dynamic_response_header_none(true);
1836 }
1837 
test_http1_dynamic_response_header_422(bool post)1838 static void test_http1_dynamic_response_header_422(bool post)
1839 {
1840 	static const char response[] = "HTTP/1.1 422\r\n"
1841 				       "Transfer-Encoding: chunked\r\n"
1842 				       "Content-Type: text/plain\r\n"
1843 				       "\r\n"
1844 				       "0\r\n\r\n";
1845 
1846 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_422;
1847 
1848 	test_http1_dynamic_response_headers_default(response, post);
1849 }
1850 
ZTEST(server_function_tests,test_http1_dynamic_get_response_header_422)1851 ZTEST(server_function_tests, test_http1_dynamic_get_response_header_422)
1852 {
1853 	test_http1_dynamic_response_header_422(false);
1854 }
1855 
ZTEST(server_function_tests,test_http1_dynamic_post_response_header_422)1856 ZTEST(server_function_tests, test_http1_dynamic_post_response_header_422)
1857 {
1858 	test_http1_dynamic_response_header_422(true);
1859 }
1860 
test_http2_dynamic_response_header_422(bool post)1861 static void test_http2_dynamic_response_header_422(bool post)
1862 {
1863 	size_t offset = 0;
1864 	const struct http_header expected_headers[] = {
1865 		{.name = ":status", .value = "422"},
1866 		{.name = "content-type", .value = "text/plain"},
1867 	};
1868 
1869 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_422;
1870 
1871 	test_http2_dynamic_response_headers_default(expected_headers, ARRAY_SIZE(expected_headers),
1872 						    post, true, &offset);
1873 }
1874 
ZTEST(server_function_tests,test_http2_dynamic_get_response_header_422)1875 ZTEST(server_function_tests, test_http2_dynamic_get_response_header_422)
1876 {
1877 	test_http2_dynamic_response_header_422(false);
1878 }
1879 
ZTEST(server_function_tests,test_http2_dynamic_post_response_header_422)1880 ZTEST(server_function_tests, test_http2_dynamic_post_response_header_422)
1881 {
1882 	test_http2_dynamic_response_header_422(true);
1883 }
1884 
test_http1_dynamic_response_header_extra(bool post)1885 static void test_http1_dynamic_response_header_extra(bool post)
1886 {
1887 	static const char response[] = "HTTP/1.1 200\r\n"
1888 				       "Transfer-Encoding: chunked\r\n"
1889 				       "Test-Header: test_data\r\n"
1890 				       "Content-Type: text/plain\r\n"
1891 				       "\r\n"
1892 				       "0\r\n\r\n";
1893 
1894 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_EXTRA_HEADER;
1895 
1896 	test_http1_dynamic_response_headers_default(response, post);
1897 }
1898 
ZTEST(server_function_tests,test_http1_dynamic_get_response_header_extra)1899 ZTEST(server_function_tests, test_http1_dynamic_get_response_header_extra)
1900 {
1901 	test_http1_dynamic_response_header_extra(false);
1902 }
1903 
ZTEST(server_function_tests,test_http1_dynamic_post_response_header_extra)1904 ZTEST(server_function_tests, test_http1_dynamic_post_response_header_extra)
1905 {
1906 	test_http1_dynamic_response_header_extra(true);
1907 }
1908 
test_http2_dynamic_response_header_extra(bool post)1909 static void test_http2_dynamic_response_header_extra(bool post)
1910 {
1911 	size_t offset = 0;
1912 	const struct http_header expected_headers[] = {
1913 		{.name = ":status", .value = "200"},
1914 		{.name = "content-type", .value = "text/plain"},
1915 		{.name = "test-header", .value = "test_data"},
1916 	};
1917 
1918 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_EXTRA_HEADER;
1919 
1920 	test_http2_dynamic_response_headers_default(expected_headers, ARRAY_SIZE(expected_headers),
1921 						    post, true, &offset);
1922 }
1923 
ZTEST(server_function_tests,test_http2_dynamic_get_response_header_extra)1924 ZTEST(server_function_tests, test_http2_dynamic_get_response_header_extra)
1925 {
1926 	test_http2_dynamic_response_header_extra(false);
1927 }
1928 
ZTEST(server_function_tests,test_http2_dynamic_post_response_header_extra)1929 ZTEST(server_function_tests, test_http2_dynamic_post_response_header_extra)
1930 {
1931 	test_http2_dynamic_response_header_extra(true);
1932 }
1933 
test_http1_dynamic_response_header_override(bool post)1934 static void test_http1_dynamic_response_header_override(bool post)
1935 {
1936 	static const char response[] = "HTTP/1.1 200\r\n"
1937 				       "Transfer-Encoding: chunked\r\n"
1938 				       "Content-Type: application/json\r\n"
1939 				       "\r\n"
1940 				       "0\r\n\r\n";
1941 
1942 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_OVERRIDE_HEADER;
1943 
1944 	test_http1_dynamic_response_headers_default(response, post);
1945 }
1946 
ZTEST(server_function_tests,test_http1_dynamic_get_response_header_override)1947 ZTEST(server_function_tests, test_http1_dynamic_get_response_header_override)
1948 {
1949 	test_http1_dynamic_response_header_override(false);
1950 }
1951 
ZTEST(server_function_tests,test_http1_dynamic_post_response_header_override)1952 ZTEST(server_function_tests, test_http1_dynamic_post_response_header_override)
1953 {
1954 	test_http1_dynamic_response_header_override(true);
1955 }
1956 
test_http2_dynamic_response_header_override(bool post)1957 static void test_http2_dynamic_response_header_override(bool post)
1958 {
1959 	size_t offset = 0;
1960 	const struct http_header expected_headers[] = {
1961 		{.name = ":status", .value = "200"},
1962 		{.name = "content-type", .value = "application/json"},
1963 	};
1964 
1965 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_OVERRIDE_HEADER;
1966 
1967 	test_http2_dynamic_response_headers_default(expected_headers, ARRAY_SIZE(expected_headers),
1968 						    post, true, &offset);
1969 }
1970 
ZTEST(server_function_tests,test_http2_dynamic_get_response_header_override)1971 ZTEST(server_function_tests, test_http2_dynamic_get_response_header_override)
1972 {
1973 	test_http2_dynamic_response_header_override(false);
1974 }
1975 
ZTEST(server_function_tests,test_http2_dynamic_post_response_header_override)1976 ZTEST(server_function_tests, test_http2_dynamic_post_response_header_override)
1977 {
1978 	test_http2_dynamic_response_header_override(true);
1979 }
1980 
test_http1_dynamic_response_header_separate(bool post)1981 static void test_http1_dynamic_response_header_separate(bool post)
1982 {
1983 	static const char response[] = "HTTP/1.1 200\r\n"
1984 				       "Transfer-Encoding: chunked\r\n"
1985 				       "Test-Header: test_data\r\n"
1986 				       "Content-Type: text/plain\r\n"
1987 				       "\r\n"
1988 				       "10\r\n" TEST_DYNAMIC_GET_PAYLOAD "\r\n"
1989 				       "0\r\n\r\n";
1990 
1991 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_SEPARATE;
1992 
1993 	test_http1_dynamic_response_headers_default(response, post);
1994 }
1995 
ZTEST(server_function_tests,test_http1_dynamic_get_response_header_separate)1996 ZTEST(server_function_tests, test_http1_dynamic_get_response_header_separate)
1997 {
1998 	test_http1_dynamic_response_header_separate(false);
1999 }
2000 
ZTEST(server_function_tests,test_http1_dynamic_post_response_header_separate)2001 ZTEST(server_function_tests, test_http1_dynamic_post_response_header_separate)
2002 {
2003 	test_http1_dynamic_response_header_separate(true);
2004 }
2005 
test_http2_dynamic_response_header_separate(bool post)2006 static void test_http2_dynamic_response_header_separate(bool post)
2007 {
2008 	size_t offset = 0;
2009 	const struct http_header expected_headers[] = {
2010 		{.name = ":status", .value = "200"},
2011 		{.name = "test-header", .value = "test_data"},
2012 		{.name = "content-type", .value = "text/plain"},
2013 	};
2014 
2015 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_SEPARATE;
2016 
2017 	test_http2_dynamic_response_headers_default(expected_headers, ARRAY_SIZE(expected_headers),
2018 						    post, false, &offset);
2019 }
2020 
ZTEST(server_function_tests,test_http2_dynamic_get_response_header_separate)2021 ZTEST(server_function_tests, test_http2_dynamic_get_response_header_separate)
2022 {
2023 	test_http2_dynamic_response_header_separate(false);
2024 }
2025 
ZTEST(server_function_tests,test_http2_dynamic_post_response_header_separate)2026 ZTEST(server_function_tests, test_http2_dynamic_post_response_header_separate)
2027 {
2028 	test_http2_dynamic_response_header_separate(true);
2029 }
2030 
test_http1_dynamic_response_header_combined(bool post)2031 static void test_http1_dynamic_response_header_combined(bool post)
2032 {
2033 	static const char response[] = "HTTP/1.1 200\r\n"
2034 				       "Transfer-Encoding: chunked\r\n"
2035 				       "Test-Header: test_data\r\n"
2036 				       "Content-Type: text/plain\r\n"
2037 				       "\r\n"
2038 				       "10\r\n" TEST_DYNAMIC_GET_PAYLOAD "\r\n"
2039 				       "0\r\n\r\n";
2040 
2041 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_COMBINED;
2042 
2043 	test_http1_dynamic_response_headers_default(response, post);
2044 }
2045 
ZTEST(server_function_tests,test_http1_dynamic_get_response_header_combined)2046 ZTEST(server_function_tests, test_http1_dynamic_get_response_header_combined)
2047 {
2048 	test_http1_dynamic_response_header_combined(false);
2049 }
2050 
ZTEST(server_function_tests,test_http1_dynamic_post_response_header_combined)2051 ZTEST(server_function_tests, test_http1_dynamic_post_response_header_combined)
2052 {
2053 	test_http1_dynamic_response_header_combined(true);
2054 }
2055 
test_http2_dynamic_response_header_combined(bool post)2056 static void test_http2_dynamic_response_header_combined(bool post)
2057 {
2058 	size_t offset = 0;
2059 	const struct http_header expected_headers[] = {
2060 		{.name = ":status", .value = "200"},
2061 		{.name = "test-header", .value = "test_data"},
2062 		{.name = "content-type", .value = "text/plain"},
2063 	};
2064 
2065 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_COMBINED;
2066 
2067 	test_http2_dynamic_response_headers_default(expected_headers, ARRAY_SIZE(expected_headers),
2068 						    post, false, &offset);
2069 }
2070 
ZTEST(server_function_tests,test_http2_dynamic_get_response_header_combined)2071 ZTEST(server_function_tests, test_http2_dynamic_get_response_header_combined)
2072 {
2073 	test_http2_dynamic_response_header_combined(false);
2074 }
2075 
ZTEST(server_function_tests,test_http2_dynamic_post_response_header_combined)2076 ZTEST(server_function_tests, test_http2_dynamic_post_response_header_combined)
2077 {
2078 	test_http2_dynamic_response_header_combined(true);
2079 }
2080 
ZTEST(server_function_tests,test_http1_dynamic_get_response_header_long)2081 ZTEST(server_function_tests, test_http1_dynamic_get_response_header_long)
2082 {
2083 	static const char response[] = "HTTP/1.1 200\r\n"
2084 				       "Transfer-Encoding: chunked\r\n"
2085 				       "Content-Type: text/plain\r\n"
2086 				       "\r\n"
2087 				       "130\r\n" TEST_LONG_PAYLOAD_CHUNK_1 "\r\n"
2088 				       "d0\r\n" TEST_LONG_PAYLOAD_CHUNK_2 "\r\n"
2089 				       "0\r\n\r\n";
2090 
2091 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_LONG;
2092 
2093 	test_http1_dynamic_response_headers_default(response, false);
2094 }
2095 
ZTEST(server_function_tests,test_http1_dynamic_post_response_header_long)2096 ZTEST(server_function_tests, test_http1_dynamic_post_response_header_long)
2097 {
2098 	static const char request[] = "POST /response_headers HTTP/1.1\r\n"
2099 				      "Accept: */*\r\n"
2100 				      "Content-Length: 512\r\n"
2101 				      "\r\n" TEST_LONG_PAYLOAD_CHUNK_1 TEST_LONG_PAYLOAD_CHUNK_2;
2102 	static const char response[] = "HTTP/1.1 200\r\n"
2103 				       "Transfer-Encoding: chunked\r\n"
2104 				       "Content-Type: text/plain\r\n"
2105 				       "\r\n"
2106 				       "0\r\n\r\n";
2107 
2108 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_LONG;
2109 
2110 	test_http1_dynamic_response_headers(request, response);
2111 	zassert_mem_equal(dynamic_response_headers_buffer, long_payload, strlen(long_payload));
2112 }
2113 
ZTEST(server_function_tests,test_http2_dynamic_get_response_header_long)2114 ZTEST(server_function_tests, test_http2_dynamic_get_response_header_long)
2115 {
2116 	size_t offset = 0;
2117 	const struct http_header expected_headers[] = {
2118 		{.name = ":status", .value = "200"},
2119 		{.name = "content-type", .value = "text/plain"},
2120 	};
2121 
2122 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_LONG;
2123 
2124 	test_http2_dynamic_response_headers_default(expected_headers, ARRAY_SIZE(expected_headers),
2125 						    false, false, &offset);
2126 	expect_http2_data_frame(&offset, TEST_STREAM_ID_1, TEST_LONG_PAYLOAD_CHUNK_1,
2127 				strlen(TEST_LONG_PAYLOAD_CHUNK_1), 0);
2128 	expect_http2_data_frame(&offset, TEST_STREAM_ID_1, TEST_LONG_PAYLOAD_CHUNK_2,
2129 				strlen(TEST_LONG_PAYLOAD_CHUNK_2), HTTP2_FLAG_END_STREAM);
2130 }
2131 
ZTEST(server_function_tests,test_http2_dynamic_post_response_header_long)2132 ZTEST(server_function_tests, test_http2_dynamic_post_response_header_long)
2133 {
2134 	size_t offset = 0;
2135 	size_t req_offset = 0;
2136 
2137 	const struct http_header expected_headers[] = {
2138 		{.name = ":status", .value = "200"},
2139 		{.name = "content-type", .value = "text/plain"},
2140 	};
2141 
2142 	const uint8_t request_part1[] = {
2143 		TEST_HTTP2_MAGIC,
2144 		TEST_HTTP2_SETTINGS,
2145 		TEST_HTTP2_SETTINGS_ACK,
2146 		TEST_HTTP2_HEADERS_POST_RESPONSE_HEADERS_STREAM_1,
2147 		/* Data frame header */
2148 		0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, TEST_STREAM_ID_1,
2149 	};
2150 
2151 	const uint8_t request_part3[] = {
2152 		TEST_HTTP2_GOAWAY,
2153 	};
2154 
2155 	static uint8_t
2156 		request[sizeof(request_part1) + (sizeof(long_payload) - 1) + sizeof(request_part3)];
2157 
2158 	BUILD_ASSERT(sizeof(long_payload) - 1 == 0x200, "Length field in data frame header must "
2159 							"match length of long_payload");
2160 
2161 	memcpy(request + req_offset, request_part1, sizeof(request_part1));
2162 	req_offset += sizeof(request_part1);
2163 	memcpy(request + req_offset, long_payload, sizeof(long_payload) - 1);
2164 	req_offset += sizeof(long_payload) - 1;
2165 	memcpy(request + req_offset, request_part3, sizeof(request_part3));
2166 	req_offset += sizeof(request_part3);
2167 
2168 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_LONG;
2169 
2170 	test_http2_dynamic_response_headers(request, req_offset, expected_headers,
2171 					    ARRAY_SIZE(expected_headers), true, &offset);
2172 	zassert_mem_equal(dynamic_response_headers_buffer, long_payload, strlen(long_payload));
2173 }
2174 
ZTEST(server_function_tests,test_http1_409_method_not_allowed)2175 ZTEST(server_function_tests, test_http1_409_method_not_allowed)
2176 {
2177 	static const char http1_request[] =
2178 		"POST / HTTP/1.1\r\n"
2179 		"Host: 127.0.0.1:8080\r\n"
2180 		"Content-Type: text/html\r\n"
2181 		"Content-Length: 13\r\n\r\n"
2182 		TEST_STATIC_PAYLOAD;
2183 	static const char expected_response[] =
2184 		"HTTP/1.1 405 Method Not Allowed\r\n";
2185 	size_t offset = 0;
2186 	int ret;
2187 
2188 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
2189 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
2190 
2191 	memset(buf, 0, sizeof(buf));
2192 
2193 	test_read_data(&offset, sizeof(expected_response) - 1);
2194 	zassert_mem_equal(buf, expected_response, sizeof(expected_response) - 1,
2195 			  "Received data doesn't match expected response");
2196 }
2197 
ZTEST(server_function_tests,test_http1_upgrade_409_method_not_allowed)2198 ZTEST(server_function_tests, test_http1_upgrade_409_method_not_allowed)
2199 {
2200 	static const char http1_request[] =
2201 		"POST / HTTP/1.1\r\n"
2202 		"Host: 127.0.0.1:8080\r\n"
2203 		"Content-Type: text/html\r\n"
2204 		"Content-Length: 13\r\n"
2205 		"Connection: Upgrade, HTTP2-Settings\r\n"
2206 		"Upgrade: h2c\r\n"
2207 		"HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA\r\n\r\n"
2208 		TEST_STATIC_PAYLOAD;
2209 	const struct http_header expected_headers[] = {
2210 		{.name = ":status", .value = "405"}
2211 	};
2212 	size_t offset = 0;
2213 	int ret;
2214 
2215 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
2216 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
2217 
2218 	memset(buf, 0, sizeof(buf));
2219 
2220 	/* Verify HTTP1 switching protocols response. */
2221 	expect_http1_switching_protocols(&offset);
2222 
2223 	/* Verify HTTP2 frames. */
2224 	expect_http2_settings_frame(&offset, false);
2225 	expect_http2_headers_frame(&offset, UPGRADE_STREAM_ID,
2226 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM,
2227 				   expected_headers, 1);
2228 }
2229 
ZTEST(server_function_tests,test_http2_409_method_not_allowed)2230 ZTEST(server_function_tests, test_http2_409_method_not_allowed)
2231 {
2232 	static const uint8_t request_post_static[] = {
2233 		TEST_HTTP2_MAGIC,
2234 		TEST_HTTP2_SETTINGS,
2235 		TEST_HTTP2_SETTINGS_ACK,
2236 		TEST_HTTP2_HEADERS_POST_ROOT_STREAM_1,
2237 		TEST_HTTP2_DATA_POST_ROOT_STREAM_1,
2238 		TEST_HTTP2_GOAWAY,
2239 	};
2240 	const struct http_header expected_headers[] = {
2241 		{.name = ":status", .value = "405"}
2242 	};
2243 	size_t offset = 0;
2244 	int ret;
2245 
2246 	ret = zsock_send(client_fd, request_post_static,
2247 			 sizeof(request_post_static), 0);
2248 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
2249 
2250 	memset(buf, 0, sizeof(buf));
2251 
2252 	expect_http2_settings_frame(&offset, false);
2253 	expect_http2_settings_frame(&offset, true);
2254 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1,
2255 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM,
2256 				   expected_headers, 1);
2257 }
2258 
ZTEST(server_function_tests,test_http1_500_internal_server_error)2259 ZTEST(server_function_tests, test_http1_500_internal_server_error)
2260 {
2261 	static const char http1_request[] =
2262 		"GET /dynamic HTTP/1.1\r\n"
2263 		"Host: 127.0.0.1:8080\r\n"
2264 		"User-Agent: curl/7.68.0\r\n"
2265 		"Accept: */*\r\n"
2266 		"Accept-Encoding: deflate, gzip, br\r\n"
2267 		"\r\n";
2268 	static const char expected_response[] =
2269 		"HTTP/1.1 500 Internal Server Error\r\n";
2270 	size_t offset = 0;
2271 	int ret;
2272 
2273 	dynamic_error = true;
2274 
2275 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
2276 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
2277 
2278 	memset(buf, 0, sizeof(buf));
2279 
2280 	test_read_data(&offset, sizeof(expected_response) - 1);
2281 	zassert_mem_equal(buf, expected_response, sizeof(expected_response) - 1,
2282 			  "Received data doesn't match expected response");
2283 }
2284 
ZTEST(server_function_tests,test_http1_upgrade_500_internal_server_error)2285 ZTEST(server_function_tests, test_http1_upgrade_500_internal_server_error)
2286 {
2287 	static const char http1_request[] =
2288 		"GET /dynamic HTTP/1.1\r\n"
2289 		"Host: 127.0.0.1:8080\r\n"
2290 		"User-Agent: curl/7.68.0\r\n"
2291 		"Accept: */*\r\n"
2292 		"Accept-Encoding: deflate, gzip, br\r\n"
2293 		"Connection: Upgrade, HTTP2-Settings\r\n"
2294 		"Upgrade: h2c\r\n"
2295 		"HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA\r\n"
2296 		"\r\n";
2297 	const struct http_header expected_headers[] = {
2298 		{.name = ":status", .value = "500"}
2299 	};
2300 	size_t offset = 0;
2301 	int ret;
2302 
2303 	dynamic_error = true;
2304 
2305 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
2306 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
2307 
2308 	memset(buf, 0, sizeof(buf));
2309 
2310 	/* Verify HTTP1 switching protocols response. */
2311 	expect_http1_switching_protocols(&offset);
2312 
2313 	/* Verify HTTP2 frames. */
2314 	expect_http2_settings_frame(&offset, false);
2315 	expect_http2_headers_frame(&offset, UPGRADE_STREAM_ID,
2316 				   HTTP2_FLAG_END_HEADERS,
2317 				   expected_headers, 1);
2318 	/* Expect data frame with reason but don't check the content as it may
2319 	 * depend on libc being used (i. e. string returned by strerror()).
2320 	 */
2321 	expect_http2_data_frame(&offset, UPGRADE_STREAM_ID, NULL, 0,
2322 				HTTP2_FLAG_END_STREAM);
2323 }
2324 
ZTEST(server_function_tests,test_http2_500_internal_server_error)2325 ZTEST(server_function_tests, test_http2_500_internal_server_error)
2326 {
2327 	static const uint8_t request_get_dynamic[] = {
2328 		TEST_HTTP2_MAGIC,
2329 		TEST_HTTP2_SETTINGS,
2330 		TEST_HTTP2_SETTINGS_ACK,
2331 		TEST_HTTP2_HEADERS_GET_DYNAMIC_STREAM_1,
2332 		TEST_HTTP2_GOAWAY,
2333 	};
2334 	const struct http_header expected_headers[] = {
2335 		{.name = ":status", .value = "500"}
2336 	};
2337 	size_t offset = 0;
2338 	int ret;
2339 
2340 	dynamic_error = true;
2341 
2342 	ret = zsock_send(client_fd, request_get_dynamic,
2343 			 sizeof(request_get_dynamic), 0);
2344 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
2345 
2346 	memset(buf, 0, sizeof(buf));
2347 
2348 	expect_http2_settings_frame(&offset, false);
2349 	expect_http2_settings_frame(&offset, true);
2350 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1,
2351 				   HTTP2_FLAG_END_HEADERS,
2352 				   expected_headers, 1);
2353 	/* Expect data frame with reason but don't check the content as it may
2354 	 * depend on libc being used (i. e. string returned by strerror()).
2355 	 */
2356 	expect_http2_data_frame(&offset, TEST_STREAM_ID_1, NULL, 0,
2357 				HTTP2_FLAG_END_STREAM);
2358 }
2359 
ZTEST(server_function_tests_no_init,test_http_server_start_stop)2360 ZTEST(server_function_tests_no_init, test_http_server_start_stop)
2361 {
2362 	struct sockaddr_in sa = { 0 };
2363 	int ret;
2364 
2365 	sa.sin_family = AF_INET;
2366 	sa.sin_port = htons(SERVER_PORT);
2367 
2368 	ret = zsock_inet_pton(AF_INET, SERVER_IPV4_ADDR, &sa.sin_addr.s_addr);
2369 	zassert_equal(1, ret, "inet_pton() failed to convert %s", SERVER_IPV4_ADDR);
2370 
2371 	zassert_ok(http_server_start(), "Failed to start the server");
2372 	zassert_not_ok(http_server_start(), "Server start should report na error.");
2373 
2374 	zassert_ok(http_server_stop(), "Failed to stop the server");
2375 	zassert_not_ok(http_server_stop(), "Server stop should report na error.");
2376 
2377 	zassert_ok(http_server_start(), "Failed to start the server");
2378 
2379 	/* Server should be listening now. */
2380 	ret = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
2381 	zassert_not_equal(ret, -1, "failed to create client socket (%d)", errno);
2382 	client_fd = ret;
2383 
2384 	zassert_ok(zsock_connect(client_fd, (struct sockaddr *)&sa, sizeof(sa)),
2385 		   "failed to connect to the server (%d)", errno);
2386 	zassert_ok(zsock_close(client_fd), "close() failed on the client fd (%d)", errno);
2387 	client_fd = -1;
2388 
2389 	/* Check if the server can be restarted again after client connected. */
2390 	zassert_ok(http_server_stop(), "Failed to stop the server");
2391 	zassert_ok(http_server_start(), "Failed to start the server");
2392 
2393 	/* Let the server thread run. */
2394 	k_msleep(CONFIG_HTTP_SERVER_RESTART_DELAY + 10);
2395 
2396 	ret = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
2397 	zassert_not_equal(ret, -1, "failed to create client socket (%d)", errno);
2398 	client_fd = ret;
2399 
2400 	zassert_ok(zsock_connect(client_fd, (struct sockaddr *)&sa, sizeof(sa)),
2401 		   "failed to connect to the server (%d)", errno);
2402 	zassert_ok(zsock_close(client_fd), "close() failed on the client fd (%d)", errno);
2403 	client_fd = -1;
2404 
2405 	zassert_ok(http_server_stop(), "Failed to stop the server");
2406 }
2407 
ZTEST(server_function_tests_no_init,test_get_frame_type_name)2408 ZTEST(server_function_tests_no_init, test_get_frame_type_name)
2409 {
2410 	zassert_str_equal(get_frame_type_name(HTTP2_DATA_FRAME), "DATA",
2411 			  "Unexpected frame type");
2412 	zassert_str_equal(get_frame_type_name(HTTP2_HEADERS_FRAME),
2413 			  "HEADERS", "Unexpected frame type");
2414 	zassert_str_equal(get_frame_type_name(HTTP2_PRIORITY_FRAME),
2415 			  "PRIORITY", "Unexpected frame type");
2416 	zassert_str_equal(get_frame_type_name(HTTP2_RST_STREAM_FRAME),
2417 			  "RST_STREAM", "Unexpected frame type");
2418 	zassert_str_equal(get_frame_type_name(HTTP2_SETTINGS_FRAME),
2419 			  "SETTINGS", "Unexpected frame type");
2420 	zassert_str_equal(get_frame_type_name(HTTP2_PUSH_PROMISE_FRAME),
2421 			  "PUSH_PROMISE", "Unexpected frame type");
2422 	zassert_str_equal(get_frame_type_name(HTTP2_PING_FRAME), "PING",
2423 			  "Unexpected frame type");
2424 	zassert_str_equal(get_frame_type_name(HTTP2_GOAWAY_FRAME),
2425 			  "GOAWAY", "Unexpected frame type");
2426 	zassert_str_equal(get_frame_type_name(HTTP2_WINDOW_UPDATE_FRAME),
2427 			  "WINDOW_UPDATE", "Unexpected frame type");
2428 	zassert_str_equal(get_frame_type_name(HTTP2_CONTINUATION_FRAME),
2429 			  "CONTINUATION", "Unexpected frame type");
2430 }
2431 
ZTEST(server_function_tests_no_init,test_parse_http_frames)2432 ZTEST(server_function_tests_no_init, test_parse_http_frames)
2433 {
2434 	static struct http_client_ctx ctx_client1;
2435 	static struct http_client_ctx ctx_client2;
2436 	struct http2_frame *frame;
2437 
2438 	unsigned char buffer1[] = {
2439 		0x00, 0x00, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x00,
2440 		0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00,
2441 		0x04, 0x00, 0x00, 0xff, 0xff, 0x00
2442 	};
2443 	unsigned char buffer2[] = {
2444 		0x00, 0x00, 0x21, 0x01, 0x05, 0x00, 0x00, 0x00,
2445 		0x01, 0x82, 0x84, 0x86, 0x41, 0x8a, 0x0b, 0xe2,
2446 		0x5c, 0x0b, 0x89, 0x70, 0xdc, 0x78, 0x0f, 0x03,
2447 		0x53, 0x03, 0x2a, 0x2f, 0x2a, 0x90, 0x7a, 0x8a,
2448 		0xaa, 0x69, 0xd2, 0x9a, 0xc4, 0xc0, 0x57, 0x68,
2449 		0x0b, 0x83
2450 	};
2451 
2452 	memcpy(ctx_client1.buffer, buffer1, sizeof(buffer1));
2453 	memcpy(ctx_client2.buffer, buffer2, sizeof(buffer2));
2454 
2455 	ctx_client1.cursor = ctx_client1.buffer;
2456 	ctx_client1.data_len = ARRAY_SIZE(buffer1);
2457 
2458 	ctx_client2.cursor = ctx_client2.buffer;
2459 	ctx_client2.data_len = ARRAY_SIZE(buffer2);
2460 
2461 	/* Test: Buffer with the first frame */
2462 	int parser1 = parse_http_frame_header(&ctx_client1, ctx_client1.cursor,
2463 					      ctx_client1.data_len);
2464 
2465 	zassert_equal(parser1, 0, "Failed to parse the first frame");
2466 
2467 	frame = &ctx_client1.current_frame;
2468 
2469 	/* Validate frame details for the 1st frame */
2470 	zassert_equal(frame->length, 0x0C, "Expected length for the 1st frame doesn't match");
2471 	zassert_equal(frame->type, 0x04, "Expected type for the 1st frame doesn't match");
2472 	zassert_equal(frame->flags, 0x00, "Expected flags for the 1st frame doesn't match");
2473 	zassert_equal(frame->stream_identifier, 0x00,
2474 		      "Expected stream_identifier for the 1st frame doesn't match");
2475 
2476 	/* Test: Buffer with the second frame */
2477 	int parser2 = parse_http_frame_header(&ctx_client2, ctx_client2.cursor,
2478 					      ctx_client2.data_len);
2479 
2480 	zassert_equal(parser2, 0, "Failed to parse the second frame");
2481 
2482 	frame = &ctx_client2.current_frame;
2483 
2484 	/* Validate frame details for the 2nd frame */
2485 	zassert_equal(frame->length, 0x21, "Expected length for the 2nd frame doesn't match");
2486 	zassert_equal(frame->type, 0x01, "Expected type for the 2nd frame doesn't match");
2487 	zassert_equal(frame->flags, 0x05, "Expected flags for the 2nd frame doesn't match");
2488 	zassert_equal(frame->stream_identifier, 0x01,
2489 		      "Expected stream_identifier for the 2nd frame doesn't match");
2490 }
2491 
2492 #if DT_HAS_COMPAT_STATUS_OKAY(zephyr_ram_disk)
2493 
2494 #include <zephyr/fs/fs.h>
2495 #include <zephyr/fs/littlefs.h>
2496 
2497 FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(storage);
2498 
2499 #define TEST_PARTITION		storage_partition
2500 #define TEST_PARTITION_ID	FIXED_PARTITION_ID(TEST_PARTITION)
2501 
2502 #define LFS_MNTP		"/littlefs"
2503 #define TEST_FILE		"static_file.html"
2504 #define TEST_DIR		"/files"
2505 #define TEST_DIR_PATH		LFS_MNTP TEST_DIR
2506 
2507 static struct http_resource_detail_static_fs static_file_resource_detail = {
2508 	.common = {
2509 			.type = HTTP_RESOURCE_TYPE_STATIC_FS,
2510 			.bitmask_of_supported_http_methods = BIT(HTTP_GET),
2511 			.content_type = "text/html",
2512 		},
2513 	.fs_path = TEST_DIR_PATH,
2514 };
2515 
2516 HTTP_RESOURCE_DEFINE(static_file_resource, test_http_service, "/static_file.html",
2517 		     &static_file_resource_detail);
2518 
2519 struct fs_mount_t littlefs_mnt = {
2520 	.type = FS_LITTLEFS,
2521 	.fs_data = &storage,
2522 	.storage_dev = (void *)TEST_PARTITION_ID,
2523 	.mnt_point = LFS_MNTP,
2524 };
2525 
test_clear_flash(void)2526 void test_clear_flash(void)
2527 {
2528 	int rc;
2529 	const struct flash_area *fap;
2530 
2531 	rc = flash_area_open(TEST_PARTITION_ID, &fap);
2532 	zassert_equal(rc, 0, "Opening flash area for erase [%d]\n", rc);
2533 
2534 	rc = flash_area_flatten(fap, 0, fap->fa_size);
2535 	zassert_equal(rc, 0, "Erasing flash area [%d]\n", rc);
2536 }
2537 
test_mount(void)2538 static int test_mount(void)
2539 {
2540 	int ret;
2541 
2542 	ret = fs_mount(&littlefs_mnt);
2543 	if (ret < 0) {
2544 		TC_PRINT("Error mounting fs [%d]\n", ret);
2545 		return TC_FAIL;
2546 	}
2547 
2548 	return TC_PASS;
2549 }
2550 
test_unmount(void)2551 static int test_unmount(void)
2552 {
2553 	int ret;
2554 
2555 	ret = fs_unmount(&littlefs_mnt);
2556 	if (ret < 0 && ret != -EINVAL) {
2557 		TC_PRINT("Error unmounting fs [%d]\n", ret);
2558 		return TC_FAIL;
2559 	}
2560 
2561 	return TC_PASS;
2562 }
2563 
2564 #ifndef PATH_MAX
2565 #define PATH_MAX 64
2566 #endif
2567 
check_file_dir_exists(const char * fpath)2568 int check_file_dir_exists(const char *fpath)
2569 {
2570 	int res;
2571 	struct fs_dirent entry;
2572 
2573 	res = fs_stat(fpath, &entry);
2574 
2575 	return !res;
2576 }
2577 
test_file_write(struct fs_file_t * filep,const char * test_str)2578 int test_file_write(struct fs_file_t *filep, const char *test_str)
2579 {
2580 	ssize_t brw;
2581 	int res;
2582 
2583 	TC_PRINT("\nWrite tests:\n");
2584 
2585 	/* Verify fs_seek() */
2586 	res = fs_seek(filep, 0, FS_SEEK_SET);
2587 	if (res) {
2588 		TC_PRINT("fs_seek failed [%d]\n", res);
2589 		fs_close(filep);
2590 		return res;
2591 	}
2592 
2593 	TC_PRINT("Data written:\"%s\"\n\n", test_str);
2594 
2595 	/* Verify fs_write() */
2596 	brw = fs_write(filep, (char *)test_str, strlen(test_str));
2597 	if (brw < 0) {
2598 		TC_PRINT("Failed writing to file [%zd]\n", brw);
2599 		fs_close(filep);
2600 		return brw;
2601 	}
2602 
2603 	if (brw < strlen(test_str)) {
2604 		TC_PRINT("Unable to complete write. Volume full.\n");
2605 		TC_PRINT("Number of bytes written: [%zd]\n", brw);
2606 		fs_close(filep);
2607 		return TC_FAIL;
2608 	}
2609 
2610 	TC_PRINT("Data successfully written!\n");
2611 
2612 	return res;
2613 }
2614 
test_mkdir(const char * dir_path,const char * file)2615 int test_mkdir(const char *dir_path, const char *file)
2616 {
2617 	int res;
2618 	struct fs_file_t filep;
2619 	char file_path[PATH_MAX] = { 0 };
2620 
2621 	fs_file_t_init(&filep);
2622 	res = sprintf(file_path, "%s/%s", dir_path, file);
2623 	__ASSERT_NO_MSG(res < sizeof(file_path));
2624 
2625 	if (check_file_dir_exists(dir_path)) {
2626 		TC_PRINT("Dir %s exists\n", dir_path);
2627 		return TC_FAIL;
2628 	}
2629 
2630 	TC_PRINT("Creating new dir %s\n", dir_path);
2631 
2632 	/* Verify fs_mkdir() */
2633 	res = fs_mkdir(dir_path);
2634 	if (res) {
2635 		TC_PRINT("Error creating dir[%d]\n", res);
2636 		return res;
2637 	}
2638 
2639 	res = fs_open(&filep, file_path, FS_O_CREATE | FS_O_RDWR);
2640 	if (res) {
2641 		TC_PRINT("Failed opening file [%d]\n", res);
2642 		return res;
2643 	}
2644 
2645 	TC_PRINT("Testing write to file %s\n", file_path);
2646 	res = test_file_write(&filep, TEST_STATIC_FS_PAYLOAD);
2647 	if (res) {
2648 		fs_close(&filep);
2649 		return res;
2650 	}
2651 
2652 	res = fs_close(&filep);
2653 	if (res) {
2654 		TC_PRINT("Error closing file [%d]\n", res);
2655 		return res;
2656 	}
2657 
2658 	TC_PRINT("Created dir %s!\n", dir_path);
2659 
2660 	return res;
2661 }
2662 
setup_fs(const char * file_ending)2663 static int setup_fs(const char *file_ending)
2664 {
2665 	char filename_buf[sizeof(TEST_FILE)+5] = TEST_FILE;
2666 
2667 	strcat(filename_buf, file_ending);
2668 	test_clear_flash();
2669 
2670 	zassert_equal(test_unmount(), TC_PASS, "Failed to unmount fs");
2671 	zassert_equal(test_mount(), TC_PASS, "Failed to mount fs");
2672 
2673 	return test_mkdir(TEST_DIR_PATH, filename_buf);
2674 }
2675 
ZTEST(server_function_tests,test_http1_static_fs)2676 ZTEST(server_function_tests, test_http1_static_fs)
2677 {
2678 	static const char http1_request[] =
2679 		"GET /static_file.html HTTP/1.1\r\n"
2680 		"Host: 127.0.0.1:8080\r\n"
2681 		"User-Agent: curl/7.68.0\r\n"
2682 		"Accept: */*\r\n"
2683 		"\r\n";
2684 	static const char expected_response[] =
2685 		"HTTP/1.1 200 OK\r\n"
2686 		"Content-Length: 30\r\n"
2687 		"Content-Type: text/html\r\n"
2688 		"\r\n"
2689 		TEST_STATIC_FS_PAYLOAD;
2690 	size_t offset = 0;
2691 	int ret;
2692 
2693 	ret = setup_fs("");
2694 	zassert_equal(ret, TC_PASS, "Failed to mount fs");
2695 
2696 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
2697 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
2698 
2699 	memset(buf, 0, sizeof(buf));
2700 
2701 	test_read_data(&offset, sizeof(expected_response) - 1);
2702 	zassert_mem_equal(buf, expected_response, sizeof(expected_response) - 1,
2703 			  "Received data doesn't match expected response");
2704 }
2705 
ZTEST(server_function_tests,test_http1_static_fs_compression)2706 ZTEST(server_function_tests, test_http1_static_fs_compression)
2707 {
2708 #define HTTP1_COMPRESSION_REQUEST                                                                  \
2709 	"GET /static_file.html HTTP/1.1\r\n"                                                       \
2710 	"Host: 127.0.0.1:8080\r\n"                                                                 \
2711 	"User-Agent: curl/7.68.0\r\n"                                                              \
2712 	"Accept: */*\r\n"                                                                          \
2713 	"Accept-Encoding: %s\r\n"                                                                  \
2714 	"\r\n"
2715 #define HTTP1_COMPRESSION_RESPONSE                                                                 \
2716 	"HTTP/1.1 200 OK\r\n"                                                                      \
2717 	"Content-Length: 30\r\n"                                                                   \
2718 	"Content-Type: text/html\r\n"                                                              \
2719 	"Content-Encoding: %s\r\n"                                                                 \
2720 	"\r\n" TEST_STATIC_FS_PAYLOAD
2721 
2722 	static const char mixed_compression_str[] = "gzip, deflate, br";
2723 	static char http1_request[sizeof(HTTP1_COMPRESSION_REQUEST) +
2724 				  ARRAY_SIZE(mixed_compression_str)] = {0};
2725 	static char expected_response[sizeof(HTTP1_COMPRESSION_RESPONSE) +
2726 				      HTTP_COMPRESSION_MAX_STRING_LEN] = {0};
2727 	static const char *const file_ending_map[] = {[HTTP_GZIP] = ".gz",
2728 						      [HTTP_COMPRESS] = ".lzw",
2729 						      [HTTP_DEFLATE] = ".zz",
2730 						      [HTTP_BR] = ".br",
2731 						      [HTTP_ZSTD] = ".zst"};
2732 	size_t offset;
2733 	int ret;
2734 	int expected_response_size;
2735 
2736 	for (enum http_compression i = 0; compression_value_is_valid(i); ++i) {
2737 		offset = 0;
2738 
2739 		if (i == HTTP_NONE) {
2740 			continue;
2741 		}
2742 		TC_PRINT("Testing %s compression...\n", http_compression_text(i));
2743 		zassert(i < ARRAY_SIZE(file_ending_map) && &file_ending_map[i] != NULL,
2744 			"No file ending defined for compression");
2745 
2746 		sprintf(http1_request, HTTP1_COMPRESSION_REQUEST, http_compression_text(i));
2747 		expected_response_size = sprintf(expected_response, HTTP1_COMPRESSION_RESPONSE,
2748 						 http_compression_text(i));
2749 
2750 		ret = setup_fs(file_ending_map[i]);
2751 		zassert_equal(ret, TC_PASS, "Failed to mount fs");
2752 
2753 		ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
2754 		zassert_not_equal(ret, -1, "send() failed (%d)", errno);
2755 
2756 		memset(buf, 0, sizeof(buf));
2757 
2758 		test_read_data(&offset, expected_response_size);
2759 		zassert_mem_equal(buf, expected_response, expected_response_size,
2760 				  "Received data doesn't match expected response");
2761 	}
2762 
2763 	offset = 0;
2764 	TC_PRINT("Testing mixed compression...\n");
2765 	sprintf(http1_request, HTTP1_COMPRESSION_REQUEST, mixed_compression_str);
2766 	expected_response_size = sprintf(expected_response, HTTP1_COMPRESSION_RESPONSE,
2767 					 http_compression_text(HTTP_BR));
2768 	ret = setup_fs(file_ending_map[HTTP_BR]);
2769 	zassert_equal(ret, TC_PASS, "Failed to mount fs");
2770 
2771 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
2772 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
2773 
2774 	memset(buf, 0, sizeof(buf));
2775 
2776 	test_read_data(&offset, expected_response_size);
2777 	zassert_mem_equal(buf, expected_response, expected_response_size,
2778 			  "Received data doesn't match expected response");
2779 }
2780 #endif /* DT_HAS_COMPAT_STATUS_OKAY(zephyr_ram_disk) */
2781 
http_server_tests_before(void * fixture)2782 static void http_server_tests_before(void *fixture)
2783 {
2784 	struct sockaddr_in sa;
2785 	struct timeval optval = {
2786 		.tv_sec = TIMEOUT_S,
2787 		.tv_usec = 0,
2788 	};
2789 	int ret;
2790 
2791 	ARG_UNUSED(fixture);
2792 
2793 	memset(dynamic_payload, 0, sizeof(dynamic_payload));
2794 	memset(dynamic_response_headers_buffer, 0, sizeof(dynamic_response_headers_buffer));
2795 	memset(&request_headers_clone, 0, sizeof(request_headers_clone));
2796 	memset(&request_headers_clone2, 0, sizeof(request_headers_clone2));
2797 	dynamic_payload_len = 0;
2798 	dynamic_error = false;
2799 
2800 	ret = http_server_start();
2801 	if (ret < 0) {
2802 		printk("Failed to start the server\n");
2803 		return;
2804 	}
2805 
2806 	ret = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
2807 	if (ret < 0) {
2808 		printk("Failed to create client socket (%d)\n", errno);
2809 		return;
2810 	}
2811 	client_fd = ret;
2812 
2813 	ret = zsock_setsockopt(client_fd, SOL_SOCKET, SO_RCVTIMEO, &optval,
2814 			       sizeof(optval));
2815 	if (ret < 0) {
2816 		printk("Failed to set timeout (%d)\n", errno);
2817 		return;
2818 	}
2819 
2820 	sa.sin_family = AF_INET;
2821 	sa.sin_port = htons(SERVER_PORT);
2822 
2823 	ret = zsock_inet_pton(AF_INET, SERVER_IPV4_ADDR, &sa.sin_addr.s_addr);
2824 	if (ret != 1) {
2825 		printk("inet_pton() failed to convert %s\n", SERVER_IPV4_ADDR);
2826 		return;
2827 	}
2828 
2829 	ret = zsock_connect(client_fd, (struct sockaddr *)&sa, sizeof(sa));
2830 	if (ret < 0) {
2831 		printk("Failed to connect (%d)\n", errno);
2832 	}
2833 }
2834 
http_server_tests_after(void * fixture)2835 static void http_server_tests_after(void *fixture)
2836 {
2837 	ARG_UNUSED(fixture);
2838 
2839 	if (client_fd >= 0) {
2840 		(void)zsock_close(client_fd);
2841 		client_fd = -1;
2842 	}
2843 
2844 	(void)http_server_stop();
2845 
2846 	k_yield();
2847 }
2848 
2849 ZTEST_SUITE(server_function_tests, NULL, NULL, http_server_tests_before,
2850 	    http_server_tests_after, NULL);
2851 ZTEST_SUITE(server_function_tests_no_init, NULL, NULL, NULL,
2852 	    http_server_tests_after, NULL);
2853