@@ -369,6 +369,46 @@ static int send_http2_409(struct http_client_ctx *client,
369369 return ret ;
370370}
371371
372+ static void send_http2_500 (struct http_client_ctx * client ,
373+ struct http2_frame * frame , int error_code )
374+ {
375+ #define HTTP_500_RESPONSE_TEMPLATE "Internal Server Error%s%s"
376+ #define MAX_ERROR_DESC_LEN 32
377+
378+ char error_str [] = "xxx" ;
379+ char http_response [sizeof (HTTP_500_RESPONSE_TEMPLATE ) +
380+ MAX_ERROR_DESC_LEN + 1 ]; /* For the error description */
381+ const char * error_desc ;
382+ const char * desc_separator ;
383+
384+ if (IS_ENABLED (CONFIG_HTTP_SERVER_REPORT_FAILURE_REASON )) {
385+ /* Try to fetch error description, fallback to error number if
386+ * not available
387+ */
388+ error_desc = strerror (error_code );
389+ if (strlen (error_desc ) == 0 ) {
390+ /* Cast error value to uint8_t to avoid truncation warnings. */
391+ (void )snprintk (error_str , sizeof (error_str ), "%u" ,
392+ (uint8_t )error_code );
393+ error_desc = error_str ;
394+ }
395+ desc_separator = ": " ;
396+ } else {
397+ error_desc = "" ;
398+ desc_separator = "" ;
399+ }
400+
401+ if (send_headers_frame (client , HTTP_500_INTERNAL_SERVER_ERROR ,
402+ frame -> stream_identifier , NULL , 0 , NULL , 0 ) < 0 ) {
403+ return ;
404+ }
405+
406+ (void )snprintk (http_response , sizeof (http_response ),
407+ HTTP_500_RESPONSE_TEMPLATE , desc_separator , error_desc );
408+ (void )send_data_frame (client , http_response , strlen (http_response ),
409+ frame -> stream_identifier , HTTP2_FLAG_END_STREAM );
410+ }
411+
372412static int handle_http2_static_resource (
373413 struct http_resource_detail_static * static_detail ,
374414 struct http2_frame * frame , struct http_client_ctx * client )
@@ -1027,7 +1067,7 @@ int handle_http1_to_http2_upgrade(struct http_client_ctx *client)
10271067 ret = http_server_sendall (client , switching_protocols ,
10281068 sizeof (switching_protocols ) - 1 );
10291069 if (ret < 0 ) {
1030- goto error ;
1070+ return ret ;
10311071 }
10321072
10331073 client -> http1_headers_sent = true;
@@ -1101,6 +1141,11 @@ int handle_http1_to_http2_upgrade(struct http_client_ctx *client)
11011141 return 0 ;
11021142
11031143error :
1144+ if (ret != - EAGAIN && client -> current_stream &&
1145+ !client -> current_stream -> headers_sent ) {
1146+ send_http2_500 (client , frame , - ret );
1147+ }
1148+
11041149 return ret ;
11051150}
11061151
@@ -1169,13 +1214,14 @@ int handle_http_frame_data(struct http_client_ctx *client)
11691214 /* There is no handler */
11701215 LOG_DBG ("No dynamic handler found." );
11711216 (void )send_http2_404 (client , frame );
1172- return - ENOENT ;
1217+ ret = - ENOENT ;
1218+ goto error ;
11731219 }
11741220
11751221 if (is_header_flag_set (frame -> flags , HTTP2_FLAG_PADDED )) {
11761222 ret = parse_http_frame_padded_field (client );
11771223 if (ret < 0 ) {
1178- return ret ;
1224+ goto error ;
11791225 }
11801226 }
11811227
@@ -1187,7 +1233,7 @@ int handle_http_frame_data(struct http_client_ctx *client)
11871233 }
11881234
11891235 if (ret < 0 ) {
1190- return ret ;
1236+ goto error ;
11911237 }
11921238
11931239 if (frame -> length == 0 ) {
@@ -1197,17 +1243,18 @@ int handle_http_frame_data(struct http_client_ctx *client)
11971243 if (stream == NULL ) {
11981244 LOG_DBG ("No stream context found for ID %d" ,
11991245 frame -> stream_identifier );
1200- return - EBADMSG ;
1246+ ret = - EBADMSG ;
1247+ goto error ;
12011248 }
12021249
12031250 ret = send_window_update_frame (client , stream );
12041251 if (ret < 0 ) {
1205- return ret ;
1252+ goto error ;
12061253 }
12071254
12081255 ret = send_window_update_frame (client , NULL );
12091256 if (ret < 0 ) {
1210- return ret ;
1257+ goto error ;
12111258 }
12121259
12131260 if (is_header_flag_set (frame -> flags , HTTP2_FLAG_END_STREAM )) {
@@ -1224,6 +1271,14 @@ int handle_http_frame_data(struct http_client_ctx *client)
12241271 }
12251272
12261273 return 0 ;
1274+
1275+ error :
1276+ if (ret != - EAGAIN && client -> current_stream &&
1277+ !client -> current_stream -> headers_sent ) {
1278+ send_http2_500 (client , frame , - ret );
1279+ }
1280+
1281+ return ret ;
12271282}
12281283
12291284static void check_user_request_headers_http2 (struct http_header_capture_ctx * ctx ,
@@ -1473,14 +1528,14 @@ int handle_http_frame_headers(struct http_client_ctx *client)
14731528 if (is_header_flag_set (frame -> flags , HTTP2_FLAG_PADDED )) {
14741529 ret = parse_http_frame_padded_field (client );
14751530 if (ret < 0 ) {
1476- return ret ;
1531+ goto error ;
14771532 }
14781533 }
14791534
14801535 if (is_header_flag_set (frame -> flags , HTTP2_FLAG_PRIORITY )) {
14811536 ret = parse_http_frame_priority_field (client );
14821537 if (ret < 0 ) {
1483- return ret ;
1538+ goto error ;
14841539 }
14851540 }
14861541
@@ -1496,12 +1551,17 @@ int handle_http_frame_headers(struct http_client_ctx *client)
14961551 ret = - EBADMSG ;
14971552 }
14981553
1499- return ret ;
1554+ if (ret < 0 ) {
1555+ goto error ;
1556+ }
1557+
1558+ return 0 ;
15001559 }
15011560
15021561 if (ret > frame -> length ) {
15031562 LOG_ERR ("Protocol error, frame length exceeded" );
1504- return - EBADMSG ;
1563+ ret = - EBADMSG ;
1564+ goto error ;
15051565 }
15061566
15071567 frame -> length -= ret ;
@@ -1513,7 +1573,7 @@ int handle_http_frame_headers(struct http_client_ctx *client)
15131573
15141574 ret = process_header (client , header );
15151575 if (ret < 0 ) {
1516- return ret ;
1576+ goto error ;
15171577 }
15181578 }
15191579
@@ -1532,34 +1592,34 @@ int handle_http_frame_headers(struct http_client_ctx *client)
15321592 (struct http_resource_detail_static * )detail ,
15331593 frame , client );
15341594 if (ret < 0 ) {
1535- return ret ;
1595+ goto error ;
15361596 }
15371597 } else if (detail -> type == HTTP_RESOURCE_TYPE_STATIC_FS ) {
15381598 ret = handle_http2_static_fs_resource (
15391599 (struct http_resource_detail_static_fs * )detail , frame , client );
15401600 if (ret < 0 ) {
1541- return ret ;
1601+ goto error ;
15421602 }
15431603 } else if (detail -> type == HTTP_RESOURCE_TYPE_DYNAMIC ) {
15441604 ret = handle_http2_dynamic_resource (
15451605 (struct http_resource_detail_dynamic * )detail ,
15461606 frame , client );
15471607 if (ret < 0 ) {
1548- return ret ;
1608+ goto error ;
15491609 }
15501610 }
15511611
15521612 } else {
15531613 ret = send_http2_404 (client , frame );
15541614 if (ret < 0 ) {
1555- return ret ;
1615+ goto error ;
15561616 }
15571617 }
15581618
15591619 if (is_header_flag_set (frame -> flags , HTTP2_FLAG_END_STREAM )) {
15601620 ret = handle_http_frame_headers_end_stream (client );
15611621 if (ret < 0 ) {
1562- return ret ;
1622+ goto error ;
15631623 }
15641624 }
15651625
@@ -1570,6 +1630,14 @@ int handle_http_frame_headers(struct http_client_ctx *client)
15701630 }
15711631
15721632 return 0 ;
1633+
1634+ error :
1635+ if (ret != - EAGAIN && client -> current_stream &&
1636+ !client -> current_stream -> headers_sent ) {
1637+ send_http2_500 (client , frame , - ret );
1638+ }
1639+
1640+ return ret ;
15731641}
15741642
15751643int handle_http_frame_priority (struct http_client_ctx * client )
0 commit comments