diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2021-12-25 18:30:28 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2021-12-26 12:41:48 +0300 |
commit | 005d1f25b2a8b2db5bc81f7134f3ca9e75fafa06 (patch) | |
tree | 2ecccfbfcc6d618eb18eea0a920343cc2e9df743 | |
parent | 8140b9e73792afc38ac8b6b4b0bd1a55ef1561a7 (diff) | |
download | libmicrohttpd-005d1f25b2a8b2db5bc81f7134f3ca9e75fafa06.tar.gz libmicrohttpd-005d1f25b2a8b2db5bc81f7134f3ca9e75fafa06.zip |
test_client_put_stop: ensure that some data will be received by MHD before closing
Simplified and unified code, improved readability.
-rw-r--r-- | src/microhttpd/test_client_put_stop.c | 66 |
1 files changed, 54 insertions, 12 deletions
diff --git a/src/microhttpd/test_client_put_stop.c b/src/microhttpd/test_client_put_stop.c index d2629031..c1707c5c 100644 --- a/src/microhttpd/test_client_put_stop.c +++ b/src/microhttpd/test_client_put_stop.c | |||
@@ -1376,6 +1376,7 @@ performQueryExternal (struct MHD_Daemon *d, struct _MHD_dumbClient *clnt) | |||
1376 | int client_accepted; | 1376 | int client_accepted; |
1377 | int full_req_recieved; | 1377 | int full_req_recieved; |
1378 | int full_req_sent; | 1378 | int full_req_sent; |
1379 | int some_data_recieved; | ||
1379 | 1380 | ||
1380 | di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_LISTEN_FD); | 1381 | di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_LISTEN_FD); |
1381 | if (NULL == di) | 1382 | if (NULL == di) |
@@ -1388,6 +1389,7 @@ performQueryExternal (struct MHD_Daemon *d, struct _MHD_dumbClient *clnt) | |||
1388 | _MHD_dumbClient_start_connect (clnt); | 1389 | _MHD_dumbClient_start_connect (clnt); |
1389 | 1390 | ||
1390 | full_req_recieved = 0; | 1391 | full_req_recieved = 0; |
1392 | some_data_recieved = 0; | ||
1391 | start = time (NULL); | 1393 | start = time (NULL); |
1392 | do | 1394 | do |
1393 | { | 1395 | { |
@@ -1396,6 +1398,7 @@ performQueryExternal (struct MHD_Daemon *d, struct _MHD_dumbClient *clnt) | |||
1396 | fd_set es; | 1398 | fd_set es; |
1397 | MHD_socket maxMhdSk; | 1399 | MHD_socket maxMhdSk; |
1398 | int num_ready; | 1400 | int num_ready; |
1401 | int do_client; /**< Process data in client */ | ||
1399 | 1402 | ||
1400 | maxMhdSk = MHD_INVALID_SOCKET; | 1403 | maxMhdSk = MHD_INVALID_SOCKET; |
1401 | FD_ZERO (&rs); | 1404 | FD_ZERO (&rs); |
@@ -1407,6 +1410,7 @@ performQueryExternal (struct MHD_Daemon *d, struct _MHD_dumbClient *clnt) | |||
1407 | * processing any connections */ | 1410 | * processing any connections */ |
1408 | unsigned long long to; | 1411 | unsigned long long to; |
1409 | full_req_sent = 1; | 1412 | full_req_sent = 1; |
1413 | do_client = 0; | ||
1410 | if (client_accepted && (MHD_YES != MHD_get_timeout (d, &to))) | 1414 | if (client_accepted && (MHD_YES != MHD_get_timeout (d, &to))) |
1411 | { | 1415 | { |
1412 | ret = 0; | 1416 | ret = 0; |
@@ -1416,12 +1420,36 @@ performQueryExternal (struct MHD_Daemon *d, struct _MHD_dumbClient *clnt) | |||
1416 | else | 1420 | else |
1417 | { | 1421 | { |
1418 | full_req_sent = _MHD_dumbClient_is_req_sent (clnt); | 1422 | full_req_sent = _MHD_dumbClient_is_req_sent (clnt); |
1419 | if ((! full_req_sent) || full_req_recieved || (0 == rate_limiter)) | 1423 | if (! full_req_sent) |
1424 | do_client = 1; /* Request hasn't been sent yet, send the data */ | ||
1425 | else | ||
1426 | { | ||
1427 | /* All request data has been sent. | ||
1428 | * Client will close the socket as the next step. */ | ||
1429 | if (full_req_recieved) | ||
1430 | do_client = 1; /* All data has been received by the MHD */ | ||
1431 | else if ((0 == rate_limiter) && some_data_recieved) | ||
1432 | { | ||
1433 | /* No RST rate limiter, no need to avoid extra RST | ||
1434 | * and at least something was received by the MHD */ | ||
1435 | do_client = 1; | ||
1436 | } | ||
1437 | else | ||
1438 | { | ||
1439 | /* When rate limiter is enabled, all sent packets must be received | ||
1440 | * before client close connection to avoid RST for every ACK. | ||
1441 | * When rate limiter is not enabled, the MHD must receive at | ||
1442 | * least something before closing the connection. */ | ||
1443 | do_client = 0; | ||
1444 | } | ||
1445 | } | ||
1446 | |||
1447 | if (do_client) | ||
1420 | _MHD_dumbClient_get_fdsets (clnt, &maxMhdSk, &rs, &ws, &es); | 1448 | _MHD_dumbClient_get_fdsets (clnt, &maxMhdSk, &rs, &ws, &es); |
1421 | } | 1449 | } |
1422 | if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxMhdSk)) | 1450 | if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxMhdSk)) |
1423 | mhdErrorExitDesc ("MHD_get_fdset() failed"); | 1451 | mhdErrorExitDesc ("MHD_get_fdset() failed"); |
1424 | if ((! full_req_sent) || full_req_recieved || (0 == rate_limiter)) | 1452 | if (do_client) |
1425 | { | 1453 | { |
1426 | tv.tv_sec = 1; | 1454 | tv.tv_sec = 1; |
1427 | tv.tv_usec = 250 * 1000; | 1455 | tv.tv_usec = 250 * 1000; |
@@ -1447,6 +1475,8 @@ performQueryExternal (struct MHD_Daemon *d, struct _MHD_dumbClient *clnt) | |||
1447 | } | 1475 | } |
1448 | if (0 == num_ready) | 1476 | if (0 == num_ready) |
1449 | { /* select() finished by timeout, looks like no more packets are pending */ | 1477 | { /* select() finished by timeout, looks like no more packets are pending */ |
1478 | if (do_client) | ||
1479 | externalErrorExitDesc ("Timeout waiting for sockets"); | ||
1450 | if (full_req_sent && (! full_req_recieved)) | 1480 | if (full_req_sent && (! full_req_recieved)) |
1451 | full_req_recieved = 1; | 1481 | full_req_recieved = 1; |
1452 | } | 1482 | } |
@@ -1454,21 +1484,33 @@ performQueryExternal (struct MHD_Daemon *d, struct _MHD_dumbClient *clnt) | |||
1454 | mhdErrorExitDesc ("MHD_run_from_select() failed"); | 1484 | mhdErrorExitDesc ("MHD_run_from_select() failed"); |
1455 | if (! client_accepted) | 1485 | if (! client_accepted) |
1456 | client_accepted = FD_ISSET (lstn_sk, &rs); | 1486 | client_accepted = FD_ISSET (lstn_sk, &rs); |
1457 | if (NULL != clnt) | 1487 | else |
1458 | { | 1488 | { /* Client connection was already accepted by MHD */ |
1459 | /* Do not close the socket on client side until | 1489 | if (! some_data_recieved) |
1460 | * MHD is accepted and processed the socket. */ | ||
1461 | if (! full_req_sent || (client_accepted && ! FD_ISSET (lstn_sk, &rs))) | ||
1462 | { | 1490 | { |
1463 | if ((! full_req_sent) || full_req_recieved || (0 == rate_limiter)) | 1491 | if (! do_client) |
1464 | { | 1492 | { |
1465 | /* When rate limiter is enabled, all sent packets must be received | 1493 | if (0 != num_ready) |
1466 | * before client close connection to avoid RST for every ACK. */ | 1494 | { /* Connection was accepted before, "ready" socket means data */ |
1467 | if (_MHD_dumbClient_process_from_fdsets (clnt, &rs, &ws, &es)) | 1495 | some_data_recieved = 1; |
1468 | clnt = NULL; | 1496 | } |
1497 | } | ||
1498 | else | ||
1499 | { | ||
1500 | if (2 == num_ready) | ||
1501 | some_data_recieved = 1; | ||
1502 | else if ((1 == num_ready) && | ||
1503 | ((MHD_INVALID_SOCKET == clnt->sckt) || | ||
1504 | ! FD_ISSET (clnt->sckt, &ws))) | ||
1505 | some_data_recieved = 1; | ||
1469 | } | 1506 | } |
1470 | } | 1507 | } |
1471 | } | 1508 | } |
1509 | if (do_client) | ||
1510 | { | ||
1511 | if (_MHD_dumbClient_process_from_fdsets (clnt, &rs, &ws, &es)) | ||
1512 | clnt = NULL; | ||
1513 | } | ||
1472 | /* Use double timeout value here so MHD would be able to catch timeout | 1514 | /* Use double timeout value here so MHD would be able to catch timeout |
1473 | * internally */ | 1515 | * internally */ |
1474 | } while (time (NULL) - start <= (TIMEOUTS_VAL * 2)); | 1516 | } while (time (NULL) - start <= (TIMEOUTS_VAL * 2)); |