Keep track of the remote IP for HTTP connections, and make it available to the callback function

This commit is contained in:
Jamie Cameron
2026-07-13 14:41:52 -07:00
parent 9e7cdc801c
commit 70011c11c0

View File

@@ -3223,6 +3223,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. =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 =cut
sub http_download sub http_download
{ {
@@ -3291,6 +3308,7 @@ if (!ref($h)) {
if ($error) { $$error = $h; return; } if ($error) { $$error = $h; return; }
else { &error(&html_escape($h)); } else { &error(&html_escape($h)); }
} }
&$cbfunc(7, $h->{'ip'}) if ($cbfunc);
&complete_http_download($h, $dest, $error, $cbfunc, $osdn, $host, $port, &complete_http_download($h, $dest, $error, $cbfunc, $osdn, $host, $port,
$headers, $ssl, $nocache, $timeout, $response_headers); $headers, $ssl, $nocache, $timeout, $response_headers);
if ((!$error || !$$error) && !$nocache) { if ((!$error || !$$error) && !$nocache) {
@@ -3883,6 +3901,8 @@ parameters are :
=item bindip - Local IP address to bind to for outgoing connections =item bindip - Local IP address to bind to for outgoing connections
Returns the IP to which the connection was actually made.
=cut =cut
sub open_socket sub open_socket
{ {
@@ -3899,13 +3919,14 @@ my @ips = &to_ipaddress($host);
push(@ips, &to_ip6address($host)); push(@ips, &to_ip6address($host));
if (!@ips) { if (!@ips) {
my $msg = "Failed to lookup IP address for $host"; my $msg = "Failed to lookup IP address for $host";
if ($err) { $$err = $msg; return 0; } if ($err) { $$err = $msg; return undef; }
else { &error($msg); } else { &error($msg); }
} }
# Try each of the resolved IPs # Try each of the resolved IPs
my $msg; my $msg;
my $proto = getprotobyname("tcp"); my $proto = getprotobyname("tcp");
my $gotip;
foreach my $ip (@ips) { foreach my $ip (@ips) {
$msg = undef; $msg = undef;
if (&check_ipaddress($ip)) { if (&check_ipaddress($ip)) {
@@ -3943,11 +3964,12 @@ foreach my $ip (@ips) {
next; next;
} }
} }
$gotip = $ip;
last; # If we got this far, it worked last; # If we got this far, it worked
} }
if ($msg) { if ($msg) {
# Last attempt failed # Last attempt failed
if ($err) { $$err = $msg; return 0; } if ($err) { $$err = $msg; return undef; }
else { &error($msg); } else { &error($msg); }
} }
@@ -3955,7 +3977,7 @@ if ($msg) {
my $old = select($fh); my $old = select($fh);
$| = 1; $| = 1;
select($old); select($old);
return 1; return $gotip;
} }
=head2 download_timeout =head2 download_timeout
@@ -9782,8 +9804,9 @@ if ($ssl) {
if (!$connected) { if (!$connected) {
# Direct connection # Direct connection
my $error; my $error;
&open_socket($host, $port, $rv->{'fh'}, \$error, $bindip); my $ip = &open_socket($host, $port, $rv->{'fh'}, \$error, $bindip);
return $error if ($error); return $error if ($error);
$rv->{'ip'} = $ip;
} }
Net::SSLeay::set_fd($rv->{'ssl_con'}, fileno($rv->{'fh'})); Net::SSLeay::set_fd($rv->{'ssl_con'}, fileno($rv->{'fh'}));
eval { eval {
@@ -9835,9 +9858,10 @@ else {
if (!$connected) { if (!$connected) {
# Connecting directly # Connecting directly
my $error; my $error;
&open_socket($host, $port, $rv->{'fh'}, \$error, $bindip); my $ip = &open_socket($host, $port, $rv->{'fh'}, \$error, $bindip);
return $error if ($error); return $error if ($error);
my $fh = $rv->{'fh'}; my $fh = $rv->{'fh'};
$rv->{'ip'} = $ip;
my $rtxt = "$method $page HTTP/1.0\r\n".$htxt; my $rtxt = "$method $page HTTP/1.0\r\n".$htxt;
print $fh $rtxt; print $fh $rtxt;
} }