From 5df2ec3530f33a91957ece5e93609b38f4002f08 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Mon, 13 Apr 2026 21:06:58 +0200 Subject: [PATCH 1/3] Implement a test server that drops connections right away ... without sending a response. It acts like Privoxy when the connection is dropped due to an ACL rule with wildcard destination and can be used to show different curl(1) behaviour before and after 335dc0e3c59. --- docs/tests/FILEFORMAT.md | 1 + tests/http-server.pl | 5 +++++ tests/server/sws.c | 18 ++++++++++++++++++ tests/serverhelp.pm | 2 +- tests/servers.pm | 24 +++++++++++++++++++++++- 5 files changed, 48 insertions(+), 2 deletions(-) diff --git a/docs/tests/FILEFORMAT.md b/docs/tests/FILEFORMAT.md index bce3e440f2..60ba36a63d 100644 --- a/docs/tests/FILEFORMAT.md +++ b/docs/tests/FILEFORMAT.md @@ -433,6 +433,7 @@ Commands for the test DNS server. ### `` What server(s) this test case requires/uses. Available servers: +- `connection-dropper` - `dict` - `file` - `ftp` diff --git a/tests/http-server.pl b/tests/http-server.pl index 006b6f3817..467b9a6fd4 100755 --- a/tests/http-server.pl +++ b/tests/http-server.pl @@ -53,6 +53,7 @@ my $connect; # IP to connect to on CONNECT my $keepalive_secs; # number of seconds to keep idle connections my $srcdir; my $gopher = 0; +my $drop_connection = 0; my $flags = ""; my $path = '.'; @@ -112,6 +113,9 @@ while(@ARGV) { elsif($ARGV[0] eq '--gopher') { $gopher = 1; } + elsif($ARGV[0] eq '--drop-connection') { + $drop_connection = 1; + } elsif($ARGV[0] eq '--port') { if($ARGV[1] =~ /^(\d+)$/) { $port = $1; @@ -175,6 +179,7 @@ $flags .= "--pidfile \"$pidfile\" ". "--portfile \"$portfile\" "; $flags .= "--gopher " if($gopher); $flags .= "--connect $connect " if($connect); +$flags .= "--drop-connection " if($drop_connection); $flags .= "--keepalive $keepalive_secs " if($keepalive_secs); if($ipvnum eq 'unix') { $flags .= "--unix-socket '$unix_socket' "; diff --git a/tests/server/sws.c b/tests/server/sws.c index cc7adaf052..9c587075f4 100644 --- a/tests/server/sws.c +++ b/tests/server/sws.c @@ -36,6 +36,7 @@ static bool use_gopher = FALSE; static bool is_proxy = FALSE; +static bool drop_connection = FALSE; #define MAX_SLEEP_TIME_MS 250 @@ -2037,6 +2038,11 @@ static int test_sws(int argc, const char *argv[]) protocol_type = "GOPHER"; end_of_headers = "\r\n"; /* gopher style is much simpler */ } + else if(!strcmp("--drop-connection", argv[arg])) { + arg++; + protocol_type = "connection-dropper"; + drop_connection = TRUE; + } else if(!strcmp("--ipv4", argv[arg])) { socket_type = "IPv4"; socket_domain = AF_INET; @@ -2126,6 +2132,7 @@ static int test_sws(int argc, const char *argv[]) " --port [port]\n" " --srcdir [path]\n" " --connect [ip4-addr]\n" + " --drop-connection\n" " --gopher"); return 0; } @@ -2359,6 +2366,17 @@ static int test_sws(int argc, const char *argv[]) (long)sock, (long)msgsock); if(msgsock == CURL_SOCKET_BAD) goto sws_cleanup; + if(drop_connection) { + num_sockets--; + logmsg("closing connection on socket %ld right away.", + (long)all_sockets[num_sockets]); + sclose(all_sockets[num_sockets]); + all_sockets[num_sockets] = CURL_SOCKET_BAD; + serverlogslocked -= 1; + if(!serverlogslocked) + clear_advisor_read_lock(loglockfile); + break; + } if(req->delay) curlx_wait_ms(req->delay); } while(msgsock > 0); diff --git a/tests/serverhelp.pm b/tests/serverhelp.pm index 3f345ad74a..e71795bfef 100644 --- a/tests/serverhelp.pm +++ b/tests/serverhelp.pm @@ -125,7 +125,7 @@ sub servername_str { $proto = uc($proto) if($proto); die "unsupported protocol: '$proto'" unless($proto && - ($proto =~ /^(((DNS|FTP|HTTP|HTTP\/2|HTTP\/3|IMAP|POP3|GOPHER|SMTP|HTTPS-MTLS)S?)|(TFTP|SFTP|SOCKS|SSH|RTSP|HTTPTLS|DICT|SMB|SMBS|TELNET|MQTT|MQTTS))$/)); + ($proto =~ /^(((DNS|FTP|HTTP|HTTP\/2|HTTP\/3|IMAP|POP3|GOPHER|SMTP|HTTPS-MTLS)S?)|(TFTP|SFTP|SOCKS|SSH|RTSP|HTTPTLS|DICT|SMB|SMBS|TELNET|MQTT|MQTTS|CONNECTION-DROPPER))$/)); $ipver = (not $ipver) ? 'ipv4' : lc($ipver); die "unsupported IP version: '$ipver'" unless($ipver && diff --git a/tests/servers.pm b/tests/servers.pm index dba3c3e1d1..26a5b99565 100644 --- a/tests/servers.pm +++ b/tests/servers.pm @@ -238,7 +238,7 @@ sub init_serverpidfile_hash { } for my $proto (('tftp', 'sftp', 'socks', 'ssh', 'rtsp', 'httptls', 'dict', 'smb', 'smbs', 'telnet', 'mqtt', 'mqtts', - 'https-mtls', 'dns')) { + 'https-mtls', 'dns', 'connection-dropper')) { for my $ipvnum ((4, 6)) { for my $idnum ((1, 2)) { my $serv = servername_id($proto, $ipvnum, $idnum); @@ -309,6 +309,7 @@ sub serverfortest { my @lprotocols = @protocols; push @lprotocols, "dns"; + push @lprotocols, "connection-dropper"; if(! grep /^\Q$server\E$/, @lprotocols) { if(substr($server, 0, 5) ne "socks") { @@ -1038,6 +1039,7 @@ my %protofunc = ('http' => \&verifyhttp, 'socks' => \&verifypid, 'socks5unix' => \&verifypid, 'gopher' => \&verifyhttp, + 'connection-dropper' => \&verifypid, 'httptls' => \&verifyhttptls, 'dict' => \&verifyftp, 'smb' => \&verifysmb, @@ -1114,6 +1116,7 @@ sub runhttpserver { my $flags = ""; $flags .= "--gopher " if($proto eq "gopher"); + $flags .= "--drop-connection " if($proto eq "connection-dropper"); $flags .= "--connect $HOSTIP " if($alt eq "proxy"); $flags .= "--keepalive $keepalive_secs "; $flags .= $verbose_flag if($debugprotocol); @@ -2453,6 +2456,25 @@ sub startservers { $run{'ftp-ipv6'}="$pid $pid2"; } } + elsif($what eq "connection-dropper") { + if($run{'connection-dropper'} && + !responsive_http_server("connection-dropper", $verbose, 0, + protoport("http"))) { + if(stopserver('connection-dropper')) { + return ("failed stopping unresponsive connection-dropper server", 3); + } + } + if(!$run{'connection-dropper'}) { + ($serr, $pid, $pid2, $PORT{'http'}) = + runhttpserver("connection-dropper", $verbose, 0); + if($pid <= 0) { + return ("failed starting CONNECTION-DROPPER server", $serr); + } + logmsg sprintf ("* pid connection-dropper => %d %d\n", $pid, $pid2) + if($verbose); + $run{'connection-dropper'}="$pid $pid2"; + } + } elsif($what eq "gopher") { if($run{'gopher'} && !responsive_http_server("gopher", $verbose, 0, -- 2.53.0 From 4627f26e0982dcdba0d5808f1017ee56d763fb89 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Wed, 15 Apr 2026 12:45:48 +0200 Subject: [PATCH 2/3] Add test1628: HTTP GET to a proxy that closes the connection right away --- tests/data/Makefile.am | 2 +- tests/data/test1628 | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 tests/data/test1628 diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 857389450e..2477736ac0 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -214,7 +214,7 @@ test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 \ test1598 test1599 test1600 test1601 test1602 test1603 test1604 test1605 \ test1606 test1607 test1608 test1609 test1610 test1611 test1612 test1613 \ test1614 test1615 test1616 test1617 test1618 test1619 test1620 test1621 \ -test1622 test1623 test1624 test1625 test1626 test1627 \ +test1622 test1623 test1624 test1625 test1626 test1627 test1628 \ \ test1630 test1631 test1632 test1633 test1634 test1635 test1636 test1637 \ test1638 test1639 test1640 test1641 test1642 test1643 test1644 \ diff --git a/tests/data/test1628 b/tests/data/test1628 new file mode 100644 index 0000000000..c54fc49892 --- /dev/null +++ b/tests/data/test1628 @@ -0,0 +1,36 @@ + + + + +HTTP +HTTP GET +HTTP proxy + + + +# Server-side + + + + + +# Client-side + + +connection-dropper + + +HTTP GET to a proxy that closes the connection without reading data or sending a response + + +--proxy http://%HOSTIP:%HTTPPORT http://%HOSTIP:%HTTPPORT/%TESTNUMBER + + + +# Verify data after the test has been "shot" + + +56 + + + -- 2.53.0 From 978ad134cb93d97bb1460c712c8af622b617cc61 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Wed, 15 Apr 2026 12:51:18 +0200 Subject: [PATCH 3/3] Add test1629: HTTP GET to a server that closes the connection right away --- tests/data/Makefile.am | 2 +- tests/data/test1629 | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 tests/data/test1629 diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 2477736ac0..30fe740dee 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -214,7 +214,7 @@ test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 \ test1598 test1599 test1600 test1601 test1602 test1603 test1604 test1605 \ test1606 test1607 test1608 test1609 test1610 test1611 test1612 test1613 \ test1614 test1615 test1616 test1617 test1618 test1619 test1620 test1621 \ -test1622 test1623 test1624 test1625 test1626 test1627 test1628 \ +test1622 test1623 test1624 test1625 test1626 test1627 test1628 test1629 \ \ test1630 test1631 test1632 test1633 test1634 test1635 test1636 test1637 \ test1638 test1639 test1640 test1641 test1642 test1643 test1644 \ diff --git a/tests/data/test1629 b/tests/data/test1629 new file mode 100644 index 0000000000..c588568898 --- /dev/null +++ b/tests/data/test1629 @@ -0,0 +1,35 @@ + + + + +HTTP +HTTP GET + + + +# Server-side + + + + + +# Client-side + + +connection-dropper + + +HTTP GET to a server that closes the connection without reading data or sending a response + + +http://%HOSTIP:%HTTPPORT/%TESTNUMBER + + + +# Verify data after the test has been "shot" + + +56 + + + -- 2.53.0