@@ -252,6 +252,7 @@ HTTP_RESOURCE_DEFINE(static_resource, test_http_service, "/",
252252
253253static uint8_t dynamic_payload [32 ];
254254static size_t dynamic_payload_len = sizeof (dynamic_payload );
255+ static bool dynamic_error ;
255256
256257static int dynamic_cb (struct http_client_ctx * client , enum http_data_status status ,
257258 const struct http_request_ctx * request_ctx ,
@@ -264,6 +265,10 @@ static int dynamic_cb(struct http_client_ctx *client, enum http_data_status stat
264265 return 0 ;
265266 }
266267
268+ if (dynamic_error ) {
269+ return - ENOMEM ;
270+ }
271+
267272 switch (client -> method ) {
268273 case HTTP_GET :
269274 response_ctx -> body = dynamic_payload ;
@@ -667,6 +672,7 @@ static void expect_http2_headers_frame(size_t *offset, int stream_id, uint8_t fl
667672 test_consume_data (offset , frame .length );
668673}
669674
675+ /* "payload" may be NULL to skip data frame content validation. */
670676static void expect_http2_data_frame (size_t * offset , int stream_id ,
671677 const uint8_t * payload , size_t payload_len ,
672678 uint8_t flags )
@@ -679,11 +685,17 @@ static void expect_http2_data_frame(size_t *offset, int stream_id,
679685 zassert_equal (frame .stream_identifier , stream_id ,
680686 "Invalid data frame stream ID" );
681687 zassert_equal (frame .flags , flags , "Unexpected flags received" );
682- zassert_equal (frame .length , payload_len , "Unexpected data frame length" );
688+ if (payload != NULL ) {
689+ zassert_equal (frame .length , payload_len ,
690+ "Unexpected data frame length" );
691+ }
683692
684693 /* Verify data payload */
685694 test_read_data (offset , frame .length );
686- zassert_mem_equal (buf , payload , payload_len , "Unexpected data payload" );
695+ if (payload != NULL ) {
696+ zassert_mem_equal (buf , payload , payload_len ,
697+ "Unexpected data payload" );
698+ }
687699 test_consume_data (offset , frame .length );
688700}
689701
@@ -2244,6 +2256,107 @@ ZTEST(server_function_tests, test_http2_409_method_not_allowed)
22442256 expected_headers , 1 );
22452257}
22462258
2259+ ZTEST (server_function_tests , test_http1_500_internal_server_error )
2260+ {
2261+ static const char http1_request [] =
2262+ "GET /dynamic HTTP/1.1\r\n"
2263+ "Host: 127.0.0.1:8080\r\n"
2264+ "User-Agent: curl/7.68.0\r\n"
2265+ "Accept: */*\r\n"
2266+ "Accept-Encoding: deflate, gzip, br\r\n"
2267+ "\r\n" ;
2268+ static const char expected_response [] =
2269+ "HTTP/1.1 500 Internal Server Error\r\n" ;
2270+ size_t offset = 0 ;
2271+ int ret ;
2272+
2273+ dynamic_error = true;
2274+
2275+ ret = zsock_send (client_fd , http1_request , strlen (http1_request ), 0 );
2276+ zassert_not_equal (ret , -1 , "send() failed (%d)" , errno );
2277+
2278+ memset (buf , 0 , sizeof (buf ));
2279+
2280+ test_read_data (& offset , sizeof (expected_response ) - 1 );
2281+ zassert_mem_equal (buf , expected_response , sizeof (expected_response ) - 1 ,
2282+ "Received data doesn't match expected response" );
2283+ }
2284+
2285+ ZTEST (server_function_tests , test_http1_upgrade_500_internal_server_error )
2286+ {
2287+ static const char http1_request [] =
2288+ "GET /dynamic HTTP/1.1\r\n"
2289+ "Host: 127.0.0.1:8080\r\n"
2290+ "User-Agent: curl/7.68.0\r\n"
2291+ "Accept: */*\r\n"
2292+ "Accept-Encoding: deflate, gzip, br\r\n"
2293+ "Connection: Upgrade, HTTP2-Settings\r\n"
2294+ "Upgrade: h2c\r\n"
2295+ "HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA\r\n"
2296+ "\r\n" ;
2297+ const struct http_header expected_headers [] = {
2298+ {.name = ":status" , .value = "500" }
2299+ };
2300+ size_t offset = 0 ;
2301+ int ret ;
2302+
2303+ dynamic_error = true;
2304+
2305+ ret = zsock_send (client_fd , http1_request , strlen (http1_request ), 0 );
2306+ zassert_not_equal (ret , -1 , "send() failed (%d)" , errno );
2307+
2308+ memset (buf , 0 , sizeof (buf ));
2309+
2310+ /* Verify HTTP1 switching protocols response. */
2311+ expect_http1_switching_protocols (& offset );
2312+
2313+ /* Verify HTTP2 frames. */
2314+ expect_http2_settings_frame (& offset , false);
2315+ expect_http2_headers_frame (& offset , UPGRADE_STREAM_ID ,
2316+ HTTP2_FLAG_END_HEADERS ,
2317+ expected_headers , 1 );
2318+ /* Expect data frame with reason but don't check the content as it may
2319+ * depend on libc being used (i. e. string returned by strerror()).
2320+ */
2321+ expect_http2_data_frame (& offset , UPGRADE_STREAM_ID , NULL , 0 ,
2322+ HTTP2_FLAG_END_STREAM );
2323+ }
2324+
2325+ ZTEST (server_function_tests , test_http2_500_internal_server_error )
2326+ {
2327+ static const uint8_t request_get_dynamic [] = {
2328+ TEST_HTTP2_MAGIC ,
2329+ TEST_HTTP2_SETTINGS ,
2330+ TEST_HTTP2_SETTINGS_ACK ,
2331+ TEST_HTTP2_HEADERS_GET_DYNAMIC_STREAM_1 ,
2332+ TEST_HTTP2_GOAWAY ,
2333+ };
2334+ const struct http_header expected_headers [] = {
2335+ {.name = ":status" , .value = "500" }
2336+ };
2337+ size_t offset = 0 ;
2338+ int ret ;
2339+
2340+ dynamic_error = true;
2341+
2342+ ret = zsock_send (client_fd , request_get_dynamic ,
2343+ sizeof (request_get_dynamic ), 0 );
2344+ zassert_not_equal (ret , -1 , "send() failed (%d)" , errno );
2345+
2346+ memset (buf , 0 , sizeof (buf ));
2347+
2348+ expect_http2_settings_frame (& offset , false);
2349+ expect_http2_settings_frame (& offset , true);
2350+ expect_http2_headers_frame (& offset , TEST_STREAM_ID_1 ,
2351+ HTTP2_FLAG_END_HEADERS ,
2352+ expected_headers , 1 );
2353+ /* Expect data frame with reason but don't check the content as it may
2354+ * depend on libc being used (i. e. string returned by strerror()).
2355+ */
2356+ expect_http2_data_frame (& offset , TEST_STREAM_ID_1 , NULL , 0 ,
2357+ HTTP2_FLAG_END_STREAM );
2358+ }
2359+
22472360ZTEST (server_function_tests_no_init , test_http_server_start_stop )
22482361{
22492362 struct sockaddr_in sa = { 0 };
@@ -2590,6 +2703,7 @@ static void http_server_tests_before(void *fixture)
25902703 memset (& request_headers_clone , 0 , sizeof (request_headers_clone ));
25912704 memset (& request_headers_clone2 , 0 , sizeof (request_headers_clone2 ));
25922705 dynamic_payload_len = 0 ;
2706+ dynamic_error = false;
25932707
25942708 ret = http_server_start ();
25952709 if (ret < 0 ) {
0 commit comments