1 /*
2  * Copyright (c) 2023, Emna Rekik
3  * Copyright (c) 2024 Nordic Semiconductor ASA
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include "server_internal.h"
9 
10 #include <string.h>
11 #include <strings.h>
12 
13 #include <zephyr/net/http/service.h>
14 #include <zephyr/net/socket.h>
15 #include <zephyr/posix/sys/eventfd.h>
16 #include <zephyr/ztest.h>
17 
18 #define BUFFER_SIZE                    1024
19 #define SERVER_IPV4_ADDR               "127.0.0.1"
20 #define SERVER_PORT                    8080
21 #define TIMEOUT_S                      1
22 
23 #define UPGRADE_STREAM_ID              1
24 #define TEST_STREAM_ID_1               3
25 #define TEST_STREAM_ID_2               5
26 
27 #define TEST_DYNAMIC_POST_PAYLOAD "Test dynamic POST"
28 #define TEST_DYNAMIC_GET_PAYLOAD "Test dynamic GET"
29 #define TEST_STATIC_PAYLOAD "Hello, World!"
30 
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 
229 static uint16_t test_http_service_port = SERVER_PORT;
230 HTTP_SERVICE_DEFINE(test_http_service, SERVER_IPV4_ADDR,
231 		    &test_http_service_port, 1, 10, NULL);
232 
233 static const char static_resource_payload[] = TEST_STATIC_PAYLOAD;
234 struct http_resource_detail_static static_resource_detail = {
235 	.common = {
236 			.type = HTTP_RESOURCE_TYPE_STATIC,
237 			.bitmask_of_supported_http_methods = BIT(HTTP_GET),
238 		},
239 	.static_data = static_resource_payload,
240 	.static_data_len = sizeof(static_resource_payload) - 1,
241 };
242 
243 HTTP_RESOURCE_DEFINE(static_resource, test_http_service, "/",
244 		     &static_resource_detail);
245 
246 static uint8_t dynamic_payload[32];
247 static size_t dynamic_payload_len = sizeof(dynamic_payload);
248 
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)249 static int dynamic_cb(struct http_client_ctx *client, enum http_data_status status,
250 		      const struct http_request_ctx *request_ctx,
251 		      struct http_response_ctx *response_ctx, void *user_data)
252 {
253 	static size_t offset;
254 
255 	if (status == HTTP_SERVER_DATA_ABORTED) {
256 		offset = 0;
257 		return 0;
258 	}
259 
260 	switch (client->method) {
261 	case HTTP_GET:
262 		response_ctx->body = dynamic_payload;
263 		response_ctx->body_len = dynamic_payload_len;
264 		response_ctx->final_chunk = true;
265 		break;
266 	case HTTP_DELETE:
267 		response_ctx->body = NULL;
268 		response_ctx->body_len = 0;
269 		response_ctx->final_chunk = true;
270 		break;
271 	case HTTP_POST:
272 	case HTTP_PUT:
273 	case HTTP_PATCH:
274 		if (request_ctx->data_len + offset > sizeof(dynamic_payload)) {
275 			return -ENOMEM;
276 		}
277 
278 		if (request_ctx->data_len > 0) {
279 			memcpy(dynamic_payload + offset, request_ctx->data, request_ctx->data_len);
280 			offset += request_ctx->data_len;
281 		}
282 
283 		if (status == HTTP_SERVER_DATA_FINAL) {
284 			/* All data received, reset progress. */
285 			dynamic_payload_len = offset;
286 			offset = 0;
287 		}
288 
289 		break;
290 	default:
291 		return -ENOTSUP;
292 	}
293 
294 	return 0;
295 }
296 
297 struct http_resource_detail_dynamic dynamic_detail = {
298 	.common = {
299 		.type = HTTP_RESOURCE_TYPE_DYNAMIC,
300 		.bitmask_of_supported_http_methods =
301 			BIT(HTTP_GET) | BIT(HTTP_DELETE) | BIT(HTTP_POST) |
302 			BIT(HTTP_PUT) | BIT(HTTP_PATCH),
303 		.content_type = "text/plain",
304 	},
305 	.cb = dynamic_cb,
306 	.user_data = NULL,
307 };
308 
309 HTTP_RESOURCE_DEFINE(dynamic_resource, test_http_service, "/dynamic",
310 		     &dynamic_detail);
311 
312 struct test_headers_clone {
313 	uint8_t buffer[CONFIG_HTTP_SERVER_CAPTURE_HEADER_BUFFER_SIZE];
314 	struct http_header headers[CONFIG_HTTP_SERVER_CAPTURE_HEADER_COUNT];
315 	size_t count;
316 	enum http_header_status status;
317 };
318 
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)319 static int dynamic_request_headers_cb(struct http_client_ctx *client, enum http_data_status status,
320 				      const struct http_request_ctx *request_ctx,
321 				      struct http_response_ctx *response_ctx, void *user_data)
322 {
323 	ptrdiff_t offset;
324 	struct http_header *hdrs_src;
325 	struct http_header *hdrs_dst;
326 	struct test_headers_clone *clone = (struct test_headers_clone *)user_data;
327 
328 	if (request_ctx->header_count != 0) {
329 		/* Copy the captured header info to static buffer for later assertions in testcase.
330 		 * Don't assume that the buffer inside client context remains valid after return
331 		 * from the callback. Also need to update pointers within structure with an offset
332 		 * to point at new buffer.
333 		 */
334 		memcpy(clone->buffer, &client->header_capture_ctx, sizeof(clone->buffer));
335 
336 		clone->count = request_ctx->header_count;
337 		clone->status = request_ctx->headers_status;
338 
339 		hdrs_src = request_ctx->headers;
340 		hdrs_dst = clone->headers;
341 		offset = clone->buffer - client->header_capture_ctx.buffer;
342 
343 		for (int i = 0; i < request_ctx->header_count; i++) {
344 			if (hdrs_src[i].name != NULL) {
345 				hdrs_dst[i].name = hdrs_src[i].name + offset;
346 			}
347 
348 			if (hdrs_src[i].value != NULL) {
349 				hdrs_dst[i].value = hdrs_src[i].value + offset;
350 			}
351 		}
352 	}
353 
354 	return 0;
355 }
356 
357 /* Define two resources for testing header capture, so that we can check concurrent streams */
358 static struct test_headers_clone request_headers_clone;
359 static struct test_headers_clone request_headers_clone2;
360 
361 struct http_resource_detail_dynamic dynamic_request_headers_detail = {
362 	.common = {
363 			.type = HTTP_RESOURCE_TYPE_DYNAMIC,
364 			.bitmask_of_supported_http_methods = BIT(HTTP_GET) | BIT(HTTP_POST),
365 			.content_type = "text/plain",
366 		},
367 	.cb = dynamic_request_headers_cb,
368 	.user_data = &request_headers_clone,
369 };
370 
371 struct http_resource_detail_dynamic dynamic_request_headers_detail2 = {
372 	.common = {
373 			.type = HTTP_RESOURCE_TYPE_DYNAMIC,
374 			.bitmask_of_supported_http_methods = BIT(HTTP_GET) | BIT(HTTP_POST),
375 			.content_type = "text/plain",
376 		},
377 	.cb = dynamic_request_headers_cb,
378 	.user_data = &request_headers_clone2,
379 };
380 
381 HTTP_RESOURCE_DEFINE(dynamic_request_headers_resource, test_http_service, "/header_capture",
382 		     &dynamic_request_headers_detail);
383 
384 HTTP_RESOURCE_DEFINE(dynamic_request_headers_resource2, test_http_service, "/header_capture2",
385 		     &dynamic_request_headers_detail2);
386 
387 HTTP_SERVER_REGISTER_HEADER_CAPTURE(capture_user_agent, "User-Agent");
388 HTTP_SERVER_REGISTER_HEADER_CAPTURE(capture_test_header, "Test-Header");
389 HTTP_SERVER_REGISTER_HEADER_CAPTURE(capture_test_header2, "Test-Header2");
390 
391 enum dynamic_response_headers_variant {
392 	/* No application defined response code, headers or data */
393 	DYNAMIC_RESPONSE_HEADERS_VARIANT_NONE,
394 
395 	/* Send a 422 response code */
396 	DYNAMIC_RESPONSE_HEADERS_VARIANT_422,
397 
398 	/* Send an extra header on top of server defaults */
399 	DYNAMIC_RESPONSE_HEADERS_VARIANT_EXTRA_HEADER,
400 
401 	/* Override the default Content-Type header */
402 	DYNAMIC_RESPONSE_HEADERS_VARIANT_OVERRIDE_HEADER,
403 
404 	/* Send body data combined with header data in a single callback */
405 	DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_COMBINED,
406 
407 	/* Send body data in a separate callback to header data */
408 	DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_SEPARATE,
409 
410 	/* Long body data split across multiple callbacks */
411 	DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_LONG,
412 };
413 
414 static uint8_t dynamic_response_headers_variant;
415 static uint8_t dynamic_response_headers_buffer[sizeof(long_payload)];
416 
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)417 static int dynamic_response_headers_cb(struct http_client_ctx *client, enum http_data_status status,
418 				       const struct http_request_ctx *request_ctx,
419 				       struct http_response_ctx *response_ctx, void *user_data)
420 {
421 	static bool request_continuation;
422 	static size_t offset;
423 
424 	static const struct http_header extra_headers[] = {
425 		{.name = "Test-Header", .value = "test_data"},
426 	};
427 
428 	static const struct http_header override_headers[] = {
429 		{.name = "Content-Type", .value = "application/json"},
430 	};
431 
432 	if (status != HTTP_SERVER_DATA_FINAL &&
433 	    dynamic_response_headers_variant != DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_LONG) {
434 		/* Long body variant is the only one which needs to take some action before final
435 		 * data has been received from server
436 		 */
437 		return 0;
438 	}
439 
440 	switch (dynamic_response_headers_variant) {
441 	case DYNAMIC_RESPONSE_HEADERS_VARIANT_NONE:
442 		break;
443 
444 	case DYNAMIC_RESPONSE_HEADERS_VARIANT_422:
445 		response_ctx->status = 422;
446 		response_ctx->final_chunk = true;
447 		break;
448 
449 	case DYNAMIC_RESPONSE_HEADERS_VARIANT_EXTRA_HEADER:
450 		response_ctx->headers = extra_headers;
451 		response_ctx->header_count = ARRAY_SIZE(extra_headers);
452 		response_ctx->final_chunk = true;
453 		break;
454 
455 	case DYNAMIC_RESPONSE_HEADERS_VARIANT_OVERRIDE_HEADER:
456 		response_ctx->headers = override_headers;
457 		response_ctx->header_count = ARRAY_SIZE(extra_headers);
458 		response_ctx->final_chunk = true;
459 		break;
460 
461 	case DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_SEPARATE:
462 		if (!request_continuation) {
463 			/* Send headers in first callback */
464 			response_ctx->headers = extra_headers;
465 			response_ctx->header_count = ARRAY_SIZE(extra_headers);
466 			request_continuation = true;
467 		} else {
468 			/* Send body in subsequent callback */
469 			response_ctx->body = TEST_DYNAMIC_GET_PAYLOAD;
470 			response_ctx->body_len = strlen(response_ctx->body);
471 			response_ctx->final_chunk = true;
472 			request_continuation = false;
473 		}
474 		break;
475 
476 	case DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_COMBINED:
477 		response_ctx->headers = extra_headers;
478 		response_ctx->header_count = ARRAY_SIZE(extra_headers);
479 		response_ctx->body = TEST_DYNAMIC_GET_PAYLOAD;
480 		response_ctx->body_len = strlen(response_ctx->body);
481 		response_ctx->final_chunk = true;
482 		break;
483 
484 	case DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_LONG:
485 		if (client->method == HTTP_GET) {
486 			/* Send GET payload split across multiple callbacks */
487 			size_t send_len = (offset == 0) ? strlen(TEST_LONG_PAYLOAD_CHUNK_1)
488 							: strlen(TEST_LONG_PAYLOAD_CHUNK_2);
489 
490 			response_ctx->body = long_payload + offset;
491 			response_ctx->body_len = send_len;
492 			offset += send_len;
493 
494 			if (offset == strlen(long_payload)) {
495 				offset = 0;
496 				response_ctx->final_chunk = true;
497 			}
498 		} else if (client->method == HTTP_POST) {
499 			/* Copy POST payload into buffer for later comparison */
500 			zassert(offset + request_ctx->data_len <=
501 					sizeof(dynamic_response_headers_buffer),
502 				"POST data too long for buffer");
503 			memcpy(dynamic_response_headers_buffer + offset, request_ctx->data,
504 			       request_ctx->data_len);
505 			offset += request_ctx->data_len;
506 
507 			if (status == HTTP_SERVER_DATA_FINAL) {
508 				offset = 0;
509 			}
510 		} else {
511 			zassert(false, "unexpected HTTP method");
512 		}
513 		break;
514 	}
515 
516 	return 0;
517 }
518 
519 struct http_resource_detail_dynamic dynamic_response_headers_detail = {
520 	.common = {
521 		.type = HTTP_RESOURCE_TYPE_DYNAMIC,
522 		.bitmask_of_supported_http_methods = BIT(HTTP_GET) | BIT(HTTP_POST),
523 		.content_type = "text/plain",
524 	},
525 	.cb = dynamic_response_headers_cb,
526 	.user_data = NULL
527 };
528 
529 HTTP_RESOURCE_DEFINE(dynamic_response_headers_resource, test_http_service, "/response_headers",
530 		     &dynamic_response_headers_detail);
531 
532 static int client_fd = -1;
533 static uint8_t buf[BUFFER_SIZE];
534 
535 /* This function ensures that there's at least as much data as requested in
536  * the buffer.
537  */
test_read_data(size_t * offset,size_t need)538 static void test_read_data(size_t *offset, size_t need)
539 {
540 	int ret;
541 
542 	while (*offset < need) {
543 		ret = zsock_recv(client_fd, buf + *offset, sizeof(buf) - *offset, 0);
544 		zassert_not_equal(ret, -1, "recv() failed (%d)", errno);
545 		*offset += ret;
546 		if (ret == 0) {
547 			break;
548 		}
549 	};
550 
551 	zassert_true(*offset >= need, "Not all requested data received");
552 }
553 
554 /* This function moves the remaining data in the buffer to the beginning. */
test_consume_data(size_t * offset,size_t consume)555 static void test_consume_data(size_t *offset, size_t consume)
556 {
557 	zassert_true(*offset >= consume, "Cannot consume more data than received");
558 	*offset -= consume;
559 	memmove(buf, buf + consume, *offset);
560 }
561 
expect_http1_switching_protocols(size_t * offset)562 static void expect_http1_switching_protocols(size_t *offset)
563 {
564 	static const char switching_protocols[] =
565 		"HTTP/1.1 101 Switching Protocols\r\n"
566 		"Connection: Upgrade\r\n"
567 		"Upgrade: h2c\r\n"
568 		"\r\n";
569 
570 	test_read_data(offset, sizeof(switching_protocols) - 1);
571 	zassert_mem_equal(buf, switching_protocols, sizeof(switching_protocols) - 1,
572 			  "Received data doesn't match expected response");
573 	test_consume_data(offset, sizeof(switching_protocols) - 1);
574 }
575 
test_get_frame_header(size_t * offset,struct http2_frame * frame)576 static void test_get_frame_header(size_t *offset, struct http2_frame *frame)
577 {
578 	test_read_data(offset, HTTP2_FRAME_HEADER_SIZE);
579 
580 	frame->length = sys_get_be24(&buf[HTTP2_FRAME_LENGTH_OFFSET]);
581 	frame->type = buf[HTTP2_FRAME_TYPE_OFFSET];
582 	frame->flags = buf[HTTP2_FRAME_FLAGS_OFFSET];
583 	frame->stream_identifier = sys_get_be32(
584 				&buf[HTTP2_FRAME_STREAM_ID_OFFSET]);
585 	frame->stream_identifier &= HTTP2_FRAME_STREAM_ID_MASK;
586 
587 	test_consume_data(offset, HTTP2_FRAME_HEADER_SIZE);
588 }
589 
expect_http2_settings_frame(size_t * offset,bool ack)590 static void expect_http2_settings_frame(size_t *offset, bool ack)
591 {
592 	struct http2_frame frame;
593 
594 	test_get_frame_header(offset, &frame);
595 
596 	zassert_equal(frame.type, HTTP2_SETTINGS_FRAME, "Expected settings frame");
597 	zassert_equal(frame.stream_identifier, 0, "Settings frame stream ID must be 0");
598 
599 	if (ack) {
600 		zassert_equal(frame.length, 0, "Invalid settings frame length");
601 		zassert_equal(frame.flags, HTTP2_FLAG_SETTINGS_ACK,
602 			      "Expected settings ACK flag");
603 	} else {
604 		zassert_equal(frame.length % sizeof(struct http2_settings_field), 0,
605 			      "Invalid settings frame length");
606 		zassert_equal(frame.flags, 0, "Expected no settings flags");
607 
608 		/* Consume settings payload */
609 		test_read_data(offset, frame.length);
610 		test_consume_data(offset, frame.length);
611 	}
612 }
613 
expect_contains_header(const uint8_t * buffer,size_t len,const struct http_header * header)614 static void expect_contains_header(const uint8_t *buffer, size_t len,
615 				   const struct http_header *header)
616 {
617 	int ret;
618 	bool found = false;
619 	struct http_hpack_header_buf header_buf;
620 	size_t consumed = 0;
621 
622 	while (consumed < len) {
623 		ret = http_hpack_decode_header(buffer + consumed, len, &header_buf);
624 		zassert_true(ret >= 0, "Failed to decode header");
625 		zassert_true(consumed + ret <= len, "Frame length exceeded");
626 
627 		if (strncasecmp(header_buf.name, header->name, header_buf.name_len) == 0 &&
628 		    strncasecmp(header_buf.value, header->value, header_buf.value_len) == 0) {
629 			found = true;
630 			break;
631 		}
632 
633 		consumed += ret;
634 	}
635 
636 	zassert_true(found, "Header '%s: %s' not found", header->name, header->value);
637 }
638 
expect_http2_headers_frame(size_t * offset,int stream_id,uint8_t flags,const struct http_header * headers,size_t headers_count)639 static void expect_http2_headers_frame(size_t *offset, int stream_id, uint8_t flags,
640 				       const struct http_header *headers, size_t headers_count)
641 {
642 	struct http2_frame frame;
643 
644 	test_get_frame_header(offset, &frame);
645 
646 	zassert_equal(frame.type, HTTP2_HEADERS_FRAME, "Expected headers frame, got frame type %u",
647 		      frame.type);
648 	zassert_equal(frame.stream_identifier, stream_id,
649 		      "Invalid headers frame stream ID");
650 	zassert_equal(frame.flags, flags, "Unexpected flags received (expected %x got %x)", flags,
651 		      frame.flags);
652 
653 	/* Consume headers payload */
654 	test_read_data(offset, frame.length);
655 
656 	for (size_t i = 0; i < headers_count; i++) {
657 		expect_contains_header(buf, frame.length, &headers[i]);
658 	}
659 
660 	test_consume_data(offset, frame.length);
661 }
662 
expect_http2_data_frame(size_t * offset,int stream_id,const uint8_t * payload,size_t payload_len,uint8_t flags)663 static void expect_http2_data_frame(size_t *offset, int stream_id,
664 				    const uint8_t *payload, size_t payload_len,
665 				    uint8_t flags)
666 {
667 	struct http2_frame frame;
668 
669 	test_get_frame_header(offset, &frame);
670 
671 	zassert_equal(frame.type, HTTP2_DATA_FRAME, "Expected data frame");
672 	zassert_equal(frame.stream_identifier, stream_id,
673 		      "Invalid data frame stream ID");
674 	zassert_equal(frame.flags, flags, "Unexpected flags received");
675 	zassert_equal(frame.length, payload_len, "Unexpected data frame length");
676 
677 	/* Verify data payload */
678 	test_read_data(offset, frame.length);
679 	zassert_mem_equal(buf, payload, payload_len, "Unexpected data payload");
680 	test_consume_data(offset, frame.length);
681 }
682 
expect_http2_window_update_frame(size_t * offset,int stream_id)683 static void expect_http2_window_update_frame(size_t *offset, int stream_id)
684 {
685 	struct http2_frame frame;
686 
687 	test_get_frame_header(offset, &frame);
688 
689 	zassert_equal(frame.type, HTTP2_WINDOW_UPDATE_FRAME,
690 		      "Expected window update frame");
691 	zassert_equal(frame.stream_identifier, stream_id,
692 		      "Invalid window update frame stream ID (expected %d got %d)", stream_id,
693 		      frame.stream_identifier);
694 	zassert_equal(frame.flags, 0, "Unexpected flags received");
695 	zassert_equal(frame.length, sizeof(uint32_t),
696 		      "Unexpected window update frame length");
697 
698 
699 	/* Consume window update payload */
700 	test_read_data(offset, frame.length);
701 	test_consume_data(offset, frame.length);
702 }
703 
ZTEST(server_function_tests,test_http2_get_concurrent_streams)704 ZTEST(server_function_tests, test_http2_get_concurrent_streams)
705 {
706 	static const uint8_t request_get_2_streams[] = {
707 		TEST_HTTP2_MAGIC,
708 		TEST_HTTP2_SETTINGS,
709 		TEST_HTTP2_SETTINGS_ACK,
710 		TEST_HTTP2_HEADERS_GET_ROOT_STREAM_1,
711 		TEST_HTTP2_HEADERS_GET_INDEX_STREAM_2,
712 		TEST_HTTP2_GOAWAY,
713 	};
714 	size_t offset = 0;
715 	int ret;
716 
717 	ret = zsock_send(client_fd, request_get_2_streams,
718 			 sizeof(request_get_2_streams), 0);
719 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
720 
721 	memset(buf, 0, sizeof(buf));
722 
723 	/* Settings frame is expected twice (server settings + settings ACK) */
724 	expect_http2_settings_frame(&offset, false);
725 	expect_http2_settings_frame(&offset, true);
726 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1, HTTP2_FLAG_END_HEADERS, NULL, 0);
727 	expect_http2_data_frame(&offset, TEST_STREAM_ID_1, TEST_STATIC_PAYLOAD,
728 				strlen(TEST_STATIC_PAYLOAD),
729 				HTTP2_FLAG_END_STREAM);
730 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_2, HTTP2_FLAG_END_HEADERS, NULL, 0);
731 	expect_http2_data_frame(&offset, TEST_STREAM_ID_2, NULL, 0,
732 				HTTP2_FLAG_END_STREAM);
733 }
734 
ZTEST(server_function_tests,test_http2_static_get)735 ZTEST(server_function_tests, test_http2_static_get)
736 {
737 	static const uint8_t request_get_static_simple[] = {
738 		TEST_HTTP2_MAGIC,
739 		TEST_HTTP2_SETTINGS,
740 		TEST_HTTP2_SETTINGS_ACK,
741 		TEST_HTTP2_HEADERS_GET_ROOT_STREAM_1,
742 		TEST_HTTP2_GOAWAY,
743 	};
744 	size_t offset = 0;
745 	int ret;
746 
747 	ret = zsock_send(client_fd, request_get_static_simple,
748 			 sizeof(request_get_static_simple), 0);
749 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
750 
751 	memset(buf, 0, sizeof(buf));
752 
753 	expect_http2_settings_frame(&offset, false);
754 	expect_http2_settings_frame(&offset, true);
755 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1, HTTP2_FLAG_END_HEADERS, NULL, 0);
756 	expect_http2_data_frame(&offset, TEST_STREAM_ID_1, TEST_STATIC_PAYLOAD,
757 				strlen(TEST_STATIC_PAYLOAD),
758 				HTTP2_FLAG_END_STREAM);
759 }
760 
ZTEST(server_function_tests,test_http1_static_upgrade_get)761 ZTEST(server_function_tests, test_http1_static_upgrade_get)
762 {
763 	static const char http1_request[] =
764 		"GET / HTTP/1.1\r\n"
765 		"Host: 127.0.0.1:8080\r\n"
766 		"Accept: */*\r\n"
767 		"Accept-Encoding: deflate, gzip, br\r\n"
768 		"Connection: Upgrade, HTTP2-Settings\r\n"
769 		"Upgrade: h2c\r\n"
770 		"HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA\r\n"
771 		"\r\n";
772 	size_t offset = 0;
773 	int ret;
774 
775 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
776 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
777 
778 	memset(buf, 0, sizeof(buf));
779 
780 	/* Verify HTTP1 switching protocols response. */
781 	expect_http1_switching_protocols(&offset);
782 
783 	/* Verify HTTP2 frames. */
784 	expect_http2_settings_frame(&offset, false);
785 	expect_http2_headers_frame(&offset, UPGRADE_STREAM_ID, HTTP2_FLAG_END_HEADERS, NULL, 0);
786 	expect_http2_data_frame(&offset, UPGRADE_STREAM_ID, TEST_STATIC_PAYLOAD,
787 				strlen(TEST_STATIC_PAYLOAD),
788 				HTTP2_FLAG_END_STREAM);
789 }
790 
ZTEST(server_function_tests,test_http1_static_get)791 ZTEST(server_function_tests, test_http1_static_get)
792 {
793 	static const char http1_request[] =
794 		"GET / HTTP/1.1\r\n"
795 		"Host: 127.0.0.1:8080\r\n"
796 		"User-Agent: curl/7.68.0\r\n"
797 		"Accept: */*\r\n"
798 		"Accept-Encoding: deflate, gzip, br\r\n"
799 		"\r\n";
800 	static const char expected_response[] =
801 		"HTTP/1.1 200 OK\r\n"
802 		"Content-Type: text/html\r\n"
803 		"Content-Length: 13\r\n"
804 		"\r\n"
805 		TEST_STATIC_PAYLOAD;
806 	size_t offset = 0;
807 	int ret;
808 
809 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
810 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
811 
812 	memset(buf, 0, sizeof(buf));
813 
814 	test_read_data(&offset, sizeof(expected_response) - 1);
815 	zassert_mem_equal(buf, expected_response, sizeof(expected_response) - 1,
816 			  "Received data doesn't match expected response");
817 }
818 
819 /* Common code to verify POST/PUT/PATCH */
common_verify_http2_dynamic_post_request(const uint8_t * request,size_t request_len)820 static void common_verify_http2_dynamic_post_request(const uint8_t *request,
821 						     size_t request_len)
822 {
823 	size_t offset = 0;
824 	int ret;
825 
826 	ret = zsock_send(client_fd, request, request_len, 0);
827 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
828 
829 	memset(buf, 0, sizeof(buf));
830 
831 	expect_http2_settings_frame(&offset, false);
832 	expect_http2_settings_frame(&offset, true);
833 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1,
834 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM, NULL, 0);
835 
836 	zassert_equal(dynamic_payload_len, strlen(TEST_DYNAMIC_POST_PAYLOAD),
837 		      "Wrong dynamic resource length");
838 	zassert_mem_equal(dynamic_payload, TEST_DYNAMIC_POST_PAYLOAD,
839 			  dynamic_payload_len, "Wrong dynamic resource data");
840 }
841 
ZTEST(server_function_tests,test_http2_dynamic_post)842 ZTEST(server_function_tests, test_http2_dynamic_post)
843 {
844 	static const uint8_t request_post_dynamic[] = {
845 		TEST_HTTP2_MAGIC,
846 		TEST_HTTP2_SETTINGS,
847 		TEST_HTTP2_SETTINGS_ACK,
848 		TEST_HTTP2_HEADERS_POST_DYNAMIC_STREAM_1,
849 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1,
850 		TEST_HTTP2_GOAWAY,
851 	};
852 
853 	common_verify_http2_dynamic_post_request(request_post_dynamic,
854 						 sizeof(request_post_dynamic));
855 }
856 
857 /* Common code to verify POST/PUT/PATCH */
common_verify_http1_dynamic_upgrade_post(const uint8_t * method)858 static void common_verify_http1_dynamic_upgrade_post(const uint8_t *method)
859 {
860 	static const char http1_request[] =
861 		" /dynamic HTTP/1.1\r\n"
862 		"Host: 127.0.0.1:8080\r\n"
863 		"User-Agent: curl/7.68.0\r\n"
864 		"Accept: */*\r\n"
865 		"Content-Length: 17\r\n"
866 		"Connection: Upgrade, HTTP2-Settings\r\n"
867 		"Upgrade: h2c\r\n"
868 		"HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA\r\n"
869 		"\r\n"
870 		TEST_DYNAMIC_POST_PAYLOAD;
871 	size_t offset = 0;
872 	int ret;
873 
874 	ret = zsock_send(client_fd, method, strlen(method), 0);
875 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
876 
877 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
878 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
879 
880 	memset(buf, 0, sizeof(buf));
881 
882 	/* Verify HTTP1 switching protocols response. */
883 	expect_http1_switching_protocols(&offset);
884 
885 	/* Verify HTTP2 frames. */
886 	expect_http2_settings_frame(&offset, false);
887 	expect_http2_headers_frame(&offset, UPGRADE_STREAM_ID,
888 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM, NULL, 0);
889 
890 	zassert_equal(dynamic_payload_len, strlen(TEST_DYNAMIC_POST_PAYLOAD),
891 		      "Wrong dynamic resource length");
892 	zassert_mem_equal(dynamic_payload, TEST_DYNAMIC_POST_PAYLOAD,
893 			  dynamic_payload_len, "Wrong dynamic resource data");
894 }
895 
ZTEST(server_function_tests,test_http1_dynamic_upgrade_post)896 ZTEST(server_function_tests, test_http1_dynamic_upgrade_post)
897 {
898 	common_verify_http1_dynamic_upgrade_post("POST");
899 }
900 
901 /* Common code to verify POST/PUT/PATCH */
common_verify_http1_dynamic_post(const uint8_t * method)902 static void common_verify_http1_dynamic_post(const uint8_t *method)
903 {
904 	static const char http1_request[] =
905 		" /dynamic HTTP/1.1\r\n"
906 		"Host: 127.0.0.1:8080\r\n"
907 		"User-Agent: curl/7.68.0\r\n"
908 		"Accept: */*\r\n"
909 		"Content-Length: 17\r\n"
910 		"\r\n"
911 		TEST_DYNAMIC_POST_PAYLOAD;
912 	static const char expected_response[] = "HTTP/1.1 200\r\n"
913 						"Transfer-Encoding: chunked\r\n"
914 						"Content-Type: text/plain\r\n"
915 						"\r\n"
916 						"0\r\n\r\n";
917 	size_t offset = 0;
918 	int ret;
919 
920 	ret = zsock_send(client_fd, method, strlen(method), 0);
921 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
922 
923 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
924 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
925 
926 	memset(buf, 0, sizeof(buf));
927 
928 	test_read_data(&offset, sizeof(expected_response) - 1);
929 	zassert_mem_equal(buf, expected_response, sizeof(expected_response) - 1,
930 			  "Received data doesn't match expected response");
931 
932 	zassert_equal(dynamic_payload_len, strlen(TEST_DYNAMIC_POST_PAYLOAD),
933 		      "Wrong dynamic resource length");
934 	zassert_mem_equal(dynamic_payload, TEST_DYNAMIC_POST_PAYLOAD,
935 			  dynamic_payload_len, "Wrong dynamic resource data");
936 }
937 
ZTEST(server_function_tests,test_http1_dynamic_post)938 ZTEST(server_function_tests, test_http1_dynamic_post)
939 {
940 	common_verify_http1_dynamic_post("POST");
941 }
942 
common_verify_http2_dynamic_get_request(const uint8_t * request,size_t request_len)943 static void common_verify_http2_dynamic_get_request(const uint8_t *request,
944 						    size_t request_len)
945 {
946 	size_t offset = 0;
947 	int ret;
948 
949 	dynamic_payload_len = strlen(TEST_DYNAMIC_GET_PAYLOAD);
950 	memcpy(dynamic_payload, TEST_DYNAMIC_GET_PAYLOAD, dynamic_payload_len);
951 
952 	ret = zsock_send(client_fd, request, request_len, 0);
953 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
954 
955 	memset(buf, 0, sizeof(buf));
956 
957 	expect_http2_settings_frame(&offset, false);
958 	expect_http2_settings_frame(&offset, true);
959 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1, HTTP2_FLAG_END_HEADERS, NULL, 0);
960 	expect_http2_data_frame(&offset, TEST_STREAM_ID_1, TEST_DYNAMIC_GET_PAYLOAD,
961 				strlen(TEST_DYNAMIC_GET_PAYLOAD), HTTP2_FLAG_END_STREAM);
962 }
963 
ZTEST(server_function_tests,test_http2_dynamic_get)964 ZTEST(server_function_tests, test_http2_dynamic_get)
965 {
966 	static const uint8_t request_get_dynamic[] = {
967 		TEST_HTTP2_MAGIC,
968 		TEST_HTTP2_SETTINGS,
969 		TEST_HTTP2_SETTINGS_ACK,
970 		TEST_HTTP2_HEADERS_GET_DYNAMIC_STREAM_1,
971 		TEST_HTTP2_GOAWAY,
972 	};
973 
974 	common_verify_http2_dynamic_get_request(request_get_dynamic,
975 						sizeof(request_get_dynamic));
976 }
977 
ZTEST(server_function_tests,test_http1_dynamic_upgrade_get)978 ZTEST(server_function_tests, test_http1_dynamic_upgrade_get)
979 {
980 	static const char http1_request[] =
981 		"GET /dynamic HTTP/1.1\r\n"
982 		"Host: 127.0.0.1:8080\r\n"
983 		"User-Agent: curl/7.68.0\r\n"
984 		"Accept: */*\r\n"
985 		"Accept-Encoding: deflate, gzip, br\r\n"
986 		"Connection: Upgrade, HTTP2-Settings\r\n"
987 		"Upgrade: h2c\r\n"
988 		"HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA\r\n"
989 		"\r\n";
990 	size_t offset = 0;
991 	int ret;
992 
993 	dynamic_payload_len = strlen(TEST_DYNAMIC_GET_PAYLOAD);
994 	memcpy(dynamic_payload, TEST_DYNAMIC_GET_PAYLOAD, dynamic_payload_len);
995 
996 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
997 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
998 
999 	memset(buf, 0, sizeof(buf));
1000 
1001 	/* Verify HTTP1 switching protocols response. */
1002 	expect_http1_switching_protocols(&offset);
1003 
1004 	/* Verify HTTP2 frames. */
1005 	expect_http2_settings_frame(&offset, false);
1006 	expect_http2_headers_frame(&offset, UPGRADE_STREAM_ID, HTTP2_FLAG_END_HEADERS, NULL, 0);
1007 	expect_http2_data_frame(&offset, UPGRADE_STREAM_ID, TEST_DYNAMIC_GET_PAYLOAD,
1008 				strlen(TEST_DYNAMIC_GET_PAYLOAD), HTTP2_FLAG_END_STREAM);
1009 }
1010 
ZTEST(server_function_tests,test_http1_dynamic_get)1011 ZTEST(server_function_tests, test_http1_dynamic_get)
1012 {
1013 	static const char http1_request[] =
1014 		"GET /dynamic HTTP/1.1\r\n"
1015 		"Host: 127.0.0.1:8080\r\n"
1016 		"User-Agent: curl/7.68.0\r\n"
1017 		"Accept: */*\r\n"
1018 		"Accept-Encoding: deflate, gzip, br\r\n"
1019 		"\r\n";
1020 	static const char expected_response[] = "HTTP/1.1 200\r\n"
1021 						"Transfer-Encoding: chunked\r\n"
1022 						"Content-Type: text/plain\r\n"
1023 						"\r\n"
1024 						"10\r\n" TEST_DYNAMIC_GET_PAYLOAD "\r\n"
1025 						"0\r\n\r\n";
1026 	size_t offset = 0;
1027 	int ret;
1028 
1029 	dynamic_payload_len = strlen(TEST_DYNAMIC_GET_PAYLOAD);
1030 	memcpy(dynamic_payload, TEST_DYNAMIC_GET_PAYLOAD, dynamic_payload_len);
1031 
1032 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
1033 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1034 
1035 	memset(buf, 0, sizeof(buf));
1036 
1037 	test_read_data(&offset, sizeof(expected_response) - 1);
1038 	zassert_mem_equal(buf, expected_response, sizeof(expected_response) - 1,
1039 			  "Received data doesn't match expected response");
1040 }
1041 
ZTEST(server_function_tests,test_http2_dynamic_put)1042 ZTEST(server_function_tests, test_http2_dynamic_put)
1043 {
1044 	static const uint8_t request_put_dynamic[] = {
1045 		TEST_HTTP2_MAGIC,
1046 		TEST_HTTP2_SETTINGS,
1047 		TEST_HTTP2_SETTINGS_ACK,
1048 		TEST_HTTP2_HEADERS_PUT_DYNAMIC_STREAM_1,
1049 		TEST_HTTP2_DATA_PUT_DYNAMIC_STREAM_1,
1050 		TEST_HTTP2_GOAWAY,
1051 	};
1052 
1053 	common_verify_http2_dynamic_post_request(request_put_dynamic,
1054 						 sizeof(request_put_dynamic));
1055 }
1056 
ZTEST(server_function_tests,test_http1_dynamic_upgrade_put)1057 ZTEST(server_function_tests, test_http1_dynamic_upgrade_put)
1058 {
1059 	common_verify_http1_dynamic_upgrade_post("PUT");
1060 }
1061 
ZTEST(server_function_tests,test_http1_dynamic_put)1062 ZTEST(server_function_tests, test_http1_dynamic_put)
1063 {
1064 	common_verify_http1_dynamic_post("PUT");
1065 }
1066 
ZTEST(server_function_tests,test_http2_dynamic_patch)1067 ZTEST(server_function_tests, test_http2_dynamic_patch)
1068 {
1069 	static const uint8_t request_patch_dynamic[] = {
1070 		TEST_HTTP2_MAGIC,
1071 		TEST_HTTP2_SETTINGS,
1072 		TEST_HTTP2_SETTINGS_ACK,
1073 		TEST_HTTP2_HEADERS_PATCH_DYNAMIC_STREAM_1,
1074 		TEST_HTTP2_DATA_PATCH_DYNAMIC_STREAM_1,
1075 		TEST_HTTP2_GOAWAY,
1076 	};
1077 
1078 	common_verify_http2_dynamic_post_request(request_patch_dynamic,
1079 						 sizeof(request_patch_dynamic));
1080 }
1081 
ZTEST(server_function_tests,test_http1_dynamic_upgrade_patch)1082 ZTEST(server_function_tests, test_http1_dynamic_upgrade_patch)
1083 {
1084 	common_verify_http1_dynamic_upgrade_post("PATCH");
1085 }
1086 
ZTEST(server_function_tests,test_http1_dynamic_patch)1087 ZTEST(server_function_tests, test_http1_dynamic_patch)
1088 {
1089 	common_verify_http1_dynamic_post("PATCH");
1090 }
1091 
ZTEST(server_function_tests,test_http2_dynamic_delete)1092 ZTEST(server_function_tests, test_http2_dynamic_delete)
1093 {
1094 	static const uint8_t request_delete_dynamic[] = {
1095 		TEST_HTTP2_MAGIC,
1096 		TEST_HTTP2_SETTINGS,
1097 		TEST_HTTP2_SETTINGS_ACK,
1098 		TEST_HTTP2_HEADERS_DELETE_DYNAMIC_STREAM_1,
1099 		TEST_HTTP2_GOAWAY,
1100 	};
1101 	size_t offset = 0;
1102 	int ret;
1103 
1104 	ret = zsock_send(client_fd, request_delete_dynamic,
1105 			 sizeof(request_delete_dynamic), 0);
1106 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1107 
1108 	memset(buf, 0, sizeof(buf));
1109 
1110 	expect_http2_settings_frame(&offset, false);
1111 	expect_http2_settings_frame(&offset, true);
1112 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1,
1113 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM,
1114 				   NULL, 0);
1115 }
1116 
ZTEST(server_function_tests,test_http1_dynamic_upgrade_delete)1117 ZTEST(server_function_tests, test_http1_dynamic_upgrade_delete)
1118 {
1119 	static const char http1_request[] =
1120 		"DELETE /dynamic HTTP/1.1\r\n"
1121 		"Host: 127.0.0.1:8080\r\n"
1122 		"User-Agent: curl/7.68.0\r\n"
1123 		"Connection: Upgrade, HTTP2-Settings\r\n"
1124 		"Upgrade: h2c\r\n"
1125 		"HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA\r\n"
1126 		"\r\n";
1127 	size_t offset = 0;
1128 	int ret;
1129 
1130 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
1131 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1132 
1133 	memset(buf, 0, sizeof(buf));
1134 
1135 	/* Verify HTTP1 switching protocols response. */
1136 	expect_http1_switching_protocols(&offset);
1137 
1138 	/* Verify HTTP2 frames. */
1139 	expect_http2_settings_frame(&offset, false);
1140 	expect_http2_headers_frame(&offset, UPGRADE_STREAM_ID,
1141 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM,
1142 				   NULL, 0);
1143 }
1144 
ZTEST(server_function_tests,test_http1_dynamic_delete)1145 ZTEST(server_function_tests, test_http1_dynamic_delete)
1146 {
1147 	static const char http1_request[] =
1148 		"DELETE /dynamic HTTP/1.1\r\n"
1149 		"Host: 127.0.0.1:8080\r\n"
1150 		"User-Agent: curl/7.68.0\r\n"
1151 		"\r\n";
1152 	static const char expected_response[] = "HTTP/1.1 200\r\n"
1153 						"Transfer-Encoding: chunked\r\n"
1154 						"Content-Type: text/plain\r\n"
1155 						"\r\n"
1156 						"0\r\n\r\n";
1157 	size_t offset = 0;
1158 	int ret;
1159 
1160 	ret = zsock_send(client_fd, http1_request, strlen(http1_request), 0);
1161 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1162 
1163 	memset(buf, 0, sizeof(buf));
1164 
1165 	test_read_data(&offset, sizeof(expected_response) - 1);
1166 	zassert_mem_equal(buf, expected_response, sizeof(expected_response) - 1,
1167 			  "Received data doesn't match expected response");
1168 }
1169 
ZTEST(server_function_tests,test_http1_connection_close)1170 ZTEST(server_function_tests, test_http1_connection_close)
1171 {
1172 	static const char http1_request_1[] =
1173 		"GET / HTTP/1.1\r\n"
1174 		"Host: 127.0.0.1:8080\r\n"
1175 		"User-Agent: curl/7.68.0\r\n"
1176 		"Accept: */*\r\n"
1177 		"Accept-Encoding: deflate, gzip, br\r\n"
1178 		"\r\n";
1179 	static const char http1_request_2[] =
1180 		"GET / HTTP/1.1\r\n"
1181 		"Host: 127.0.0.1:8080\r\n"
1182 		"User-Agent: curl/7.68.0\r\n"
1183 		"Accept: */*\r\n"
1184 		"Accept-Encoding: deflate, gzip, br\r\n"
1185 		"Connection: close\r\n"
1186 		"\r\n";
1187 	static const char expected_response[] =
1188 		"HTTP/1.1 200 OK\r\n"
1189 		"Content-Type: text/html\r\n"
1190 		"Content-Length: 13\r\n"
1191 		"\r\n"
1192 		TEST_STATIC_PAYLOAD;
1193 	size_t offset = 0;
1194 	int ret;
1195 
1196 	ret = zsock_send(client_fd, http1_request_1, strlen(http1_request_1), 0);
1197 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1198 
1199 	memset(buf, 0, sizeof(buf));
1200 
1201 	test_read_data(&offset, sizeof(expected_response) - 1);
1202 	zassert_mem_equal(buf, expected_response, sizeof(expected_response) - 1,
1203 			  "Received data doesn't match expected response");
1204 	test_consume_data(&offset, sizeof(expected_response) - 1);
1205 
1206 	/* With no connection: close, the server shall serve another request on
1207 	 * the same connection.
1208 	 */
1209 	ret = zsock_send(client_fd, http1_request_2, strlen(http1_request_2), 0);
1210 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1211 
1212 	memset(buf, 0, sizeof(buf));
1213 
1214 	test_read_data(&offset, sizeof(expected_response) - 1);
1215 	zassert_mem_equal(buf, expected_response, sizeof(expected_response) - 1,
1216 			  "Received data doesn't match expected response");
1217 	test_consume_data(&offset, sizeof(expected_response) - 1);
1218 
1219 	/* Second request included connection: close, so we should expect the
1220 	 * connection to be closed now.
1221 	 */
1222 	ret = zsock_recv(client_fd, buf, sizeof(buf), 0);
1223 	zassert_equal(ret, 0, "Connection should've been closed");
1224 }
1225 
ZTEST(server_function_tests,test_http2_post_data_with_padding)1226 ZTEST(server_function_tests, test_http2_post_data_with_padding)
1227 {
1228 	static const uint8_t request_post_dynamic[] = {
1229 		TEST_HTTP2_MAGIC,
1230 		TEST_HTTP2_SETTINGS,
1231 		TEST_HTTP2_SETTINGS_ACK,
1232 		TEST_HTTP2_HEADERS_POST_DYNAMIC_STREAM_1,
1233 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1_PADDED,
1234 		TEST_HTTP2_GOAWAY,
1235 	};
1236 
1237 	common_verify_http2_dynamic_post_request(request_post_dynamic,
1238 						 sizeof(request_post_dynamic));
1239 }
1240 
ZTEST(server_function_tests,test_http2_post_headers_with_priority)1241 ZTEST(server_function_tests, test_http2_post_headers_with_priority)
1242 {
1243 	static const uint8_t request_post_dynamic[] = {
1244 		TEST_HTTP2_MAGIC,
1245 		TEST_HTTP2_SETTINGS,
1246 		TEST_HTTP2_SETTINGS_ACK,
1247 		TEST_HTTP2_HEADERS_POST_DYNAMIC_STREAM_1_PRIORITY,
1248 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1_PADDED,
1249 		TEST_HTTP2_GOAWAY,
1250 	};
1251 
1252 	common_verify_http2_dynamic_post_request(request_post_dynamic,
1253 						 sizeof(request_post_dynamic));
1254 }
1255 
ZTEST(server_function_tests,test_http2_post_headers_with_priority_and_padding)1256 ZTEST(server_function_tests, test_http2_post_headers_with_priority_and_padding)
1257 {
1258 	static const uint8_t request_post_dynamic[] = {
1259 		TEST_HTTP2_MAGIC,
1260 		TEST_HTTP2_SETTINGS,
1261 		TEST_HTTP2_SETTINGS_ACK,
1262 		TEST_HTTP2_HEADERS_POST_DYNAMIC_STREAM_1_PRIORITY_PADDED,
1263 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1_PADDED,
1264 		TEST_HTTP2_GOAWAY,
1265 	};
1266 
1267 	common_verify_http2_dynamic_post_request(request_post_dynamic,
1268 						 sizeof(request_post_dynamic));
1269 }
1270 
ZTEST(server_function_tests,test_http2_post_headers_with_continuation)1271 ZTEST(server_function_tests, test_http2_post_headers_with_continuation)
1272 {
1273 	static const uint8_t request_post_dynamic[] = {
1274 		TEST_HTTP2_MAGIC,
1275 		TEST_HTTP2_SETTINGS,
1276 		TEST_HTTP2_SETTINGS_ACK,
1277 		TEST_HTTP2_PARTIAL_HEADERS_POST_DYNAMIC_STREAM_1,
1278 		TEST_HTTP2_CONTINUATION_POST_DYNAMIC_STREAM_1,
1279 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1,
1280 		TEST_HTTP2_GOAWAY,
1281 	};
1282 
1283 	common_verify_http2_dynamic_post_request(request_post_dynamic,
1284 						 sizeof(request_post_dynamic));
1285 }
1286 
ZTEST(server_function_tests,test_http2_post_missing_continuation)1287 ZTEST(server_function_tests, test_http2_post_missing_continuation)
1288 {
1289 	static const uint8_t request_post_dynamic[] = {
1290 		TEST_HTTP2_MAGIC,
1291 		TEST_HTTP2_SETTINGS,
1292 		TEST_HTTP2_SETTINGS_ACK,
1293 		TEST_HTTP2_PARTIAL_HEADERS_POST_DYNAMIC_STREAM_1,
1294 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1,
1295 		TEST_HTTP2_GOAWAY,
1296 	};
1297 	size_t offset = 0;
1298 	int ret;
1299 
1300 	memset(buf, 0, sizeof(buf));
1301 
1302 	ret = zsock_send(client_fd, request_post_dynamic,
1303 			 sizeof(request_post_dynamic), 0);
1304 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1305 
1306 	/* Expect settings, but processing headers (and lack of continuation
1307 	 * frame) should break the stream, and trigger disconnect.
1308 	 */
1309 	expect_http2_settings_frame(&offset, false);
1310 	expect_http2_settings_frame(&offset, true);
1311 
1312 	ret = zsock_recv(client_fd, buf, sizeof(buf), 0);
1313 	zassert_equal(ret, 0, "Connection should've been closed");
1314 }
1315 
ZTEST(server_function_tests,test_http2_post_trailing_headers)1316 ZTEST(server_function_tests, test_http2_post_trailing_headers)
1317 {
1318 	static const uint8_t request_post_dynamic[] = {
1319 		TEST_HTTP2_MAGIC,
1320 		TEST_HTTP2_SETTINGS,
1321 		TEST_HTTP2_SETTINGS_ACK,
1322 		TEST_HTTP2_HEADERS_POST_DYNAMIC_STREAM_1,
1323 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1_NO_END_STREAM,
1324 		TEST_HTTP2_TRAILING_HEADER_STREAM_1,
1325 		TEST_HTTP2_GOAWAY,
1326 	};
1327 	size_t offset = 0;
1328 	int ret;
1329 
1330 	ret = zsock_send(client_fd, request_post_dynamic,
1331 			 sizeof(request_post_dynamic), 0);
1332 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1333 
1334 	memset(buf, 0, sizeof(buf));
1335 
1336 	expect_http2_settings_frame(&offset, false);
1337 	expect_http2_settings_frame(&offset, true);
1338 	/* In this case order is reversed, data frame had not END_STREAM flag.
1339 	 * Because of this, reply will only be sent after processing the final
1340 	 * trailing headers frame, but this will be preceded by window update
1341 	 * after processing the data frame.
1342 	 */
1343 	expect_http2_window_update_frame(&offset, TEST_STREAM_ID_1);
1344 	expect_http2_window_update_frame(&offset, 0);
1345 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1,
1346 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM, NULL, 0);
1347 
1348 	zassert_equal(dynamic_payload_len, strlen(TEST_DYNAMIC_POST_PAYLOAD),
1349 		      "Wrong dynamic resource length");
1350 	zassert_mem_equal(dynamic_payload, TEST_DYNAMIC_POST_PAYLOAD,
1351 			  dynamic_payload_len, "Wrong dynamic resource data");
1352 }
1353 
ZTEST(server_function_tests,test_http2_get_headers_with_padding)1354 ZTEST(server_function_tests, test_http2_get_headers_with_padding)
1355 {
1356 	static const uint8_t request_get_dynamic[] = {
1357 		TEST_HTTP2_MAGIC,
1358 		TEST_HTTP2_SETTINGS,
1359 		TEST_HTTP2_SETTINGS_ACK,
1360 		TEST_HTTP2_HEADERS_GET_DYNAMIC_STREAM_1_PADDED,
1361 		TEST_HTTP2_GOAWAY,
1362 	};
1363 
1364 	common_verify_http2_dynamic_get_request(request_get_dynamic,
1365 						sizeof(request_get_dynamic));
1366 }
1367 
ZTEST(server_function_tests,test_http2_rst_stream)1368 ZTEST(server_function_tests, test_http2_rst_stream)
1369 {
1370 	static const uint8_t request_rst_stream[] = {
1371 		TEST_HTTP2_MAGIC,
1372 		TEST_HTTP2_SETTINGS,
1373 		TEST_HTTP2_SETTINGS_ACK,
1374 		TEST_HTTP2_HEADERS_POST_DYNAMIC_STREAM_1,
1375 		TEST_HTTP2_RST_STREAM_STREAM_1,
1376 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1,
1377 		TEST_HTTP2_GOAWAY,
1378 	};
1379 
1380 	size_t offset = 0;
1381 	int ret;
1382 
1383 	memset(buf, 0, sizeof(buf));
1384 
1385 	ret = zsock_send(client_fd, request_rst_stream,
1386 			 sizeof(request_rst_stream), 0);
1387 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1388 
1389 	/* Expect settings, but processing RST_STREAM should close the stream,
1390 	 * so DATA frame should trigger connection error (closed stream) and
1391 	 * disconnect.
1392 	 */
1393 	expect_http2_settings_frame(&offset, false);
1394 	expect_http2_settings_frame(&offset, true);
1395 
1396 	ret = zsock_recv(client_fd, buf, sizeof(buf), 0);
1397 	zassert_equal(ret, 0, "Connection should've been closed");
1398 }
1399 
1400 static const char http1_header_capture_common_response[] = "HTTP/1.1 200\r\n"
1401 							   "Transfer-Encoding: chunked\r\n"
1402 							   "Content-Type: text/plain\r\n"
1403 							   "\r\n"
1404 							   "0\r\n\r\n";
1405 
test_http1_header_capture_common(const char * request)1406 static void test_http1_header_capture_common(const char *request)
1407 {
1408 	size_t offset = 0;
1409 	int ret;
1410 
1411 	ret = zsock_send(client_fd, request, strlen(request), 0);
1412 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1413 
1414 	test_read_data(&offset, sizeof(http1_header_capture_common_response) - 1);
1415 }
1416 
ZTEST(server_function_tests,test_http1_header_capture)1417 ZTEST(server_function_tests, test_http1_header_capture)
1418 {
1419 	static const char request[] = "GET /header_capture HTTP/1.1\r\n"
1420 				      "User-Agent: curl/7.68.0\r\n"
1421 				      "Test-Header: test_value\r\n"
1422 				      "Accept: */*\r\n"
1423 				      "Accept-Encoding: deflate, gzip, br\r\n"
1424 				      "\r\n";
1425 	struct http_header *hdrs = request_headers_clone.headers;
1426 	int ret;
1427 
1428 	test_http1_header_capture_common(request);
1429 
1430 	zassert_equal(request_headers_clone.count, 2,
1431 		      "Didn't capture the expected number of headers");
1432 	zassert_equal(request_headers_clone.status, HTTP_HEADER_STATUS_OK,
1433 		      "Header capture status was not OK");
1434 
1435 	zassert_not_equal(hdrs[0].name, NULL, "First header name is NULL");
1436 	zassert_not_equal(hdrs[0].value, NULL, "First header value is NULL");
1437 	zassert_not_equal(hdrs[1].name, NULL, "Second header name is NULL");
1438 	zassert_not_equal(hdrs[1].value, NULL, "Second header value is NULL");
1439 
1440 	ret = strcmp(hdrs[0].name, "User-Agent");
1441 	zassert_equal(0, ret, "Header strings did not match");
1442 	ret = strcmp(hdrs[0].value, "curl/7.68.0");
1443 	zassert_equal(0, ret, "Header strings did not match");
1444 	ret = strcmp(hdrs[1].name, "Test-Header");
1445 	zassert_equal(0, ret, "Header strings did not match");
1446 	ret = strcmp(hdrs[1].value, "test_value");
1447 	zassert_equal(0, ret, "Header strings did not match");
1448 }
1449 
ZTEST(server_function_tests,test_http1_header_too_long)1450 ZTEST(server_function_tests, test_http1_header_too_long)
1451 {
1452 	static const char request[] =
1453 		"GET /header_capture HTTP/1.1\r\n"
1454 		"User-Agent: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n"
1455 		"Test-Header: test_value\r\n"
1456 		"Accept: */*\r\n"
1457 		"Accept-Encoding: deflate, gzip, br\r\n"
1458 		"\r\n";
1459 	struct http_header *hdrs = request_headers_clone.headers;
1460 	int ret;
1461 
1462 	test_http1_header_capture_common(request);
1463 
1464 	zassert_equal(request_headers_clone.count, 1,
1465 		      "Didn't capture the expected number of headers");
1466 	zassert_equal(request_headers_clone.status, HTTP_HEADER_STATUS_DROPPED,
1467 		      "Header capture status was OK, but should not have been");
1468 
1469 	/* First header too long should not stop second header being captured into first slot */
1470 	zassert_not_equal(hdrs[0].name, NULL, "First header name is NULL");
1471 	zassert_not_equal(hdrs[0].value, NULL, "First header value is NULL");
1472 
1473 	ret = strcmp(hdrs[0].name, "Test-Header");
1474 	zassert_equal(0, ret, "Header strings did not match");
1475 	ret = strcmp(hdrs[0].value, "test_value");
1476 	zassert_equal(0, ret, "Header strings did not match");
1477 }
1478 
ZTEST(server_function_tests,test_http1_header_too_many)1479 ZTEST(server_function_tests, test_http1_header_too_many)
1480 {
1481 	static const char request[] = "GET /header_capture HTTP/1.1\r\n"
1482 				      "User-Agent: curl/7.68.0\r\n"
1483 				      "Test-Header: test_value\r\n"
1484 				      "Test-Header2: test_value2\r\n"
1485 				      "Accept: */*\r\n"
1486 				      "Accept-Encoding: deflate, gzip, br\r\n"
1487 				      "\r\n";
1488 	struct http_header *hdrs = request_headers_clone.headers;
1489 	int ret;
1490 
1491 	test_http1_header_capture_common(request);
1492 
1493 	zassert_equal(request_headers_clone.count, 2,
1494 		      "Didn't capture the expected number of headers");
1495 	zassert_equal(request_headers_clone.status, HTTP_HEADER_STATUS_DROPPED,
1496 		      "Header capture status OK, but should not have been");
1497 
1498 	zassert_not_equal(hdrs[0].name, NULL, "First header name is NULL");
1499 	zassert_not_equal(hdrs[0].value, NULL, "First header value is NULL");
1500 	zassert_not_equal(hdrs[1].name, NULL, "Second header name is NULL");
1501 	zassert_not_equal(hdrs[1].value, NULL, "Second header value is NULL");
1502 
1503 	ret = strcmp(hdrs[0].name, "User-Agent");
1504 	zassert_equal(0, ret, "Header strings did not match");
1505 	ret = strcmp(hdrs[0].value, "curl/7.68.0");
1506 	zassert_equal(0, ret, "Header strings did not match");
1507 	ret = strcmp(hdrs[1].name, "Test-Header");
1508 	zassert_equal(0, ret, "Header strings did not match");
1509 	ret = strcmp(hdrs[1].value, "test_value");
1510 	zassert_equal(0, ret, "Header strings did not match");
1511 }
1512 
common_verify_http2_get_header_capture_request(const uint8_t * request,size_t request_len)1513 static void common_verify_http2_get_header_capture_request(const uint8_t *request,
1514 							   size_t request_len)
1515 {
1516 	size_t offset = 0;
1517 	int ret;
1518 
1519 	dynamic_payload_len = strlen(TEST_DYNAMIC_GET_PAYLOAD);
1520 	memcpy(dynamic_payload, TEST_DYNAMIC_GET_PAYLOAD, dynamic_payload_len);
1521 
1522 	ret = zsock_send(client_fd, request, request_len, 0);
1523 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1524 
1525 	memset(buf, 0, sizeof(buf));
1526 
1527 	expect_http2_settings_frame(&offset, false);
1528 	expect_http2_settings_frame(&offset, true);
1529 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1,
1530 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM, NULL, 0);
1531 }
1532 
ZTEST(server_function_tests,test_http2_header_capture)1533 ZTEST(server_function_tests, test_http2_header_capture)
1534 {
1535 	static const uint8_t request[] = {
1536 		TEST_HTTP2_MAGIC,
1537 		TEST_HTTP2_SETTINGS,
1538 		TEST_HTTP2_SETTINGS_ACK,
1539 		TEST_HTTP2_HEADERS_GET_HEADER_CAPTURE1_STREAM_1,
1540 		TEST_HTTP2_GOAWAY,
1541 	};
1542 	struct http_header *hdrs = request_headers_clone.headers;
1543 	int ret;
1544 
1545 	common_verify_http2_get_header_capture_request(request, sizeof(request));
1546 
1547 	zassert_equal(request_headers_clone.count, 2,
1548 		      "Didn't capture the expected number of headers");
1549 	zassert_equal(request_headers_clone.status, HTTP_HEADER_STATUS_OK,
1550 		      "Header capture status was not OK");
1551 
1552 	zassert_not_equal(hdrs[0].name, NULL, "First header name is NULL");
1553 	zassert_not_equal(hdrs[0].value, NULL, "First header value is NULL");
1554 	zassert_not_equal(hdrs[1].name, NULL, "Second header name is NULL");
1555 	zassert_not_equal(hdrs[1].value, NULL, "Second header value is NULL");
1556 
1557 	ret = strcmp(hdrs[0].name, "User-Agent");
1558 	zassert_equal(0, ret, "Header strings did not match");
1559 	ret = strcmp(hdrs[0].value, "curl/7.81.0");
1560 	zassert_equal(0, ret, "Header strings did not match");
1561 	ret = strcmp(hdrs[1].name, "Test-Header");
1562 	zassert_equal(0, ret, "Header strings did not match");
1563 	ret = strcmp(hdrs[1].value, "test_value");
1564 	zassert_equal(0, ret, "Header strings did not match");
1565 }
1566 
ZTEST(server_function_tests,test_http2_header_too_long)1567 ZTEST(server_function_tests, test_http2_header_too_long)
1568 {
1569 	static const uint8_t request[] = {
1570 		TEST_HTTP2_MAGIC,
1571 		TEST_HTTP2_SETTINGS,
1572 		TEST_HTTP2_SETTINGS_ACK,
1573 		TEST_HTTP2_HEADERS_GET_HEADER_CAPTURE2_STREAM_1,
1574 		TEST_HTTP2_GOAWAY,
1575 	};
1576 	struct http_header *hdrs = request_headers_clone.headers;
1577 	int ret;
1578 
1579 	common_verify_http2_get_header_capture_request(request, sizeof(request));
1580 
1581 	zassert_equal(request_headers_clone.count, 1,
1582 		      "Didn't capture the expected number of headers");
1583 	zassert_equal(request_headers_clone.status, HTTP_HEADER_STATUS_DROPPED,
1584 		      "Header capture status was OK, but should not have been");
1585 
1586 	/* First header too long should not stop second header being captured into first slot */
1587 	zassert_not_equal(hdrs[0].name, NULL, "First header name is NULL");
1588 	zassert_not_equal(hdrs[0].value, NULL, "First header value is NULL");
1589 
1590 	ret = strcmp(hdrs[0].name, "Test-Header");
1591 	zassert_equal(0, ret, "Header strings did not match");
1592 	ret = strcmp(hdrs[0].value, "test_value");
1593 	zassert_equal(0, ret, "Header strings did not match");
1594 }
1595 
ZTEST(server_function_tests,test_http2_header_too_many)1596 ZTEST(server_function_tests, test_http2_header_too_many)
1597 {
1598 	static const uint8_t request[] = {
1599 		TEST_HTTP2_MAGIC,
1600 		TEST_HTTP2_SETTINGS,
1601 		TEST_HTTP2_SETTINGS_ACK,
1602 		TEST_HTTP2_HEADERS_GET_HEADER_CAPTURE3_STREAM_1,
1603 		TEST_HTTP2_GOAWAY,
1604 	};
1605 	struct http_header *hdrs = request_headers_clone.headers;
1606 	int ret;
1607 
1608 	common_verify_http2_get_header_capture_request(request, sizeof(request));
1609 
1610 	zassert_equal(request_headers_clone.count, 2,
1611 		      "Didn't capture the expected number of headers");
1612 	zassert_equal(request_headers_clone.status, HTTP_HEADER_STATUS_DROPPED,
1613 		      "Header capture status OK, but should not have been");
1614 
1615 	zassert_not_equal(hdrs[0].name, NULL, "First header name is NULL");
1616 	zassert_not_equal(hdrs[0].value, NULL, "First header value is NULL");
1617 	zassert_not_equal(hdrs[1].name, NULL, "Second header name is NULL");
1618 	zassert_not_equal(hdrs[1].value, NULL, "Second header value is NULL");
1619 
1620 	ret = strcmp(hdrs[0].name, "User-Agent");
1621 	zassert_equal(0, ret, "Header strings did not match");
1622 	ret = strcmp(hdrs[0].value, "curl/7.81.0");
1623 	zassert_equal(0, ret, "Header strings did not match");
1624 	ret = strcmp(hdrs[1].name, "Test-Header");
1625 	zassert_equal(0, ret, "Header strings did not match");
1626 	ret = strcmp(hdrs[1].value, "test_value");
1627 	zassert_equal(0, ret, "Header strings did not match");
1628 }
1629 
ZTEST(server_function_tests,test_http2_header_concurrent)1630 ZTEST(server_function_tests, test_http2_header_concurrent)
1631 {
1632 	/* Two POST requests which are concurrent, ie. headers1, headers2, data1, data2 */
1633 	static const uint8_t request[] = {
1634 		TEST_HTTP2_MAGIC,
1635 		TEST_HTTP2_SETTINGS,
1636 		TEST_HTTP2_SETTINGS_ACK,
1637 		TEST_HTTP2_HEADERS_POST_HEADER_CAPTURE_WITH_TESTHEADER_STREAM_1,
1638 		TEST_HTTP2_HEADERS_POST_HEADER_CAPTURE2_NO_TESTHEADER_STREAM_2,
1639 		TEST_HTTP2_DATA_POST_HEADER_CAPTURE_STREAM_1,
1640 		TEST_HTTP2_DATA_POST_HEADER_CAPTURE_STREAM_2,
1641 		TEST_HTTP2_GOAWAY,
1642 	};
1643 
1644 	struct http_header *hdrs = request_headers_clone.headers;
1645 	struct http_header *hdrs2 = request_headers_clone2.headers;
1646 	int ret;
1647 	size_t offset = 0;
1648 
1649 	ret = zsock_send(client_fd, request, sizeof(request), 0);
1650 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1651 
1652 	/* Wait for response on both resources before checking captured headers */
1653 	expect_http2_settings_frame(&offset, false);
1654 	expect_http2_settings_frame(&offset, true);
1655 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_1,
1656 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM, NULL, 0);
1657 	expect_http2_window_update_frame(&offset, TEST_STREAM_ID_1);
1658 	expect_http2_window_update_frame(&offset, 0);
1659 	expect_http2_headers_frame(&offset, TEST_STREAM_ID_2,
1660 				   HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM, NULL, 0);
1661 
1662 	/* Headers captured on /header_capture path should have two headers including the
1663 	 * Test-Header
1664 	 */
1665 	zassert_equal(request_headers_clone.count, 2,
1666 		      "Didn't capture the expected number of headers");
1667 
1668 	zassert_not_equal(hdrs[0].name, NULL, "First header name is NULL");
1669 	zassert_not_equal(hdrs[0].value, NULL, "First header value is NULL");
1670 	zassert_not_equal(hdrs[1].name, NULL, "Second header name is NULL");
1671 	zassert_not_equal(hdrs[1].value, NULL, "Second header value is NULL");
1672 
1673 	ret = strcmp(hdrs[0].name, "User-Agent");
1674 	zassert_equal(0, ret, "Header strings did not match");
1675 	ret = strcmp(hdrs[0].value, "curl/7.81.0");
1676 	zassert_equal(0, ret, "Header strings did not match");
1677 	ret = strcmp(hdrs[1].name, "Test-Header");
1678 	zassert_equal(0, ret, "Header strings did not match");
1679 	ret = strcmp(hdrs[1].value, "test_value");
1680 	zassert_equal(0, ret, "Header strings did not match");
1681 
1682 	/* Headers captured on the /header_capture2 path should have only one header, not including
1683 	 * the Test-Header
1684 	 */
1685 	zassert_equal(request_headers_clone2.count, 1,
1686 		      "Didn't capture the expected number of headers");
1687 
1688 	zassert_not_equal(hdrs2[0].name, NULL, "First header name is NULL");
1689 	zassert_not_equal(hdrs2[0].value, NULL, "First header value is NULL");
1690 
1691 	ret = strcmp(hdrs2[0].name, "User-Agent");
1692 	zassert_equal(0, ret, "Header strings did not match");
1693 	ret = strcmp(hdrs2[0].value, "curl/7.81.0");
1694 	zassert_equal(0, ret, "Header strings did not match");
1695 }
1696 
test_http1_dynamic_response_headers(const char * request,const char * expected_response)1697 static void test_http1_dynamic_response_headers(const char *request, const char *expected_response)
1698 {
1699 	int ret;
1700 	size_t offset = 0;
1701 
1702 	ret = zsock_send(client_fd, request, strlen(request), 0);
1703 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1704 
1705 	test_read_data(&offset, strlen(expected_response));
1706 	zassert_mem_equal(buf, expected_response, strlen(expected_response));
1707 }
1708 
test_http1_dynamic_response_headers_default(const char * expected_response,bool post)1709 static void test_http1_dynamic_response_headers_default(const char *expected_response, bool post)
1710 {
1711 	static const char http1_get_response_headers_request[] =
1712 		"GET /response_headers HTTP/1.1\r\n"
1713 		"Accept: */*\r\n"
1714 		"\r\n";
1715 	static const char http1_post_response_headers_request[] =
1716 		"POST /response_headers HTTP/1.1\r\n"
1717 		"Accept: */*\r\n"
1718 		"Content-Length: 17\r\n"
1719 		"\r\n" TEST_DYNAMIC_POST_PAYLOAD;
1720 	const char *request =
1721 		post ? http1_post_response_headers_request : http1_get_response_headers_request;
1722 
1723 	test_http1_dynamic_response_headers(request, expected_response);
1724 }
1725 
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)1726 static void test_http2_dynamic_response_headers(const uint8_t *request, size_t request_len,
1727 						const struct http_header *expected_headers,
1728 						size_t expected_headers_count, bool end_stream,
1729 						size_t *offset)
1730 {
1731 	int ret;
1732 	const uint8_t expected_flags = end_stream ? HTTP2_FLAG_END_HEADERS | HTTP2_FLAG_END_STREAM
1733 						  : HTTP2_FLAG_END_HEADERS;
1734 
1735 	ret = zsock_send(client_fd, request, request_len, 0);
1736 	zassert_not_equal(ret, -1, "send() failed (%d)", errno);
1737 
1738 	expect_http2_settings_frame(offset, false);
1739 	expect_http2_settings_frame(offset, true);
1740 	expect_http2_headers_frame(offset, TEST_STREAM_ID_1, expected_flags, expected_headers,
1741 				   expected_headers_count);
1742 }
1743 
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)1744 static void test_http2_dynamic_response_headers_default(const struct http_header *expected_headers,
1745 							size_t expected_headers_count, bool post,
1746 							bool end_stream, size_t *offset)
1747 {
1748 	const uint8_t http2_get_response_headers_request[] = {
1749 		TEST_HTTP2_MAGIC,
1750 		TEST_HTTP2_SETTINGS,
1751 		TEST_HTTP2_SETTINGS_ACK,
1752 		TEST_HTTP2_HEADERS_GET_RESPONSE_HEADERS_STREAM_1,
1753 		TEST_HTTP2_GOAWAY,
1754 	};
1755 	const uint8_t http2_post_response_headers_request[] = {
1756 		TEST_HTTP2_MAGIC,
1757 		TEST_HTTP2_SETTINGS,
1758 		TEST_HTTP2_SETTINGS_ACK,
1759 		TEST_HTTP2_HEADERS_POST_RESPONSE_HEADERS_STREAM_1,
1760 		TEST_HTTP2_DATA_POST_DYNAMIC_STREAM_1,
1761 		TEST_HTTP2_GOAWAY,
1762 	};
1763 	const uint8_t *request =
1764 		post ? http2_post_response_headers_request : http2_get_response_headers_request;
1765 	size_t request_len = post ? sizeof(http2_post_response_headers_request)
1766 				  : sizeof(http2_get_response_headers_request);
1767 
1768 	test_http2_dynamic_response_headers(request, request_len, expected_headers,
1769 					    expected_headers_count, end_stream, offset);
1770 }
1771 
test_http1_dynamic_response_header_none(bool post)1772 static void test_http1_dynamic_response_header_none(bool post)
1773 {
1774 	static const char response[] = "HTTP/1.1 200\r\n"
1775 				       "Transfer-Encoding: chunked\r\n"
1776 				       "Content-Type: text/plain\r\n"
1777 				       "\r\n"
1778 				       "0\r\n\r\n";
1779 
1780 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_NONE;
1781 
1782 	test_http1_dynamic_response_headers_default(response, post);
1783 }
1784 
ZTEST(server_function_tests,test_http1_dynamic_get_response_header_none)1785 ZTEST(server_function_tests, test_http1_dynamic_get_response_header_none)
1786 {
1787 	test_http1_dynamic_response_header_none(false);
1788 }
1789 
ZTEST(server_function_tests,test_http1_dynamic_post_response_header_none)1790 ZTEST(server_function_tests, test_http1_dynamic_post_response_header_none)
1791 {
1792 	test_http1_dynamic_response_header_none(true);
1793 }
1794 
test_http2_dynamic_response_header_none(bool post)1795 static void test_http2_dynamic_response_header_none(bool post)
1796 {
1797 	size_t offset = 0;
1798 	const struct http_header expected_headers[] = {
1799 		{.name = ":status", .value = "200"},
1800 		{.name = "content-type", .value = "text/plain"},
1801 	};
1802 
1803 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_NONE;
1804 
1805 	test_http2_dynamic_response_headers_default(expected_headers, ARRAY_SIZE(expected_headers),
1806 						    post, true, &offset);
1807 }
1808 
ZTEST(server_function_tests,test_http2_dynamic_get_response_header_none)1809 ZTEST(server_function_tests, test_http2_dynamic_get_response_header_none)
1810 {
1811 	test_http2_dynamic_response_header_none(false);
1812 }
1813 
ZTEST(server_function_tests,test_http2_dynamic_post_response_header_none)1814 ZTEST(server_function_tests, test_http2_dynamic_post_response_header_none)
1815 {
1816 	test_http2_dynamic_response_header_none(true);
1817 }
1818 
test_http1_dynamic_response_header_422(bool post)1819 static void test_http1_dynamic_response_header_422(bool post)
1820 {
1821 	static const char response[] = "HTTP/1.1 422\r\n"
1822 				       "Transfer-Encoding: chunked\r\n"
1823 				       "Content-Type: text/plain\r\n"
1824 				       "\r\n"
1825 				       "0\r\n\r\n";
1826 
1827 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_422;
1828 
1829 	test_http1_dynamic_response_headers_default(response, post);
1830 }
1831 
ZTEST(server_function_tests,test_http1_dynamic_get_response_header_422)1832 ZTEST(server_function_tests, test_http1_dynamic_get_response_header_422)
1833 {
1834 	test_http1_dynamic_response_header_422(false);
1835 }
1836 
ZTEST(server_function_tests,test_http1_dynamic_post_response_header_422)1837 ZTEST(server_function_tests, test_http1_dynamic_post_response_header_422)
1838 {
1839 	test_http1_dynamic_response_header_422(true);
1840 }
1841 
test_http2_dynamic_response_header_422(bool post)1842 static void test_http2_dynamic_response_header_422(bool post)
1843 {
1844 	size_t offset = 0;
1845 	const struct http_header expected_headers[] = {
1846 		{.name = ":status", .value = "422"},
1847 		{.name = "content-type", .value = "text/plain"},
1848 	};
1849 
1850 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_422;
1851 
1852 	test_http2_dynamic_response_headers_default(expected_headers, ARRAY_SIZE(expected_headers),
1853 						    post, true, &offset);
1854 }
1855 
ZTEST(server_function_tests,test_http2_dynamic_get_response_header_422)1856 ZTEST(server_function_tests, test_http2_dynamic_get_response_header_422)
1857 {
1858 	test_http2_dynamic_response_header_422(false);
1859 }
1860 
ZTEST(server_function_tests,test_http2_dynamic_post_response_header_422)1861 ZTEST(server_function_tests, test_http2_dynamic_post_response_header_422)
1862 {
1863 	test_http2_dynamic_response_header_422(true);
1864 }
1865 
test_http1_dynamic_response_header_extra(bool post)1866 static void test_http1_dynamic_response_header_extra(bool post)
1867 {
1868 	static const char response[] = "HTTP/1.1 200\r\n"
1869 				       "Transfer-Encoding: chunked\r\n"
1870 				       "Test-Header: test_data\r\n"
1871 				       "Content-Type: text/plain\r\n"
1872 				       "\r\n"
1873 				       "0\r\n\r\n";
1874 
1875 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_EXTRA_HEADER;
1876 
1877 	test_http1_dynamic_response_headers_default(response, post);
1878 }
1879 
ZTEST(server_function_tests,test_http1_dynamic_get_response_header_extra)1880 ZTEST(server_function_tests, test_http1_dynamic_get_response_header_extra)
1881 {
1882 	test_http1_dynamic_response_header_extra(false);
1883 }
1884 
ZTEST(server_function_tests,test_http1_dynamic_post_response_header_extra)1885 ZTEST(server_function_tests, test_http1_dynamic_post_response_header_extra)
1886 {
1887 	test_http1_dynamic_response_header_extra(true);
1888 }
1889 
test_http2_dynamic_response_header_extra(bool post)1890 static void test_http2_dynamic_response_header_extra(bool post)
1891 {
1892 	size_t offset = 0;
1893 	const struct http_header expected_headers[] = {
1894 		{.name = ":status", .value = "200"},
1895 		{.name = "content-type", .value = "text/plain"},
1896 		{.name = "test-header", .value = "test_data"},
1897 	};
1898 
1899 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_EXTRA_HEADER;
1900 
1901 	test_http2_dynamic_response_headers_default(expected_headers, ARRAY_SIZE(expected_headers),
1902 						    post, true, &offset);
1903 }
1904 
ZTEST(server_function_tests,test_http2_dynamic_get_response_header_extra)1905 ZTEST(server_function_tests, test_http2_dynamic_get_response_header_extra)
1906 {
1907 	test_http2_dynamic_response_header_extra(false);
1908 }
1909 
ZTEST(server_function_tests,test_http2_dynamic_post_response_header_extra)1910 ZTEST(server_function_tests, test_http2_dynamic_post_response_header_extra)
1911 {
1912 	test_http2_dynamic_response_header_extra(true);
1913 }
1914 
test_http1_dynamic_response_header_override(bool post)1915 static void test_http1_dynamic_response_header_override(bool post)
1916 {
1917 	static const char response[] = "HTTP/1.1 200\r\n"
1918 				       "Transfer-Encoding: chunked\r\n"
1919 				       "Content-Type: application/json\r\n"
1920 				       "\r\n"
1921 				       "0\r\n\r\n";
1922 
1923 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_OVERRIDE_HEADER;
1924 
1925 	test_http1_dynamic_response_headers_default(response, post);
1926 }
1927 
ZTEST(server_function_tests,test_http1_dynamic_get_response_header_override)1928 ZTEST(server_function_tests, test_http1_dynamic_get_response_header_override)
1929 {
1930 	test_http1_dynamic_response_header_override(false);
1931 }
1932 
ZTEST(server_function_tests,test_http1_dynamic_post_response_header_override)1933 ZTEST(server_function_tests, test_http1_dynamic_post_response_header_override)
1934 {
1935 	test_http1_dynamic_response_header_override(true);
1936 }
1937 
test_http2_dynamic_response_header_override(bool post)1938 static void test_http2_dynamic_response_header_override(bool post)
1939 {
1940 	size_t offset = 0;
1941 	const struct http_header expected_headers[] = {
1942 		{.name = ":status", .value = "200"},
1943 		{.name = "content-type", .value = "application/json"},
1944 	};
1945 
1946 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_OVERRIDE_HEADER;
1947 
1948 	test_http2_dynamic_response_headers_default(expected_headers, ARRAY_SIZE(expected_headers),
1949 						    post, true, &offset);
1950 }
1951 
ZTEST(server_function_tests,test_http2_dynamic_get_response_header_override)1952 ZTEST(server_function_tests, test_http2_dynamic_get_response_header_override)
1953 {
1954 	test_http2_dynamic_response_header_override(false);
1955 }
1956 
ZTEST(server_function_tests,test_http2_dynamic_post_response_header_override)1957 ZTEST(server_function_tests, test_http2_dynamic_post_response_header_override)
1958 {
1959 	test_http2_dynamic_response_header_override(true);
1960 }
1961 
test_http1_dynamic_response_header_separate(bool post)1962 static void test_http1_dynamic_response_header_separate(bool post)
1963 {
1964 	static const char response[] = "HTTP/1.1 200\r\n"
1965 				       "Transfer-Encoding: chunked\r\n"
1966 				       "Test-Header: test_data\r\n"
1967 				       "Content-Type: text/plain\r\n"
1968 				       "\r\n"
1969 				       "10\r\n" TEST_DYNAMIC_GET_PAYLOAD "\r\n"
1970 				       "0\r\n\r\n";
1971 
1972 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_SEPARATE;
1973 
1974 	test_http1_dynamic_response_headers_default(response, post);
1975 }
1976 
ZTEST(server_function_tests,test_http1_dynamic_get_response_header_separate)1977 ZTEST(server_function_tests, test_http1_dynamic_get_response_header_separate)
1978 {
1979 	test_http1_dynamic_response_header_separate(false);
1980 }
1981 
ZTEST(server_function_tests,test_http1_dynamic_post_response_header_separate)1982 ZTEST(server_function_tests, test_http1_dynamic_post_response_header_separate)
1983 {
1984 	test_http1_dynamic_response_header_separate(true);
1985 }
1986 
test_http2_dynamic_response_header_separate(bool post)1987 static void test_http2_dynamic_response_header_separate(bool post)
1988 {
1989 	size_t offset = 0;
1990 	const struct http_header expected_headers[] = {
1991 		{.name = ":status", .value = "200"},
1992 		{.name = "test-header", .value = "test_data"},
1993 		{.name = "content-type", .value = "text/plain"},
1994 	};
1995 
1996 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_SEPARATE;
1997 
1998 	test_http2_dynamic_response_headers_default(expected_headers, ARRAY_SIZE(expected_headers),
1999 						    post, false, &offset);
2000 }
2001 
ZTEST(server_function_tests,test_http2_dynamic_get_response_header_separate)2002 ZTEST(server_function_tests, test_http2_dynamic_get_response_header_separate)
2003 {
2004 	test_http2_dynamic_response_header_separate(false);
2005 }
2006 
ZTEST(server_function_tests,test_http2_dynamic_post_response_header_separate)2007 ZTEST(server_function_tests, test_http2_dynamic_post_response_header_separate)
2008 {
2009 	test_http2_dynamic_response_header_separate(true);
2010 }
2011 
test_http1_dynamic_response_header_combined(bool post)2012 static void test_http1_dynamic_response_header_combined(bool post)
2013 {
2014 	static const char response[] = "HTTP/1.1 200\r\n"
2015 				       "Transfer-Encoding: chunked\r\n"
2016 				       "Test-Header: test_data\r\n"
2017 				       "Content-Type: text/plain\r\n"
2018 				       "\r\n"
2019 				       "10\r\n" TEST_DYNAMIC_GET_PAYLOAD "\r\n"
2020 				       "0\r\n\r\n";
2021 
2022 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_COMBINED;
2023 
2024 	test_http1_dynamic_response_headers_default(response, post);
2025 }
2026 
ZTEST(server_function_tests,test_http1_dynamic_get_response_header_combined)2027 ZTEST(server_function_tests, test_http1_dynamic_get_response_header_combined)
2028 {
2029 	test_http1_dynamic_response_header_combined(false);
2030 }
2031 
ZTEST(server_function_tests,test_http1_dynamic_post_response_header_combined)2032 ZTEST(server_function_tests, test_http1_dynamic_post_response_header_combined)
2033 {
2034 	test_http1_dynamic_response_header_combined(true);
2035 }
2036 
test_http2_dynamic_response_header_combined(bool post)2037 static void test_http2_dynamic_response_header_combined(bool post)
2038 {
2039 	size_t offset = 0;
2040 	const struct http_header expected_headers[] = {
2041 		{.name = ":status", .value = "200"},
2042 		{.name = "test-header", .value = "test_data"},
2043 		{.name = "content-type", .value = "text/plain"},
2044 	};
2045 
2046 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_COMBINED;
2047 
2048 	test_http2_dynamic_response_headers_default(expected_headers, ARRAY_SIZE(expected_headers),
2049 						    post, false, &offset);
2050 }
2051 
ZTEST(server_function_tests,test_http2_dynamic_get_response_header_combined)2052 ZTEST(server_function_tests, test_http2_dynamic_get_response_header_combined)
2053 {
2054 	test_http2_dynamic_response_header_combined(false);
2055 }
2056 
ZTEST(server_function_tests,test_http2_dynamic_post_response_header_combined)2057 ZTEST(server_function_tests, test_http2_dynamic_post_response_header_combined)
2058 {
2059 	test_http2_dynamic_response_header_combined(true);
2060 }
2061 
ZTEST(server_function_tests,test_http1_dynamic_get_response_header_long)2062 ZTEST(server_function_tests, test_http1_dynamic_get_response_header_long)
2063 {
2064 	static const char response[] = "HTTP/1.1 200\r\n"
2065 				       "Transfer-Encoding: chunked\r\n"
2066 				       "Content-Type: text/plain\r\n"
2067 				       "\r\n"
2068 				       "130\r\n" TEST_LONG_PAYLOAD_CHUNK_1 "\r\n"
2069 				       "d0\r\n" TEST_LONG_PAYLOAD_CHUNK_2 "\r\n"
2070 				       "0\r\n\r\n";
2071 
2072 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_LONG;
2073 
2074 	test_http1_dynamic_response_headers_default(response, false);
2075 }
2076 
ZTEST(server_function_tests,test_http1_dynamic_post_response_header_long)2077 ZTEST(server_function_tests, test_http1_dynamic_post_response_header_long)
2078 {
2079 	static const char request[] = "POST /response_headers HTTP/1.1\r\n"
2080 				      "Accept: */*\r\n"
2081 				      "Content-Length: 512\r\n"
2082 				      "\r\n" TEST_LONG_PAYLOAD_CHUNK_1 TEST_LONG_PAYLOAD_CHUNK_2;
2083 	static const char response[] = "HTTP/1.1 200\r\n"
2084 				       "Transfer-Encoding: chunked\r\n"
2085 				       "Content-Type: text/plain\r\n"
2086 				       "\r\n"
2087 				       "0\r\n\r\n";
2088 
2089 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_LONG;
2090 
2091 	test_http1_dynamic_response_headers(request, response);
2092 	zassert_mem_equal(dynamic_response_headers_buffer, long_payload, strlen(long_payload));
2093 }
2094 
ZTEST(server_function_tests,test_http2_dynamic_get_response_header_long)2095 ZTEST(server_function_tests, test_http2_dynamic_get_response_header_long)
2096 {
2097 	size_t offset = 0;
2098 	const struct http_header expected_headers[] = {
2099 		{.name = ":status", .value = "200"},
2100 		{.name = "content-type", .value = "text/plain"},
2101 	};
2102 
2103 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_LONG;
2104 
2105 	test_http2_dynamic_response_headers_default(expected_headers, ARRAY_SIZE(expected_headers),
2106 						    false, false, &offset);
2107 	expect_http2_data_frame(&offset, TEST_STREAM_ID_1, TEST_LONG_PAYLOAD_CHUNK_1,
2108 				strlen(TEST_LONG_PAYLOAD_CHUNK_1), 0);
2109 	expect_http2_data_frame(&offset, TEST_STREAM_ID_1, TEST_LONG_PAYLOAD_CHUNK_2,
2110 				strlen(TEST_LONG_PAYLOAD_CHUNK_2), HTTP2_FLAG_END_STREAM);
2111 }
2112 
ZTEST(server_function_tests,test_http2_dynamic_post_response_header_long)2113 ZTEST(server_function_tests, test_http2_dynamic_post_response_header_long)
2114 {
2115 	size_t offset = 0;
2116 	size_t req_offset = 0;
2117 
2118 	const struct http_header expected_headers[] = {
2119 		{.name = ":status", .value = "200"},
2120 		{.name = "content-type", .value = "text/plain"},
2121 	};
2122 
2123 	const uint8_t request_part1[] = {
2124 		TEST_HTTP2_MAGIC,
2125 		TEST_HTTP2_SETTINGS,
2126 		TEST_HTTP2_SETTINGS_ACK,
2127 		TEST_HTTP2_HEADERS_POST_RESPONSE_HEADERS_STREAM_1,
2128 		/* Data frame header */
2129 		0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, TEST_STREAM_ID_1,
2130 	};
2131 
2132 	const uint8_t request_part3[] = {
2133 		TEST_HTTP2_GOAWAY,
2134 	};
2135 
2136 	static uint8_t
2137 		request[sizeof(request_part1) + (sizeof(long_payload) - 1) + sizeof(request_part3)];
2138 
2139 	BUILD_ASSERT(sizeof(long_payload) - 1 == 0x200, "Length field in data frame header must "
2140 							"match length of long_payload");
2141 
2142 	memcpy(request + req_offset, request_part1, sizeof(request_part1));
2143 	req_offset += sizeof(request_part1);
2144 	memcpy(request + req_offset, long_payload, sizeof(long_payload) - 1);
2145 	req_offset += sizeof(long_payload) - 1;
2146 	memcpy(request + req_offset, request_part3, sizeof(request_part3));
2147 	req_offset += sizeof(request_part3);
2148 
2149 	dynamic_response_headers_variant = DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_LONG;
2150 
2151 	test_http2_dynamic_response_headers(request, req_offset, expected_headers,
2152 					    ARRAY_SIZE(expected_headers), true, &offset);
2153 	zassert_mem_equal(dynamic_response_headers_buffer, long_payload, strlen(long_payload));
2154 }
2155 
ZTEST(server_function_tests_no_init,test_http_server_start_stop)2156 ZTEST(server_function_tests_no_init, test_http_server_start_stop)
2157 {
2158 	struct sockaddr_in sa = { 0 };
2159 	int ret;
2160 
2161 	sa.sin_family = AF_INET;
2162 	sa.sin_port = htons(SERVER_PORT);
2163 
2164 	ret = zsock_inet_pton(AF_INET, SERVER_IPV4_ADDR, &sa.sin_addr.s_addr);
2165 	zassert_equal(1, ret, "inet_pton() failed to convert %s", SERVER_IPV4_ADDR);
2166 
2167 	zassert_ok(http_server_start(), "Failed to start the server");
2168 	zassert_not_ok(http_server_start(), "Server start should report na error.");
2169 
2170 	zassert_ok(http_server_stop(), "Failed to stop the server");
2171 	zassert_not_ok(http_server_stop(), "Server stop should report na error.");
2172 
2173 	zassert_ok(http_server_start(), "Failed to start the server");
2174 
2175 	/* Server should be listening now. */
2176 	ret = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
2177 	zassert_not_equal(ret, -1, "failed to create client socket (%d)", errno);
2178 	client_fd = ret;
2179 
2180 	zassert_ok(zsock_connect(client_fd, (struct sockaddr *)&sa, sizeof(sa)),
2181 		   "failed to connect to the server (%d)", errno);
2182 	zassert_ok(zsock_close(client_fd), "close() failed on the client fd (%d)", errno);
2183 	client_fd = -1;
2184 
2185 	/* Check if the server can be restarted again after client connected. */
2186 	zassert_ok(http_server_stop(), "Failed to stop the server");
2187 	zassert_ok(http_server_start(), "Failed to start the server");
2188 
2189 	/* Let the server thread run. */
2190 	k_msleep(CONFIG_HTTP_SERVER_RESTART_DELAY + 10);
2191 
2192 	ret = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
2193 	zassert_not_equal(ret, -1, "failed to create client socket (%d)", errno);
2194 	client_fd = ret;
2195 
2196 	zassert_ok(zsock_connect(client_fd, (struct sockaddr *)&sa, sizeof(sa)),
2197 		   "failed to connect to the server (%d)", errno);
2198 	zassert_ok(zsock_close(client_fd), "close() failed on the client fd (%d)", errno);
2199 	client_fd = -1;
2200 
2201 	zassert_ok(http_server_stop(), "Failed to stop the server");
2202 }
2203 
ZTEST(server_function_tests_no_init,test_get_frame_type_name)2204 ZTEST(server_function_tests_no_init, test_get_frame_type_name)
2205 {
2206 	zassert_str_equal(get_frame_type_name(HTTP2_DATA_FRAME), "DATA",
2207 			  "Unexpected frame type");
2208 	zassert_str_equal(get_frame_type_name(HTTP2_HEADERS_FRAME),
2209 			  "HEADERS", "Unexpected frame type");
2210 	zassert_str_equal(get_frame_type_name(HTTP2_PRIORITY_FRAME),
2211 			  "PRIORITY", "Unexpected frame type");
2212 	zassert_str_equal(get_frame_type_name(HTTP2_RST_STREAM_FRAME),
2213 			  "RST_STREAM", "Unexpected frame type");
2214 	zassert_str_equal(get_frame_type_name(HTTP2_SETTINGS_FRAME),
2215 			  "SETTINGS", "Unexpected frame type");
2216 	zassert_str_equal(get_frame_type_name(HTTP2_PUSH_PROMISE_FRAME),
2217 			  "PUSH_PROMISE", "Unexpected frame type");
2218 	zassert_str_equal(get_frame_type_name(HTTP2_PING_FRAME), "PING",
2219 			  "Unexpected frame type");
2220 	zassert_str_equal(get_frame_type_name(HTTP2_GOAWAY_FRAME),
2221 			  "GOAWAY", "Unexpected frame type");
2222 	zassert_str_equal(get_frame_type_name(HTTP2_WINDOW_UPDATE_FRAME),
2223 			  "WINDOW_UPDATE", "Unexpected frame type");
2224 	zassert_str_equal(get_frame_type_name(HTTP2_CONTINUATION_FRAME),
2225 			  "CONTINUATION", "Unexpected frame type");
2226 }
2227 
ZTEST(server_function_tests_no_init,test_parse_http_frames)2228 ZTEST(server_function_tests_no_init, test_parse_http_frames)
2229 {
2230 	static struct http_client_ctx ctx_client1;
2231 	static struct http_client_ctx ctx_client2;
2232 	struct http2_frame *frame;
2233 
2234 	unsigned char buffer1[] = {
2235 		0x00, 0x00, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x00,
2236 		0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x64, 0x00,
2237 		0x04, 0x00, 0x00, 0xff, 0xff, 0x00
2238 	};
2239 	unsigned char buffer2[] = {
2240 		0x00, 0x00, 0x21, 0x01, 0x05, 0x00, 0x00, 0x00,
2241 		0x01, 0x82, 0x84, 0x86, 0x41, 0x8a, 0x0b, 0xe2,
2242 		0x5c, 0x0b, 0x89, 0x70, 0xdc, 0x78, 0x0f, 0x03,
2243 		0x53, 0x03, 0x2a, 0x2f, 0x2a, 0x90, 0x7a, 0x8a,
2244 		0xaa, 0x69, 0xd2, 0x9a, 0xc4, 0xc0, 0x57, 0x68,
2245 		0x0b, 0x83
2246 	};
2247 
2248 	memcpy(ctx_client1.buffer, buffer1, sizeof(buffer1));
2249 	memcpy(ctx_client2.buffer, buffer2, sizeof(buffer2));
2250 
2251 	ctx_client1.cursor = ctx_client1.buffer;
2252 	ctx_client1.data_len = ARRAY_SIZE(buffer1);
2253 
2254 	ctx_client2.cursor = ctx_client2.buffer;
2255 	ctx_client2.data_len = ARRAY_SIZE(buffer2);
2256 
2257 	/* Test: Buffer with the first frame */
2258 	int parser1 = parse_http_frame_header(&ctx_client1, ctx_client1.cursor,
2259 					      ctx_client1.data_len);
2260 
2261 	zassert_equal(parser1, 0, "Failed to parse the first frame");
2262 
2263 	frame = &ctx_client1.current_frame;
2264 
2265 	/* Validate frame details for the 1st frame */
2266 	zassert_equal(frame->length, 0x0C, "Expected length for the 1st frame doesn't match");
2267 	zassert_equal(frame->type, 0x04, "Expected type for the 1st frame doesn't match");
2268 	zassert_equal(frame->flags, 0x00, "Expected flags for the 1st frame doesn't match");
2269 	zassert_equal(frame->stream_identifier, 0x00,
2270 		      "Expected stream_identifier for the 1st frame doesn't match");
2271 
2272 	/* Test: Buffer with the second frame */
2273 	int parser2 = parse_http_frame_header(&ctx_client2, ctx_client2.cursor,
2274 					      ctx_client2.data_len);
2275 
2276 	zassert_equal(parser2, 0, "Failed to parse the second frame");
2277 
2278 	frame = &ctx_client2.current_frame;
2279 
2280 	/* Validate frame details for the 2nd frame */
2281 	zassert_equal(frame->length, 0x21, "Expected length for the 2nd frame doesn't match");
2282 	zassert_equal(frame->type, 0x01, "Expected type for the 2nd frame doesn't match");
2283 	zassert_equal(frame->flags, 0x05, "Expected flags for the 2nd frame doesn't match");
2284 	zassert_equal(frame->stream_identifier, 0x01,
2285 		      "Expected stream_identifier for the 2nd frame doesn't match");
2286 }
2287 
http_server_tests_before(void * fixture)2288 static void http_server_tests_before(void *fixture)
2289 {
2290 	struct sockaddr_in sa;
2291 	struct timeval optval = {
2292 		.tv_sec = TIMEOUT_S,
2293 		.tv_usec = 0,
2294 	};
2295 	int ret;
2296 
2297 	ARG_UNUSED(fixture);
2298 
2299 	memset(dynamic_payload, 0, sizeof(dynamic_payload));
2300 	memset(dynamic_response_headers_buffer, 0, sizeof(dynamic_response_headers_buffer));
2301 	memset(&request_headers_clone, 0, sizeof(request_headers_clone));
2302 	memset(&request_headers_clone2, 0, sizeof(request_headers_clone2));
2303 	dynamic_payload_len = 0;
2304 
2305 	ret = http_server_start();
2306 	if (ret < 0) {
2307 		printk("Failed to start the server\n");
2308 		return;
2309 	}
2310 
2311 	ret = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
2312 	if (ret < 0) {
2313 		printk("Failed to create client socket (%d)\n", errno);
2314 		return;
2315 	}
2316 	client_fd = ret;
2317 
2318 	ret = zsock_setsockopt(client_fd, SOL_SOCKET, SO_RCVTIMEO, &optval,
2319 			       sizeof(optval));
2320 	if (ret < 0) {
2321 		printk("Failed to set timeout (%d)\n", errno);
2322 		return;
2323 	}
2324 
2325 	sa.sin_family = AF_INET;
2326 	sa.sin_port = htons(SERVER_PORT);
2327 
2328 	ret = zsock_inet_pton(AF_INET, SERVER_IPV4_ADDR, &sa.sin_addr.s_addr);
2329 	if (ret != 1) {
2330 		printk("inet_pton() failed to convert %s\n", SERVER_IPV4_ADDR);
2331 		return;
2332 	}
2333 
2334 	ret = zsock_connect(client_fd, (struct sockaddr *)&sa, sizeof(sa));
2335 	if (ret < 0) {
2336 		printk("Failed to connect (%d)\n", errno);
2337 	}
2338 }
2339 
http_server_tests_after(void * fixture)2340 static void http_server_tests_after(void *fixture)
2341 {
2342 	ARG_UNUSED(fixture);
2343 
2344 	if (client_fd >= 0) {
2345 		(void)zsock_close(client_fd);
2346 		client_fd = -1;
2347 	}
2348 
2349 	(void)http_server_stop();
2350 }
2351 
2352 ZTEST_SUITE(server_function_tests, NULL, NULL, http_server_tests_before,
2353 	    http_server_tests_after, NULL);
2354 ZTEST_SUITE(server_function_tests_no_init, NULL, NULL, NULL,
2355 	    http_server_tests_after, NULL);
2356