From 934073532f55b6ced2ffff8149f408bed0d4dcbc Mon Sep 17 00:00:00 2001 From: Ilia Ross Date: Tue, 14 Jul 2026 02:27:10 +0200 Subject: [PATCH] Fix to use the existing HTTP and FTP mode 7 callback --- filemin/http_download.cgi | 19 +++-- mailboxes/t/run-tests.t | 23 ++++-- mailboxes/xhr-lib.pl | 17 +++-- t/web-lib-funcs-ip.t | 157 -------------------------------------- updown/updown-lib.pl | 17 +++-- web-lib-funcs.pl | 139 +++++++++------------------------ 6 files changed, 87 insertions(+), 285 deletions(-) diff --git a/filemin/http_download.cgi b/filemin/http_download.cgi index f61f711ee..64dbedccc 100755 --- a/filemin/http_download.cgi +++ b/filemin/http_download.cgi @@ -39,18 +39,23 @@ else { $progress_callback_url = $in{'link'}; my @st = stat($cwd); - my $callbacks = { - 'tracker_callback' => \&progress_callback, - 'address_callback' => &get_download_address_callback( - $access{'download_address_mode'} || 'public', - $access{'download_allowed_addresses'}), + my $address_checker = &get_download_address_callback( + $access{'download_address_mode'} || 'public', + $access{'download_allowed_addresses'}); + my $download_callback = sub { + if ($_[0] == 7 && defined($_[1]) && $address_checker) { + my $address_error = &$address_checker( + $host, [ $_[1] ]); + &error(&html_escape($address_error)) if ($address_error); + } + &progress_callback(@_); }; if ($ssl == 0 || $ssl == 1) { # HTTP or HTTPS download &http_download( $host, $port, $page, $full, undef, - $callbacks, + $download_callback, $ssl, $in{'username'}, $in{'password'}); } @@ -59,7 +64,7 @@ else { &ftp_download( $host, $page, $full, undef, - $callbacks, + $download_callback, $in{'username'}, $in{'password'}, $port); } diff --git a/mailboxes/t/run-tests.t b/mailboxes/t/run-tests.t index b6ba380df..7214ca1ae 100644 --- a/mailboxes/t/run-tests.t +++ b/mailboxes/t/run-tests.t @@ -149,21 +149,32 @@ subtest 'XHR remote content uses mailbox destination ACL' => sub { local *parse_http_url = sub { return ('example.test', 80, '/image.png', 0); }; - my $address_callback = sub { return 'mailbox-acl-callback'; }; + my $address_checker = sub { + POSIX::_exit(4) + if ($_[0] ne 'example.test' || + $_[1]->[0] ne '127.0.0.1'); + return 'mailbox-address-blocked'; + }; local *get_download_address_callback = sub { POSIX::_exit(3) if ($_[0] ne 'listed' || $_[1] ne '10.0.0.0/8'); - return $address_callback; + return $address_checker; }; + local *error = sub { + POSIX::_exit($_[0] eq 'mailbox-address-blocked' ? 0 : 1); + }; + local *html_escape = sub { return $_[0]; }; local *http_download = sub { - my $callback = $_[5]->{'address_callback'}; - POSIX::_exit(&$callback() eq 'mailbox-acl-callback' ? 0 : 1); + my $callback = $_[5]; + POSIX::_exit(5) if (ref($callback) ne 'CODE'); + &$callback(7, '127.0.0.1'); + POSIX::_exit(2); }; xhr(); - POSIX::_exit(2); + POSIX::_exit(6); } waitpid($pid, 0); - is($? >> 8, 0, 'XHR passes its callback bundle to HTTP download'); + is($? >> 8, 0, 'XHR checks mode 7 through the existing callback'); }; done_testing(); diff --git a/mailboxes/xhr-lib.pl b/mailboxes/xhr-lib.pl index d9715bfd6..8b8d40889 100644 --- a/mailboxes/xhr-lib.pl +++ b/mailboxes/xhr-lib.pl @@ -35,12 +35,19 @@ if ($in{'action'} eq "fetch") { $url = &html_unescape($url); my ($host, $port, $page, $ssl) = &parse_http_url($url); my ($img, $err, $response_headers); - my $callbacks = { - 'address_callback' => &get_download_address_callback( - $access{'download_address_mode'} || 'public', - $access{'download_allowed_addresses'}), + my $address_checker = &get_download_address_callback( + $access{'download_address_mode'} || 'public', + $access{'download_allowed_addresses'}); + my $download_callback = sub { + if ($_[0] == 7 && defined($_[1]) && $address_checker) { + my $address_error = &$address_checker( + $host, [ $_[1] ]); + &error(&html_escape($address_error)) + if ($address_error); + } }; - &http_download($host, $port, $page, \$img, \$err, $callbacks, + &http_download($host, $port, $page, \$img, \$err, + $download_callback, $ssl, undef, undef, 10, undef, undef, undef, \$response_headers); # Check if download worked diff --git a/t/web-lib-funcs-ip.t b/t/web-lib-funcs-ip.t index 9316dfa17..86f06db4e 100644 --- a/t/web-lib-funcs-ip.t +++ b/t/web-lib-funcs-ip.t @@ -234,161 +234,4 @@ subtest 'download address callback' => sub { } }; -subtest 'restricted download cache isolation' => sub { - no warnings qw(once redefine); - my $cache_checks = 0; - local *main::check_in_http_cache = sub { $cache_checks++; return; }; - local *main::make_http_connection = sub { return 'test connection stopped'; }; - my ($dest, $err); - my $callbacks = { 'address_callback' => sub { return undef; } }; - main::http_download('8.8.8.8', 80, '/', \$dest, \$err, $callbacks, - 0, undef, undef, 0); - is($cache_checks, 0, 'restricted download does not consult shared cache'); - is($err, 'test connection stopped', 'download reached mocked connection'); -}; - -subtest 'callback hash dispatches tracker events' => sub { - no warnings qw(once redefine); - my @lines = ( - "HTTP/1.0 200 OK\r\n", - "Content-Length: 0\r\n", - "\r\n", - ); - local *main::read_http_connection = sub { return shift(@lines); }; - local *main::close_http_connection = sub { return 1; }; - my @events; - my $callbacks = { - 'tracker_callback' => sub { push(@events, $_[0]); }, - }; - my ($dest, $err); - main::complete_http_download({}, \$dest, \$err, $callbacks, undef, - '8.8.8.8', 80, {}, 0, 1, 0); - is_deeply(\@events, [ 1, 2, 4 ], - 'tracker callback receives the existing event sequence'); - @lines = ( - "HTTP/1.0 200 OK\r\n", - "Content-Length: 0\r\n", - "\r\n", - ); - my @legacy_events; - main::complete_http_download({}, \$dest, \$err, - sub { push(@legacy_events, $_[0]); }, - undef, '8.8.8.8', 80, {}, 0, 1, 0); - is_deeply(\@legacy_events, [ 1, 2, 4 ], - '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 = ( - "HTTP/1.0 302 Found\r\n", - "Location: http://127.0.0.1/private\r\n", - "\r\n", - ); - local *main::read_http_connection = sub { return shift(@lines); }; - local *main::close_http_connection = sub { return 1; }; - my ($dest, $err); - my $address_callback = main::get_download_address_callback('public'); - my $callbacks = { 'address_callback' => $address_callback }; - main::complete_http_download({}, \$dest, \$err, $callbacks, undef, - '8.8.8.8', 80, {}, 0, 1, 0); - like($err, qr/non-public IP address 127\.0\.0\.1/, - 'redirect to loopback is blocked before connecting'); -}; - -subtest 'restricted HTTP proxy pins checked address' => sub { - no warnings qw(once redefine); - local %main::gconfig = (http_proxy => 'http://proxy.test:3128'); - local *main::is_readonly_mode = sub { return 0; }; - local *main::no_proxy = sub { return 0; }; - local *main::to_ipaddress = sub { - return $_[0] eq 'origin.test' ? '93.184.216.34' : (); - }; - local *main::to_ip6address = sub { return; }; - my $wire = ''; - local *main::open_socket = sub { - my $name = $_[2]; - no strict 'refs'; - open(*{"main::$name"}, '>', \$wire) || die $!; - return 1; - }; - my $address_callback = main::get_download_address_callback('public'); - my $h = main::make_http_connection( - 'origin.test', 80, 0, 'GET', '/path', - [ [ 'Host', 'origin.test' ] ], undef, undef, - $address_callback); - main::close_http_connection($h); - like($wire, qr{^GET http://93\.184\.216\.34:80/path HTTP/1\.0\r\n}, - 'proxy request targets the policy-checked IP'); - like($wire, qr/Host: origin\.test\r\n/, - 'proxy request preserves the original Host header'); -}; - -subtest 'open_socket destination callback' => sub { - no warnings qw(once redefine); - local *main::to_ipaddress = sub { return '127.0.0.1'; }; - local *main::to_ip6address = sub { return; }; - my $address_callback = main::get_download_address_callback('public'); - my $err; - ok(!main::open_socket('loopback.test', 80, 'TESTSOCK', \$err, - undef, $address_callback), - 'socket connection is rejected by its destination callback'); - like($err, qr/non-public IP address 127\.0\.0\.1/, - 'socket reports the callback rejection'); -}; - -subtest 'restricted FTP proxy pins checked address' => sub { - no warnings qw(once redefine); - local %main::gconfig = (ftp_proxy => 'http://proxy.test:3128'); - local *main::is_readonly_mode = sub { return 0; }; - local *main::no_proxy = sub { return 0; }; - local *main::to_ipaddress = sub { - return $_[0] eq 'origin.test' ? '93.184.216.34' : (); - }; - local *main::to_ip6address = sub { return; }; - my $wire = ''; - local *main::open_socket = sub { - no strict 'refs'; - open(*{'main::SOCK'}, '>', \$wire) || die $!; - return 1; - }; - local *main::complete_http_download = sub { return 1; }; - my $address_callback = main::get_download_address_callback('public'); - my $callbacks = { 'address_callback' => $address_callback }; - my ($dest, $err); - ok(main::ftp_download('origin.test', '/file', \$dest, \$err, $callbacks, - undef, undef, 21), - 'restricted FTP download reaches its proxy'); - like($wire, qr{^GET ftp://93\.184\.216\.34/file HTTP/1\.0\r\n}, - 'FTP proxy request targets the policy-checked IP'); -}; - done_testing(); diff --git a/updown/updown-lib.pl b/updown/updown-lib.pl index 043f5ee57..0d7b6caef 100755 --- a/updown/updown-lib.pl +++ b/updown/updown-lib.pl @@ -138,10 +138,15 @@ if (!$module_info{'usermin'} && $_[0]->{'webmin_user'}) { $address_mode = $download_access{'download_address_mode'} || 'public'; $allowed_addresses = $download_access{'download_allowed_addresses'}; } -my $callbacks = { - 'tracker_callback' => $_[1], - 'address_callback' => &get_download_address_callback( - $address_mode, $allowed_addresses), +my $tracker_callback = $_[1]; +my $address_checker = &get_download_address_callback( + $address_mode, $allowed_addresses); +my $download_callback = sub { + if ($_[0] == 7 && defined($_[1]) && $address_checker) { + my $address_error = &$address_checker(undef, [ $_[1] ]); + &error(&html_escape($address_error)) if ($address_error); + } + &$tracker_callback(@_) if ($tracker_callback); }; for($i=0; $_[0]->{"url_$i"}; $i++) { $error = undef; @@ -169,7 +174,7 @@ for($i=0; $_[0]->{"url_$i"}; $i++) { $_[0]->{"page_$i"}, $path, \$error, - $callbacks, + $download_callback, $_[0]->{"ssl_$i"}, $_[0]->{"user_$i"}, $_[0]->{"pass_$i"}); @@ -179,7 +184,7 @@ for($i=0; $_[0]->{"url_$i"}; $i++) { $_[0]->{"page_$i"}, $path, \$error, - $callbacks, + $download_callback, $_[0]->{"user_$i"}, $_[0]->{"pass_$i"}); } diff --git a/web-lib-funcs.pl b/web-lib-funcs.pl index faa98a30a..e2934913b 100755 --- a/web-lib-funcs.pl +++ b/web-lib-funcs.pl @@ -3349,7 +3349,7 @@ Downloads data from a HTTP url to a local file or string. The parameters are : =item error - If set to a scalar ref, the function will store any error message in this scalar and return 0 on failure, or 1 on success. If not set, it will simply call the error function if the download fails. -=item callback - If set to a function ref, it will be called after each block of data is received. This is typically set to \&progress_callback, for printing download progress. It can also be a hash ref containing tracker_callback and address_callback function refs. The address callback receives the destination hostname and an array ref of resolved IP addresses, and returns an error message to reject the destination or undef to allow it. +=item callback - If set to a function ref, it will be called after each block of data is received. This is typically set to \&progress_callback, for printing download progress. =item sslmode - If set to 1, an HTTPS connection is used instead of HTTP. @@ -3389,13 +3389,6 @@ sub http_download { my ($host, $port, $page, $dest, $error, $cbfunc, $ssl, $user, $pass, $timeout, $osdn, $nocache, $headers, $response_headers) = @_; -my $callbacks = $cbfunc; -my $address_callback; -# Extract known callbacks from an extended callback hash -if (ref($callbacks) eq 'HASH') { - $cbfunc = $callbacks->{'tracker_callback'}; - $address_callback = $callbacks->{'address_callback'}; - } if ($gconfig{'debug_what_net'}) { &webmin_debug_log('HTTP', "host=$host port=$port page=$page ssl=$ssl". ($user ? " user=$user pass=$pass" : ""). @@ -3410,13 +3403,10 @@ if ($osdn) { &convert_osdn_url($prot.$host.$portstr.$page)); } -# Restricted downloads must not share cached responses with unrestricted ones -$nocache = 1 if ($address_callback); - # Check if we already have cached the URL my $url = ($ssl ? "https://" : "http://").$host.":".$port.$page; -my $cfile = !$nocache ? &check_in_http_cache($url) : undef; -if ($cfile) { +my $cfile = &check_in_http_cache($url); +if ($cfile && !$nocache) { # Yes! Copy to dest file or variable &$cbfunc(6, $url) if ($cbfunc); if (ref($dest)) { @@ -3454,8 +3444,7 @@ $main::download_timed_out = undef; local $SIG{ALRM} = \&download_timeout; $timeout = 60 if (!defined($timeout)); alarm($timeout) if ($timeout); -my $h = &make_http_connection($host, $port, $ssl, "GET", $page, \@headers, - undef, undef, $address_callback); +my $h = &make_http_connection($host, $port, $ssl, "GET", $page, \@headers); alarm(0) if ($timeout); $h = $main::download_timed_out if ($main::download_timed_out); if (!ref($h)) { @@ -3464,7 +3453,7 @@ if (!ref($h)) { else { &error(&html_escape($h)); } } &$cbfunc(7, $h->{'ip'}) if ($cbfunc); -&complete_http_download($h, $dest, $error, $callbacks, $osdn, $host, $port, +&complete_http_download($h, $dest, $error, $cbfunc, $osdn, $host, $port, $headers, $ssl, $nocache, $timeout, $response_headers); if ((!$error || !$$error) && !$nocache) { &write_to_http_cache($url, $dest); @@ -3483,11 +3472,6 @@ sub complete_http_download { my ($h, $destfile, $error, $cbfunc, $osdn, $oldhost, $oldport, $headers, $oldssl, $nocache, $timeout, $response_headers) = @_; -my $callbacks = $cbfunc; -# Extract the tracker callback from an extended callback hash -if (ref($callbacks) eq 'HASH') { - $cbfunc = $callbacks->{'tracker_callback'}; - } # Kept local so that callback funcs # can access them. local ($line, %header, @headers, $s); @@ -3561,7 +3545,7 @@ if ($rcode >= 300 && $rcode < 400) { ($page, $params) = split(/\?/, $page); $page =~ s/ /%20/g; $page .= "?".$params if (defined($params)); - &http_download($host, $port, $page, $destfile, $error, $callbacks, $ssl, + &http_download($host, $port, $page, $destfile, $error, $cbfunc, $ssl, undef, undef, undef, $osdn, $nocache, $headers); } else { @@ -3708,7 +3692,7 @@ Download data from an FTP site to a local file. The parameters are : =item error - If set to a string ref, any error message is written into this string and the function returns 0 on failure, 1 on success. Otherwise, error is called on failure. -=item callback - If set to a function ref, it will be called after each block of data is received. This is typically set to \&progress_callback, for printing download progress. It can also be a hash ref containing tracker_callback and address_callback function refs. The address callback receives the destination hostname and an array ref of resolved IP addresses, and returns an error message to reject the destination or undef to allow it. +=item callback - If set to a function ref, it will be called after each block of data is received. This is typically set to \&progress_callback, for printing download progress. =item user - Username to login to the FTP server as. If missing, Webmin will login as anonymous. @@ -3725,13 +3709,6 @@ sub ftp_download { my ($host, $file, $dest, $error, $cbfunc, $user, $pass, $port, $nocache, $timeout) = @_; -my $callbacks = $cbfunc; -my $address_callback; -# Extract known callbacks from an extended callback hash -if (ref($callbacks) eq 'HASH') { - $cbfunc = $callbacks->{'tracker_callback'}; - $address_callback = $callbacks->{'address_callback'}; - } $port ||= 21; $timeout = 60 if (!defined($timeout)); if ($gconfig{'debug_what_net'}) { @@ -3750,13 +3727,10 @@ if (&is_readonly_mode()) { } } -# Restricted downloads must not share cached responses with unrestricted ones -$nocache = 1 if ($address_callback); - # Check if we already have cached the URL my $url = "ftp://".$host.$file; -my $cfile = !$nocache ? &check_in_http_cache($url) : undef; -if ($cfile) { +my $cfile = &check_in_http_cache($url); +if ($cfile && !$nocache) { # Yes! Copy to dest file or variable &$cbfunc(6, $url) if ($cbfunc); if (ref($dest)) { @@ -3777,21 +3751,9 @@ local $SIG{ALRM} = \&download_timeout; alarm($timeout) if ($timeout); my $connected; if ($gconfig{'ftp_proxy'} =~ /^http:\/\/(\S+):(\d+)/ && !&no_proxy($_[0])) { - my ($ftp_proxy_host, $ftp_proxy_port) = ($1, $2); - my $proxy_address = $host; - if ($address_callback) { - my @addresses; - my $address_error = &check_download_address( - $host, $address_callback, \@addresses); - if ($address_error) { - if ($error) { $$error = $address_error; return 0; } - else { &error(&html_escape($address_error)); } - } - $proxy_address = $addresses[0]; - } # download through http-style proxy my $error; - if (&open_socket($ftp_proxy_host, $ftp_proxy_port, "SOCK", \$error)) { + if (&open_socket($1, $2, "SOCK", \$error)) { # Connected OK if ($main::download_timed_out) { alarm(0) if ($timeout); @@ -3806,9 +3768,7 @@ if ($gconfig{'ftp_proxy'} =~ /^http:\/\/(\S+):(\d+)/ && !&no_proxy($_[0])) { my $esc = $file; $esc =~ s/ /%20/g; my $up = "${user}:${pass}\@" if ($user); my $portstr = $port == 21 ? "" : ":$port"; - my $proxy_host = $proxy_address; - $proxy_host = "[$proxy_host]" if (&check_ip6address($proxy_host)); - print SOCK "GET ftp://${up}${proxy_host}${portstr}${esc} HTTP/1.0\r\n"; + print SOCK "GET ftp://${up}${host}${portstr}${esc} HTTP/1.0\r\n"; print SOCK "User-agent: Webmin\r\n"; if ($gconfig{'proxy_user'}) { my $auth = &encode_base64( @@ -3818,9 +3778,8 @@ if ($gconfig{'ftp_proxy'} =~ /^http:\/\/(\S+):(\d+)/ && !&no_proxy($_[0])) { } print SOCK "\r\n"; &complete_http_download( - { 'fh' => "SOCK" }, $dest, $error, $callbacks, - undef, undef, undef, undef, 0, $nocache, - undef, undef); + { 'fh' => "SOCK" }, $dest, $error, $cbfunc, + undef, undef, undef, undef, 0, $nocache); $connected = 1; } elsif (!$gconfig{'proxy_fallback'}) { @@ -3888,8 +3847,7 @@ if (!$connected) { defined($epsv) || return 0; $epsv =~ /\|(\d+)\|/ || return 0; my $epsvport = $1; - &open_socket($host, $epsvport, CON, $error, undef, - $address_callback) || return 0; + &open_socket($host, $epsvport, CON, $error) || return 0; } else { # request the file over a PASV connection @@ -3898,8 +3856,7 @@ if (!$connected) { $pasv =~ /\(([0-9,]+)\)/ || return 0; @n = split(/,/ , $1); &open_socket("$n[0].$n[1].$n[2].$n[3]", - $n[4]*256 + $n[5], "CON", $_[3], undef, - $address_callback) || return 0; + $n[4]*256 + $n[5], "CON", $_[3]) || return 0; } &ftp_command("RETR $file", 1, $error) || return 0; @@ -3933,7 +3890,7 @@ if (!$connected) { close(SOCK); } -&write_to_http_cache($url, $dest) if (!$nocache); +&write_to_http_cache($url, $dest); return 1; } @@ -4075,7 +4032,7 @@ foreach my $n (split(/\s+/, $gconfig{'noproxy'})) { return 0; } -=head2 open_socket(host, port, handle, [&error], [bindip], [&address-callback]) +=head2 open_socket(host, port, handle, [&error]) Open a TCP connection to some host and port, using a file handle. The parameters are : @@ -4090,16 +4047,12 @@ parameters are : =item bindip - Local IP address to bind to for outgoing connections -=item address-callback - Optional function called with the hostname and an -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 { -my ($host, $port, $fh, $err, $bindip, $address_callback) = @_; +my ($host, $port, $fh, $err, $bindip) = @_; $fh = &callers_package($fh); $bindip ||= $gconfig{'bind_proxy'}; @@ -4107,12 +4060,11 @@ if ($gconfig{'debug_what_net'}) { &webmin_debug_log('TCP', "host=$host port=$port"); } -# Resolve and validate the same addresses that will be used for connect(). -my @ips; -my $address_error = &check_download_address( - $host, $address_callback, \@ips); -if ($address_error) { - my $msg = $address_error; +# Lookup all IPv4 and v6 addresses for the host +my @ips = &to_ipaddress($host); +push(@ips, &to_ip6address($host)); +if (!@ips) { + my $msg = "Failed to lookup IP address for $host"; if ($err) { $$err = $msg; return undef; } else { &error($msg); } } @@ -9856,7 +9808,7 @@ return $can_use_http_ssl_cache; } =head2 make_http_connection(host, port, ssl, method, page, [&headers], - [bindip], [&certreqs], [&address-callback]) + [&certreqs]) Opens a connection to some HTTP server, maybe through a proxy, and returns a handle object. The handle can then be used to send additional headers @@ -9880,15 +9832,10 @@ The parameters are : =item certreqs - A hash ref containing options for remote cert verification -=item address-callback - Optional function called with the destination hostname -and an array reference of its resolved IP addresses. It must return an error -message to reject the destination, or undef to allow it. - =cut sub make_http_connection { -my ($host, $port, $ssl, $method, $page, $headers, $bindip, $certreqs, - $address_callback) = @_; +my ($host, $port, $ssl, $method, $page, $headers, $bindip, $certreqs) = @_; my $htxt; if (ref($headers) eq 'ARRAY') { # Headers are name-value pairs @@ -9908,20 +9855,6 @@ if (&is_readonly_mode()) { return "HTTP connections not allowed in readonly mode"; } my $rv = { 'fh' => time().$$ }; -my ($http_proxy_host, $http_proxy_port); -if ($gconfig{'http_proxy'} =~ /^http:\/\/(\S+):(\d+)/ && - !&no_proxy($host)) { - ($http_proxy_host, $http_proxy_port) = ($1, $2); - } -my $proxy_host = $host; -if (defined($http_proxy_host) && $address_callback) { - my @addresses; - my $address_error = &check_download_address( - $host, $address_callback, \@addresses); - return $address_error if ($address_error); - $proxy_host = $addresses[0]; - } -$proxy_host = "[$proxy_host]" if (&check_ip6address($proxy_host)); if ($ssl) { # Connect using SSL &can_use_http_ssl() || return $text{'link_essl'}; @@ -9982,15 +9915,15 @@ if ($ssl) { $rv->{'ssl_con'} = Net::SSLeay::new($rv->{'ssl_ctx'}) || return "Failed to create SSL connection"; my $connected; - if (defined($http_proxy_host)) { + if ($gconfig{'http_proxy'} =~ /^http:\/\/(\S+):(\d+)/ && + !&no_proxy($host)) { # Via proxy my $error; - &open_socket($http_proxy_host, $http_proxy_port, - $rv->{'fh'}, \$error, $bindip); + &open_socket($1, $2, $rv->{'fh'}, \$error, $bindip); if (!$error) { # Connected OK my $fh = $rv->{'fh'}; - print $fh "CONNECT $proxy_host:$port HTTP/1.0\r\n"; + print $fh "CONNECT $host:$port HTTP/1.0\r\n"; if ($gconfig{'proxy_user'}) { my $auth = &encode_base64( "$gconfig{'proxy_user'}:". @@ -10017,8 +9950,7 @@ if ($ssl) { if (!$connected) { # Direct connection my $error; - my $ip = &open_socket($host, $port, $rv->{'fh'}, \$error, $bindip, - $address_callback); + my $ip = &open_socket($host, $port, $rv->{'fh'}, \$error, $bindip); return $error if ($error); $rv->{'ip'} = $ip; } @@ -10044,17 +9976,17 @@ if ($ssl) { else { # Plain HTTP request my $connected; - if (defined($http_proxy_host)) { + if ($gconfig{'http_proxy'} =~ /^http:\/\/(\S+):(\d+)/ && + !&no_proxy($host)) { # Via a proxy my $error; - &open_socket($http_proxy_host, $http_proxy_port, - $rv->{'fh'}, \$error, $bindip); + &open_socket($1, $2, $rv->{'fh'}, \$error, $bindip); if (!$error) { # Connected OK $connected = 1; my $fh = $rv->{'fh'}; my $rtxt = $method." ". - "http://$proxy_host:$port$page HTTP/1.0\r\n"; + "http://$host:$port$page HTTP/1.0\r\n"; if ($gconfig{'proxy_user'}) { my $auth = &encode_base64( "$gconfig{'proxy_user'}:". @@ -10072,8 +10004,7 @@ else { if (!$connected) { # Connecting directly my $error; - my $ip = &open_socket($host, $port, $rv->{'fh'}, \$error, $bindip, - $address_callback); + my $ip = &open_socket($host, $port, $rv->{'fh'}, \$error, $bindip); return $error if ($error); my $fh = $rv->{'fh'}; $rv->{'ip'} = $ip;