use IO::Socket::INET;
use IO::Socket::SSL;
use IO::Select;
use strict;
my $sock = IO::Socket::INET->new(
PeerHost => 'encrypted.google.com', PeerPort => 443, Blocking => 0
) or die $@; # first create simple N-B socket with IO::Socket::INET
my $sel = IO::Select->new($sock); # wait until it connected
if ($sel->can_write) {
print "IO::Socket::INET connected\n";
}
# upgrade socket to IO::Socket::SSL
IO::Socket::SSL->start_SSL($sock, SSL_startHandshake => 0);
# make non-blocking SSL handshake
while (1) {
if ($sock->connect_SSL) { # will not block
print "IO::Socket::SSL connected\n";
last;
}
else { # handshake still incomplete
print "IO::Socket::SSL not connected yet\n";
if ($SSL_ERROR == SSL_WANT_READ) {
$sel->can_read;
}
elsif ($SSL_ERROR == SSL_WANT_WRITE) {
$sel->can_write;
}
else {
die "IO::Socket::SSL unknown error: ", $SSL_ERROR;
}
}
}
# sucessfully connected, we can write to socket
$sock->syswrite(
join(
"\015\012",
"GET / HTTP/1.0",
"\015\012"
)
) or die $!;
# and then read from it
while ($sel->can_read && $sock->sysread(my $buf, 1024)) {
print $buf;
}
$sock->close();
Non-blocking IO::Socket::SSL client example
OSS emulation with ALSA
I faced out with this problem when tried to play Postal 2 on my debian PC. There was no sound and in the console I could see such error:
open /dev/[sound/]dsp: No such file or directory
Google said that aoss from alsa-oss package could help me ... but not on 64 bit system, because Postal 2 is 32 bit app. Ok, 32 bit app should work with 32 bit aoss. And as practice has shown it works. Go to packages.debian.org and download alsa-oss package for i386, then install it with
dpkg -i --force-architecture alsa-oss_VERSION_i386.deb
Now you could start the game with
aoss postal2
Notice: this is ugly hack, good practice says that you should make new amd64 package with 32 bit contents with name different from alsa-oss to avoid conflicts with original alsa-oss package.
PyQt and QImage.scanLine()
import struct;
from PyQt4 import QtGui;
# get QImage object
# ...
#
img = img.convertToFormat(QtGui.QImage.Format_RGB32);
width = img.width();
height = img.height();
linebytes = width * 4;
for y in xrange(0, height):
pixels = img.scanLine(y).asstring(linebytes);
for x in xrange(0, width):
# unpack 32 bit integer
color = struct.unpack('I', pixels[x*4:x*4+4])[0];
# here it is
r = QtGui.qRed(color);
g = QtGui.qGreen(color);
b = QtGui.qBlue(color);
Three ways to work with LWP via socks
LWP::Protocol::socks
This module allows to specify socks for LWP in the same way as you could specify http proxy, which LWP supports out-of-the-box. The problem of this module is that it is only supports socks version 5. But as we can see 4 version is still in use in the real world. To fix this problem I posted a patch on the cpan. Make sure that IO::Socket::Socks 0.2 or higher installed, because only in this version I added support for 4 version of the protocol. May be in the next few years author will accept the patch, but now if you want to use socks 4 you should patch the module yourself.
Here is a simple example of usage:
use LWP;
# You shouldn't say `use LWP::Protocol::socks'
# However you could do it to make sure it is installed
# If it is installed then it will be loaded automatically when needed
# But if it is not then the request will fail
# create lwp object as usual
my $lwp = LWP::UserAgent->new();
# and set socks 5 proxy with host=localhost and port=1080
$lwp->proxy(['http', 'https'], 'socks://localhost:1080');
# use 'socks://login:password@localhost:1080' instead if you
# need authentication
# ...
# thus you could set socks 4 proxy
# if module supports it
$lwp->proxy(['http', 'https'], 'socks4://localhost:1080');
# use 'socks://userid:@localhost:1080' instead if you need
# to specify user id for IDENT
Benefits of using LWP::Protocol::socks
- Easy and logical proxy configuration, in the same way as you usual do it with LWP
- Ability to setup different proxy for different objects
- Authentication with login and password support
- HTTPS support
- Stable and supported IO::Socket::Socks module as backend
Cons of using LWP::Protocol::socks
- No socks4 support out-of-the-box
IO::Socket::Socks::Wrapper
In fact this module allows to get worked via socks any pure perl module. To be more accurate - any connection initiated by perl connect() function. As it uses IO::Socket::Socks as backend it supports both 4 and 5 socks version. This module could be used to wrap any network connection or connections from separate modules. Because we talking about LWP let's wrap it up:
use IO::Socket::Socks::Wrapper (
# wrap classes used by LWP for http and https connections
Net::HTTP => {
ProxyAddr => 'localhost',
ProxyPort => 1080,
SocksVersion => 4
},
Net::HTTPS => { # works since IO::Socket::Socks::Wrapper 0.02
ProxyAddr => 'localhost',
ProxyPort => 1080,
SocksVersion => 4
}
);
use LWP;
# then use LWP as usual
my $lwp = LWP::UserAgent->new();
# all connections will be done via specified socks proxy
my $resp = $lwp->get('http://www.google.com/');
print $resp->status_line, "\n";
$resp = $lwp->get('https://encrypted.google.com/');
print $resp->status_line, "\n";
Benefits of using IO::Socket::Socks::Wrapper
- Universal solution: wrap up any module in the same way
- It supports any options supported by IO::Socket::Socks
Cons of using IO::Socket::Socks::Wrapper
- Global wrapping: you can't specify different proxy for different LWP objects
LWP::Protocol::http::SocksChain
This is extension to LWP::Protocol. It uses Net::SC as backend. From the documentation: Net::SC - perl module for create the chain from the SOCKS/HTTP proxies. So, this extension to the LWP::Protocol also could create connections via socks chain. It supports 4 and 5 socks versions. Let's see an example:
use LWP::Protocol::http::SocksChain;
use LWP::Protocol::https::SocksChain;
use LWP;
# turn on proxy chain
LWP::Protocol::implementor(http => 'LWP::Protocol::http::SocksChain');
LWP::Protocol::implementor(https => 'LWP::Protocol::https::SocksChain');
# setup proxy chain
@LWP::Protocol::http::SocksChain::EXTRA_SOCK_OPTS = (
Chain_Len => 1,
Debug => 0,
# format: host:port:uid:pswd:socks_ver
Chain_File_Data => ['localhost:1080:::5'],
);
@LWP::Protocol::https::SocksChain::EXTRA_SOCK_OPTS = (
Chain_Len => 1,
Debug => 0,
Chain_File_Data => ['localhost:1080:::5'],
);
# then use LWP as usual
my $lwp = LWP::UserAgent->new();
# all connections will be done via specified socks proxy
# ...
Benefits of using LWP::Protocol::http::SocksChain
- Allows to create connections via socks chain
Cons of using LWP::Protocol::http::SocksChain
- Looks like ugly hack
Conclusion:
All of this three modules have roughly equal opportunities. All three supports socks 5 and 4 version (first with a patch) and authorization with login and password. The first two uses IO::Socket::Socks as backend, third uses own backend, called Net::SC.
LWP::Protocol::socks is the most simple and logical way to include socks support in the LWP. IO::Socket::Socks::Wrapper is the most universal solution if you need to include socks support everywhere. LWP::Protocol::http::SocksChain is unique solution for creating connections via socks chains.
Read original modules documentation to get more information.