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