Fix to manually incorporated Jamie's 70011c1 change

This commit is contained in:
Ilia Ross
2026-07-14 00:46:12 +02:00
parent dae0bf373d
commit bf3cd03977
2 changed files with 59 additions and 7 deletions

View File

@@ -278,6 +278,34 @@ subtest 'callback hash dispatches tracker events' => sub {
'legacy callback code refs remain supported');
};
subtest 'callback bundle preserves connected IP event' => sub {
no warnings qw(once redefine);
my ($connection_callback, $download_callbacks);
local *main::make_http_connection = sub {
$connection_callback = $_[8];
return { 'ip' => '93.184.216.34' };
};
local *main::complete_http_download = sub {
$download_callbacks = $_[3];
return 1;
};
my @events;
my $address_callback = sub { return undef; };
my $callbacks = {
'tracker_callback' => sub { push(@events, [ @_ ]); },
'address_callback' => $address_callback,
};
my ($dest, $err);
main::http_download('origin.test', 80, '/', \$dest, \$err, $callbacks,
0, undef, undef, 0, undef, 1);
is_deeply(\@events, [ [ 7, '93.184.216.34' ] ],
'tracker callback receives the connected IP event');
is($connection_callback, $address_callback,
'connection receives the address callback');
is($download_callbacks, $callbacks,
'download receives the complete callback bundle');
};
subtest 'redirect destination policy' => sub {
no warnings qw(once redefine);
my @lines = (

View File

@@ -3367,6 +3367,23 @@ Downloads data from a HTTP url to a local file or string. The parameters are :
=item response_headers - If set returns a hash ref of response HTTP headers.
If the callback function is defined, it will be called at each step of the download process with a mode parameter and
additional args. The mode will be one of :
=item 1 - Completed reading headers, arg is 1 for a redirect, 0 otherwise
=item 2 - Received content length, arg is the response size in bytes
=item 3 - Received data, arg is the bytes returned so far
=item 4 - Finished receiving data
=item 5 - Following a redirect, arg is the new URL
=item 6 - Data was found in cache, arg is the full cached URL
=item 7 - TCP connection made, arg is the remote IP (if known)
=cut
sub http_download
{
@@ -3446,6 +3463,7 @@ if (!ref($h)) {
if ($error) { $$error = $h; return; }
else { &error(&html_escape($h)); }
}
&$cbfunc(7, $h->{'ip'}) if ($cbfunc);
&complete_http_download($h, $dest, $error, $callbacks, $osdn, $host, $port,
$headers, $ssl, $nocache, $timeout, $response_headers);
if ((!$error || !$$error) && !$nocache) {
@@ -4076,6 +4094,8 @@ parameters are :
array reference of its resolved IP addresses. It must return an error message
to reject the destination, or undef to allow it.
Returns the IP to which the connection was actually made.
=cut
sub open_socket
{
@@ -4093,13 +4113,14 @@ my $address_error = &check_download_address(
$host, $address_callback, \@ips);
if ($address_error) {
my $msg = $address_error;
if ($err) { $$err = $msg; return 0; }
if ($err) { $$err = $msg; return undef; }
else { &error($msg); }
}
# Try each of the resolved IPs
my $msg;
my $proto = getprotobyname("tcp");
my $gotip;
foreach my $ip (@ips) {
$msg = undef;
if (&check_ipaddress($ip)) {
@@ -4137,11 +4158,12 @@ foreach my $ip (@ips) {
next;
}
}
$gotip = $ip;
last; # If we got this far, it worked
}
if ($msg) {
# Last attempt failed
if ($err) { $$err = $msg; return 0; }
if ($err) { $$err = $msg; return undef; }
else { &error($msg); }
}
@@ -4149,7 +4171,7 @@ if ($msg) {
my $old = select($fh);
$| = 1;
select($old);
return 1;
return $gotip;
}
=head2 download_timeout
@@ -9995,9 +10017,10 @@ if ($ssl) {
if (!$connected) {
# Direct connection
my $error;
&open_socket($host, $port, $rv->{'fh'}, \$error, $bindip,
$address_callback);
my $ip = &open_socket($host, $port, $rv->{'fh'}, \$error, $bindip,
$address_callback);
return $error if ($error);
$rv->{'ip'} = $ip;
}
Net::SSLeay::set_fd($rv->{'ssl_con'}, fileno($rv->{'fh'}));
eval {
@@ -10049,10 +10072,11 @@ else {
if (!$connected) {
# Connecting directly
my $error;
&open_socket($host, $port, $rv->{'fh'}, \$error, $bindip,
$address_callback);
my $ip = &open_socket($host, $port, $rv->{'fh'}, \$error, $bindip,
$address_callback);
return $error if ($error);
my $fh = $rv->{'fh'};
$rv->{'ip'} = $ip;
my $rtxt = "$method $page HTTP/1.0\r\n".$htxt;
print $fh $rtxt;
}