The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

IO::Socket::Socks::Wrapper - Allow any perl package to work through a socks proxy

SYNOPSIS

            # only Net::FTP and Net::HTTP
            use IO::Socket::Socks::Wrapper (
                    Net::FTP => { # use also `Net::FTP::dataconn' to wrap data connection
                            ProxyAddr => '10.0.0.1',
                            ProxyPort => 1080,
                            SocksDebug => 1
                    },
                    Net::HTTP => {
                            ProxyAddr => '10.0.0.2',
                            ProxyPort => 1080,
                            SocksVersion => 4,
                            SocksDebug => 1
                    }
            );
            use Net::FTP;
            use Net::POP3;
            use LWP;
            use strict;
            
            my $ftp = Net::FTP->new();       # via socks5://10.0.0.1:1080
            my $lwp = LWP::UserAgent->new(); # via socks4://10.0.0.2:1080
            my $pop = Net::POP3->new();      # direct network access
            
            ...
            
            # change proxy for Net::FTP
            IO::Socket::Socks::Wrapper->import(Net::FTP:: => {ProxyAddr => '10.0.0.3', ProxyPort => 1080});
            # all modules
            use IO::Socket::Socks::Wrapper ( # should be before any other `use'
                    {
                            ProxyAddr => 'localhost',
                            ProxyPort => 1080,
                            SocksDebug => 1,
                            Timeout => 10
                    }
            );
            
            # except Net::FTP
            IO::Socket::Socks::Wrapper->import(Net::FTP:: => 0); # direct network access
            # more direct LWP::UserAgent wrapping
            
            # we need to associate LWP::Protocol::http::Socket and LWP::Protocol::https::Socket packages
            # with socks proxy
            # this packages haven't separate modules
            # LWP::Protocol::http and LWP::Protocol::https modules includes this packages respectively
            # IO::Socket::Socks::Wrapper should have access to @ISA of each package which want to be wrapped
            # when package == module it can load packages automatically and do its magic with @ISA
            # but in the case like this loading will fail
            # so, we should load this modules manually
            use LWP::Protocol::http;
            use LWP::Protocol::https;
            use IO::Socket::Socks::Wrapper (
                    LWP::Protocol::http::Socket => {
                            ProxyAddr => 'localhost',
                            ProxyPort => 1080,
                            SocksDebug => 1
                    },
                    LWP::Protocol::https::Socket => {
                            ProxyAddr => 'localhost',
                            ProxyPort => 1080,
                            SocksDebug => 1
                    }
            );
            use LWP;
            
            # then use lwp as usual
            my $ua = LWP::UserAgent->new();
            
            # in this case Net::HTTP and Net::HTTPS objects will use direct network access
            # but LWP::UserAgent objects will use socks proxy

DESCRIPTION

IO::Socket::Socks::Wrapper allows to wrap up the network connections into socks proxy. It can wrap up connection from separate packages or any network connection. It works by overriding builtin connect() function in the package or globally.

METHODS

import( CFG )

import() is invoked when IO::Socket::Socks::Wrapper loaded by `use' command. Later it can be invoked manually to change proxy in some package. Global overriding will not work in packages which was loaded before calling IO::Socket::Socks::Wrapper->import(). So, for this purposes `use IO::Socket::Socks::Wrapper' should be before any other `use' statements.

CFG syntax to wrap up separate packages is:

        pkg => $hashref,
        ...
        pkg => $hashref

pkg is a package which is responsible for connections. For example if you want to wrap LWP http connections, then module name should be Net::HTTP, for https connections it should be Net::HTTPS or even LWP::Protocol::http::Socket and LWP::Protocol::https::Socket respectively (see examples above). You really need to look at the source code of the package which you want to wrap to determine the name for wrapping or use global wrapping which will wrap all that can. Use `SocksDebug' to verify that wrapping works good.

For the global wrapping only $hashref should be specified.

$hashref is a reference to a hash with key/value pairs same as IO::Socket::Socks constructor options, but without (Connect|Bind|Udp)Addr and (Connect|Bind|Udp)Port. To disable of using proxy $hashref could be scalar with false value.

BUGS

Wrapping doesn't work with impure perl packages. WWW::Curl for example.

SEE ALSO

IO::Socket::Socks

COPYRIGHT

Oleg G <oleg@cpan.org>.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.