@@ -369,6 +369,46 @@ static int send_http2_409(struct http_client_ctx *client,
369
369
return ret ;
370
370
}
371
371
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
+
372
412
static int handle_http2_static_resource (
373
413
struct http_resource_detail_static * static_detail ,
374
414
struct http2_frame * frame , struct http_client_ctx * client )
@@ -1027,7 +1067,7 @@ int handle_http1_to_http2_upgrade(struct http_client_ctx *client)
1027
1067
ret = http_server_sendall (client , switching_protocols ,
1028
1068
sizeof (switching_protocols ) - 1 );
1029
1069
if (ret < 0 ) {
1030
- goto error ;
1070
+ return ret ;
1031
1071
}
1032
1072
1033
1073
client -> http1_headers_sent = true;
@@ -1101,6 +1141,11 @@ int handle_http1_to_http2_upgrade(struct http_client_ctx *client)
1101
1141
return 0 ;
1102
1142
1103
1143
error :
1144
+ if (ret != - EAGAIN && client -> current_stream &&
1145
+ !client -> current_stream -> headers_sent ) {
1146
+ send_http2_500 (client , frame , - ret );
1147
+ }
1148
+
1104
1149
return ret ;
1105
1150
}
1106
1151
@@ -1169,13 +1214,14 @@ int handle_http_frame_data(struct http_client_ctx *client)
1169
1214
/* There is no handler */
1170
1215
LOG_DBG ("No dynamic handler found." );
1171
1216
(void )send_http2_404 (client , frame );
1172
- return - ENOENT ;
1217
+ ret = - ENOENT ;
1218
+ goto error ;
1173
1219
}
1174
1220
1175
1221
if (is_header_flag_set (frame -> flags , HTTP2_FLAG_PADDED )) {
1176
1222
ret = parse_http_frame_padded_field (client );
1177
1223
if (ret < 0 ) {
1178
- return ret ;
1224
+ goto error ;
1179
1225
}
1180
1226
}
1181
1227
@@ -1187,7 +1233,7 @@ int handle_http_frame_data(struct http_client_ctx *client)
1187
1233
}
1188
1234
1189
1235
if (ret < 0 ) {
1190
- return ret ;
1236
+ goto error ;
1191
1237
}
1192
1238
1193
1239
if (frame -> length == 0 ) {
@@ -1197,17 +1243,18 @@ int handle_http_frame_data(struct http_client_ctx *client)
1197
1243
if (stream == NULL ) {
1198
1244
LOG_DBG ("No stream context found for ID %d" ,
1199
1245
frame -> stream_identifier );
1200
- return - EBADMSG ;
1246
+ ret = - EBADMSG ;
1247
+ goto error ;
1201
1248
}
1202
1249
1203
1250
ret = send_window_update_frame (client , stream );
1204
1251
if (ret < 0 ) {
1205
- return ret ;
1252
+ goto error ;
1206
1253
}
1207
1254
1208
1255
ret = send_window_update_frame (client , NULL );
1209
1256
if (ret < 0 ) {
1210
- return ret ;
1257
+ goto error ;
1211
1258
}
1212
1259
1213
1260
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)
1224
1271
}
1225
1272
1226
1273
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 ;
1227
1282
}
1228
1283
1229
1284
static 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)
1473
1528
if (is_header_flag_set (frame -> flags , HTTP2_FLAG_PADDED )) {
1474
1529
ret = parse_http_frame_padded_field (client );
1475
1530
if (ret < 0 ) {
1476
- return ret ;
1531
+ goto error ;
1477
1532
}
1478
1533
}
1479
1534
1480
1535
if (is_header_flag_set (frame -> flags , HTTP2_FLAG_PRIORITY )) {
1481
1536
ret = parse_http_frame_priority_field (client );
1482
1537
if (ret < 0 ) {
1483
- return ret ;
1538
+ goto error ;
1484
1539
}
1485
1540
}
1486
1541
@@ -1496,12 +1551,17 @@ int handle_http_frame_headers(struct http_client_ctx *client)
1496
1551
ret = - EBADMSG ;
1497
1552
}
1498
1553
1499
- return ret ;
1554
+ if (ret < 0 ) {
1555
+ goto error ;
1556
+ }
1557
+
1558
+ return 0 ;
1500
1559
}
1501
1560
1502
1561
if (ret > frame -> length ) {
1503
1562
LOG_ERR ("Protocol error, frame length exceeded" );
1504
- return - EBADMSG ;
1563
+ ret = - EBADMSG ;
1564
+ goto error ;
1505
1565
}
1506
1566
1507
1567
frame -> length -= ret ;
@@ -1513,7 +1573,7 @@ int handle_http_frame_headers(struct http_client_ctx *client)
1513
1573
1514
1574
ret = process_header (client , header );
1515
1575
if (ret < 0 ) {
1516
- return ret ;
1576
+ goto error ;
1517
1577
}
1518
1578
}
1519
1579
@@ -1532,34 +1592,34 @@ int handle_http_frame_headers(struct http_client_ctx *client)
1532
1592
(struct http_resource_detail_static * )detail ,
1533
1593
frame , client );
1534
1594
if (ret < 0 ) {
1535
- return ret ;
1595
+ goto error ;
1536
1596
}
1537
1597
} else if (detail -> type == HTTP_RESOURCE_TYPE_STATIC_FS ) {
1538
1598
ret = handle_http2_static_fs_resource (
1539
1599
(struct http_resource_detail_static_fs * )detail , frame , client );
1540
1600
if (ret < 0 ) {
1541
- return ret ;
1601
+ goto error ;
1542
1602
}
1543
1603
} else if (detail -> type == HTTP_RESOURCE_TYPE_DYNAMIC ) {
1544
1604
ret = handle_http2_dynamic_resource (
1545
1605
(struct http_resource_detail_dynamic * )detail ,
1546
1606
frame , client );
1547
1607
if (ret < 0 ) {
1548
- return ret ;
1608
+ goto error ;
1549
1609
}
1550
1610
}
1551
1611
1552
1612
} else {
1553
1613
ret = send_http2_404 (client , frame );
1554
1614
if (ret < 0 ) {
1555
- return ret ;
1615
+ goto error ;
1556
1616
}
1557
1617
}
1558
1618
1559
1619
if (is_header_flag_set (frame -> flags , HTTP2_FLAG_END_STREAM )) {
1560
1620
ret = handle_http_frame_headers_end_stream (client );
1561
1621
if (ret < 0 ) {
1562
- return ret ;
1622
+ goto error ;
1563
1623
}
1564
1624
}
1565
1625
@@ -1570,6 +1630,14 @@ int handle_http_frame_headers(struct http_client_ctx *client)
1570
1630
}
1571
1631
1572
1632
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 ;
1573
1641
}
1574
1642
1575
1643
int handle_http_frame_priority (struct http_client_ctx * client )
0 commit comments