IO::Socket::Socks::Wrapper - Allow any perl package to work through a socks proxy
# wrap Net::FTP and Net::HTTP only use IO::Socket::Socks::Wrapper ( Net::FTP => { # also specify `Net::FTP::dataconn' to wrap data connection ProxyAddr => '10.0.0.1', ProxyPort => 1080, SocksDebug => 1, Timeout => 15 }, Net::HTTP => { ProxyAddr => '10.0.0.2', ProxyPort => 1080, SocksVersion => 4, SocksDebug => 1, Timeout => 15 } ); 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});
# wrap all connections 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 do not have separate modules # LWP::Protocol::http and LWP::Protocol::https modules includes this packages respectively # IO::Socket::Socks::Wrapper should has 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, Timeout => 15 }, LWP::Protocol::https::Socket => { ProxyAddr => 'localhost', ProxyPort => 1080, SocksDebug => 1, Timeout => 15 } ); 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
# the way to wrap package that is not inherited from IO::Socket # but uses IO::Socket object as internal socket handle use HTTP::Tiny; # HTTP::Tiny::Handle package is in HTTP::Tiny module use IO::Socket::Socks::Wrapper ( # HTTP::Tiny::Handle::connect sub invokes IO::Socket::INET->new # see HTTP::Tiny sourse code 'HTTP::Tiny::Handle::connect()' => { # parentheses required ProxyAddr => 'localhost', ProxyPort => 1080, SocksVersion => 4, Timeout => 15 } ); # via socks my $page = HTTP::Tiny->new->get('http://www.google.com/')->{content}; # disable wrapping for HTTP::Tiny IO::Socket::Socks::Wrapper->import('HTTP::Tiny::Handle::connect()' => 0); # and get page without socks $page = HTTP::Tiny->new->get('http://www.google.com/')->{content};
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, or by overriding IO::Socket::connect() function in the package.
IO::Socket::Socks::Wrapper
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 the packages that was loaded before calling IO::Socket::Socks::Wrapper->import(). So, for this purposes `use IO::Socket::Socks::Wrapper' with $hashref argument should be before any other `use' statements.
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 wrapping $hashref could be scalar with false value.
Examples are: Net::FTP, Net::POP3, Net::HTTP
'pkg' => $hashref
Where pkg is a package name that 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 $hashref description see above.
Examples are: HTTP::Tiny (HTTP::Tiny::Handle::connect)
'pkg::sub()' => $hashref
Where sub is a name of subroutine contains IO::Socket object creation/connection. Parentheses required. For pkg and $hashref description see above.
Default timeout for wrapped connect is 180 sec. You can specify your own value using Timeout option. Set it to zero if you don't want to limit connection attempt time.
Timeout
Wrapping doesn't work with impure perl packages. WWW::Curl for example.
IO::Socket::Socks
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.
To install IO::Socket::Socks::Wrapper, copy and paste the appropriate command in to your terminal.
cpanm
cpanm IO::Socket::Socks::Wrapper
CPAN shell
perl -MCPAN -e shell install IO::Socket::Socks::Wrapper
For more information on module installation, please visit the detailed CPAN module installation guide.