9254
9268
use warnings FATAL => 'all';
9255
9269
use English qw(-no_match_vars);
9256
9271
use constant PTDEBUG => $ENV{PTDEBUG} || 0;
9258
9273
use POSIX qw(setsid);
9274
use Fcntl qw(:DEFAULT);
9261
my ( $class, %args ) = @_;
9262
foreach my $arg ( qw(o) ) {
9263
die "I need a $arg argument" unless $args{$arg};
9277
my ($class, %args) = @_;
9268
log_file => $o->has('log') ? $o->get('log') : undef,
9269
PID_file => $o->has('pid') ? $o->get('pid') : undef,
9279
log_file => $args{log_file},
9280
pid_file => $args{pid_file},
9281
daemonize => $args{daemonize},
9282
force_log_file => $args{force_log_file},
9283
parent_exit => $args{parent_exit},
9284
pid_file_owner => 0,
9272
check_PID_file(undef, $self->{PID_file});
9274
PTDEBUG && _d('Daemonized child will log to', $self->{log_file});
9275
9286
return bless $self, $class;
9281
PTDEBUG && _d('About to fork and daemonize');
9282
defined (my $pid = fork()) or die "Cannot fork: $OS_ERROR";
9284
PTDEBUG && _d('Parent PID', $PID, 'exiting after forking child PID',$pid);
9288
PTDEBUG && _d('Daemonizing child PID', $PID);
9289
$self->{PID_owner} = $PID;
9292
POSIX::setsid() or die "Cannot start a new session: $OS_ERROR";
9293
chdir '/' or die "Cannot chdir to /: $OS_ERROR";
9295
$self->_make_PID_file();
9297
$OUTPUT_AUTOFLUSH = 1;
9299
PTDEBUG && _d('Redirecting STDIN to /dev/null');
9301
open STDIN, '/dev/null'
9302
or die "Cannot reopen STDIN to /dev/null: $OS_ERROR";
9304
if ( $self->{log_file} ) {
9305
PTDEBUG && _d('Redirecting STDOUT and STDERR to', $self->{log_file});
9307
open STDOUT, '>>', $self->{log_file}
9308
or die "Cannot open log file $self->{log_file}: $OS_ERROR";
9311
open STDERR, ">&STDOUT"
9312
or die "Cannot dupe STDERR to STDOUT: $OS_ERROR";
9316
PTDEBUG && _d('No log file and STDOUT is a terminal;',
9317
'redirecting to /dev/null');
9292
my $daemonize = $self->{daemonize};
9293
my $pid_file = $self->{pid_file};
9294
my $log_file = $self->{log_file};
9295
my $force_log_file = $self->{force_log_file};
9296
my $parent_exit = $self->{parent_exit};
9298
PTDEBUG && _d('Starting daemon');
9302
$self->_make_pid_file(
9303
pid => $PID, # parent's pid
9304
pid_file => $pid_file,
9307
die "$EVAL_ERROR\n" if $EVAL_ERROR;
9308
if ( !$daemonize ) {
9309
$self->{pid_file_owner} = $PID; # parent's pid
9314
defined (my $child_pid = fork()) or die "Cannot fork: $OS_ERROR";
9316
PTDEBUG && _d('Forked child', $child_pid);
9317
$parent_exit->($child_pid) if $parent_exit;
9321
POSIX::setsid() or die "Cannot start a new session: $OS_ERROR";
9322
chdir '/' or die "Cannot chdir to /: $OS_ERROR";
9325
$self->_update_pid_file(
9326
pid => $PID, # child's pid
9327
pid_file => $pid_file,
9329
$self->{pid_file_owner} = $PID;
9333
if ( $daemonize || $force_log_file ) {
9334
PTDEBUG && _d('Redirecting STDIN to /dev/null');
9336
open STDIN, '/dev/null'
9337
or die "Cannot reopen STDIN to /dev/null: $OS_ERROR";
9339
PTDEBUG && _d('Redirecting STDOUT and STDERR to', $log_file);
9319
open STDOUT, '>', '/dev/null'
9320
or die "Cannot reopen STDOUT to /dev/null: $OS_ERROR";
9323
PTDEBUG && _d('No log file and STDERR is a terminal;',
9324
'redirecting to /dev/null');
9341
open STDOUT, '>>', $log_file
9342
or die "Cannot open log file $log_file: $OS_ERROR";
9326
open STDERR, '>', '/dev/null'
9327
or die "Cannot reopen STDERR to /dev/null: $OS_ERROR";
9334
sub check_PID_file {
9335
my ( $self, $file ) = @_;
9336
my $PID_file = $self ? $self->{PID_file} : $file;
9337
PTDEBUG && _d('Checking PID file', $PID_file);
9338
if ( $PID_file && -f $PID_file ) {
9341
chomp($pid = (slurp_file($PID_file) || ''));
9343
if ( $EVAL_ERROR ) {
9344
die "The PID file $PID_file already exists but it cannot be read: "
9347
PTDEBUG && _d('PID file exists; it contains PID', $pid);
9349
my $pid_is_alive = kill 0, $pid;
9345
open STDERR, ">&STDOUT"
9346
or die "Cannot dupe STDERR to STDOUT: $OS_ERROR";
9350
PTDEBUG && _d('No log file and STDOUT is a terminal;',
9351
'redirecting to /dev/null');
9353
open STDOUT, '>', '/dev/null'
9354
or die "Cannot reopen STDOUT to /dev/null: $OS_ERROR";
9357
PTDEBUG && _d('No log file and STDERR is a terminal;',
9358
'redirecting to /dev/null');
9360
open STDERR, '>', '/dev/null'
9361
or die "Cannot reopen STDERR to /dev/null: $OS_ERROR";
9365
$OUTPUT_AUTOFLUSH = 1;
9368
PTDEBUG && _d('Daemon running');
9372
sub _make_pid_file {
9373
my ($self, %args) = @_;
9374
my @required_args = qw(pid pid_file);
9375
foreach my $arg ( @required_args ) {
9376
die "I need a $arg argument" unless $args{$arg};
9378
my $pid = $args{pid};
9379
my $pid_file = $args{pid_file};
9382
sysopen(PID_FH, $pid_file, O_RDWR|O_CREAT|O_EXCL) or die $OS_ERROR;
9383
print PID_FH $PID, "\n";
9386
if ( my $e = $EVAL_ERROR ) {
9387
if ( $e =~ m/file exists/i ) {
9388
my $old_pid = $self->_check_pid_file(
9389
pid_file => $pid_file,
9393
warn "Overwriting PID file $pid_file because PID $old_pid "
9394
. "is not running.\n";
9396
$self->_update_pid_file(
9398
pid_file => $pid_file
9402
die "Error creating PID file $pid_file: $e\n";
9409
sub _check_pid_file {
9410
my ($self, %args) = @_;
9411
my @required_args = qw(pid_file pid);
9412
foreach my $arg ( @required_args ) {
9413
die "I need a $arg argument" unless $args{$arg};
9415
my $pid_file = $args{pid_file};
9416
my $pid = $args{pid};
9418
PTDEBUG && _d('Checking if PID in', $pid_file, 'is running');
9420
if ( ! -f $pid_file ) {
9421
PTDEBUG && _d('PID file', $pid_file, 'does not exist');
9425
open my $fh, '<', $pid_file
9426
or die "Error opening $pid_file: $OS_ERROR";
9427
my $existing_pid = do { local $/; <$fh> };
9428
chomp($existing_pid) if $existing_pid;
9430
or die "Error closing $pid_file: $OS_ERROR";
9432
if ( $existing_pid ) {
9433
if ( $existing_pid == $pid ) {
9434
warn "The current PID $pid already holds the PID file $pid_file\n";
9438
PTDEBUG && _d('Checking if PID', $existing_pid, 'is running');
9439
my $pid_is_alive = kill 0, $existing_pid;
9350
9440
if ( $pid_is_alive ) {
9351
die "The PID file $PID_file already exists "
9352
. " and the PID that it contains, $pid, is running";
9355
warn "Overwriting PID file $PID_file because the PID that it "
9356
. "contains, $pid, is not running";
9360
die "The PID file $PID_file already exists but it does not "
9441
die "PID file $pid_file exists and PID $existing_pid is running\n";
9365
PTDEBUG && _d('No PID file');
9372
if ( exists $self->{child} ) {
9373
die "Do not call Daemon::make_PID_file() for daemonized scripts";
9375
$self->_make_PID_file();
9376
$self->{PID_owner} = $PID;
9380
sub _make_PID_file {
9383
my $PID_file = $self->{PID_file};
9385
PTDEBUG && _d('No PID file to create');
9389
$self->check_PID_file();
9391
open my $PID_FH, '>', $PID_file
9392
or die "Cannot open PID file $PID_file: $OS_ERROR";
9394
or die "Cannot print to PID file $PID_file: $OS_ERROR";
9396
or die "Cannot close PID file $PID_file: $OS_ERROR";
9398
PTDEBUG && _d('Created PID file:', $self->{PID_file});
9402
sub _remove_PID_file {
9404
if ( $self->{PID_file} && -f $self->{PID_file} ) {
9405
unlink $self->{PID_file}
9406
or warn "Cannot remove PID file $self->{PID_file}: $OS_ERROR";
9446
die "PID file $pid_file exists but it is empty. Remove the file "
9447
. "if the process is no longer running.\n";
9450
return $existing_pid;
9453
sub _update_pid_file {
9454
my ($self, %args) = @_;
9455
my @required_args = qw(pid pid_file);
9456
foreach my $arg ( @required_args ) {
9457
die "I need a $arg argument" unless $args{$arg};
9459
my $pid = $args{pid};
9460
my $pid_file = $args{pid_file};
9462
open my $fh, '>', $pid_file
9463
or die "Cannot open $pid_file: $OS_ERROR";
9464
print { $fh } $pid, "\n"
9465
or die "Cannot print to $pid_file: $OS_ERROR";
9467
or warn "Cannot close $pid_file: $OS_ERROR";
9472
sub remove_pid_file {
9473
my ($self, $pid_file) = @_;
9474
$pid_file ||= $self->{pid_file};
9475
if ( $pid_file && -f $pid_file ) {
9476
unlink $self->{pid_file}
9477
or warn "Cannot remove PID file $pid_file: $OS_ERROR";
9407
9478
PTDEBUG && _d('Removed PID file');
11633
11697
return ($scheme, $host, $port, $path_query);
11637
HTTPMicro::Handle; # hide from PAUSE/indexers
11641
use Carp qw[croak];
11642
use Errno qw[EINTR EPIPE];
11643
use IO::Socket qw[SOCK_STREAM];
11645
sub BUFSIZE () { 32768 }
11647
my $Printable = sub {
11652
s/([^\x20-\x7E])/sprintf('\\x%.2X', ord($1))/ge;
11657
my ($class, %args) = @_;
11661
max_line_size => 16384,
11666
my $ssl_verify_args = {
11667
check_cn => "when_only",
11668
wildcards_in_alt => "anywhere",
11669
wildcards_in_cn => "anywhere"
11673
@_ == 4 || croak(q/Usage: $handle->connect(scheme, host, port)/);
11674
my ($self, $scheme, $host, $port) = @_;
11676
if ( $scheme eq 'https' ) {
11677
eval "require IO::Socket::SSL"
11678
unless exists $INC{'IO/Socket/SSL.pm'};
11679
croak(qq/IO::Socket::SSL must be installed for https support\n/)
11680
unless $INC{'IO/Socket/SSL.pm'};
11682
elsif ( $scheme ne 'http' ) {
11683
croak(qq/Unsupported URL scheme '$scheme'\n/);
11686
$self->{fh} = 'IO::Socket::INET'->new(
11690
Type => SOCK_STREAM,
11691
Timeout => $self->{timeout}
11692
) or croak(qq/Could not connect to '$host:$port': $@/);
11694
binmode($self->{fh})
11695
or croak(qq/Could not binmode() socket: '$!'/);
11697
if ( $scheme eq 'https') {
11698
IO::Socket::SSL->start_SSL($self->{fh});
11699
ref($self->{fh}) eq 'IO::Socket::SSL'
11700
or die(qq/SSL connection failed for $host\n/);
11701
if ( $self->{fh}->can("verify_hostname") ) {
11702
$self->{fh}->verify_hostname( $host, $ssl_verify_args );
11705
my $fh = $self->{fh};
11706
_verify_hostname_of_cert($host, _peer_certificate($fh), $ssl_verify_args)
11707
or die(qq/SSL certificate not valid for $host\n/);
11711
$self->{host} = $host;
11712
$self->{port} = $port;
11718
@_ == 1 || croak(q/Usage: $handle->close()/);
11720
CORE::close($self->{fh})
11721
or croak(qq/Could not close socket: '$!'/);
11725
@_ == 2 || croak(q/Usage: $handle->write(buf)/);
11726
my ($self, $buf) = @_;
11728
my $len = length $buf;
11731
local $SIG{PIPE} = 'IGNORE';
11735
or croak(q/Timed out while waiting for socket to become ready for writing/);
11736
my $r = syswrite($self->{fh}, $buf, $len, $off);
11740
last unless $len > 0;
11742
elsif ($! == EPIPE) {
11743
croak(qq/Socket closed by remote server: $!/);
11745
elsif ($! != EINTR) {
11746
croak(qq/Could not write to socket: '$!'/);
11753
@_ == 2 || @_ == 3 || croak(q/Usage: $handle->read(len)/);
11754
my ($self, $len) = @_;
11757
my $got = length $self->{rbuf};
11760
my $take = ($got < $len) ? $got : $len;
11761
$buf = substr($self->{rbuf}, 0, $take, '');
11767
or croak(q/Timed out while waiting for socket to become ready for reading/);
11768
my $r = sysread($self->{fh}, $buf, $len, length $buf);
11773
elsif ($! != EINTR) {
11774
croak(qq/Could not read from socket: '$!'/);
11778
croak(q/Unexpected end of stream/);
11784
@_ == 1 || croak(q/Usage: $handle->readline()/);
11788
if ($self->{rbuf} =~ s/\A ([^\x0D\x0A]* \x0D?\x0A)//x) {
11792
or croak(q/Timed out while waiting for socket to become ready for reading/);
11793
my $r = sysread($self->{fh}, $self->{rbuf}, BUFSIZE, length $self->{rbuf});
11797
elsif ($! != EINTR) {
11798
croak(qq/Could not read from socket: '$!'/);
11801
croak(q/Unexpected end of stream while looking for line/);
11804
sub read_header_lines {
11805
@_ == 1 || @_ == 2 || croak(q/Usage: $handle->read_header_lines([headers])/);
11806
my ($self, $headers) = @_;
11812
my $line = $self->readline;
11814
if ($line =~ /\A ([^\x00-\x1F\x7F:]+) : [\x09\x20]* ([^\x0D\x0A]*)/x) {
11815
my ($field_name) = lc $1;
11816
$val = \($headers->{$field_name} = $2);
11818
elsif ($line =~ /\A [\x09\x20]+ ([^\x0D\x0A]*)/x) {
11820
or croak(q/Unexpected header continuation line/);
11821
next unless length $1;
11822
$$val .= ' ' if length $$val;
11825
elsif ($line =~ /\A \x0D?\x0A \z/x) {
11829
croak(q/Malformed header line: / . $Printable->($line));
11835
sub write_header_lines {
11836
(@_ == 2 && ref $_[1] eq 'HASH') || croak(q/Usage: $handle->write_header_lines(headers)/);
11837
my($self, $headers) = @_;
11840
while (my ($k, $v) = each %$headers) {
11841
my $field_name = lc $k;
11842
$field_name =~ /\A [\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7A\x7C\x7E]+ \z/x
11843
or croak(q/Invalid HTTP header field name: / . $Printable->($field_name));
11844
$field_name =~ s/\b(\w)/\u$1/g;
11845
$buf .= "$field_name: $v\x0D\x0A";
11847
$buf .= "\x0D\x0A";
11848
return $self->write($buf);
11851
sub read_content_body {
11852
@_ == 3 || @_ == 4 || croak(q/Usage: $handle->read_content_body(callback, response, [read_length])/);
11853
my ($self, $cb, $response, $len) = @_;
11854
$len ||= $response->{headers}{'content-length'};
11856
croak("No content-length in the returned response, and this "
11857
. "UA doesn't implement chunking") unless defined $len;
11860
my $read = ($len > BUFSIZE) ? BUFSIZE : $len;
11861
$cb->($self->read($read), $response);
11868
sub write_content_body {
11869
@_ == 2 || croak(q/Usage: $handle->write_content_body(request)/);
11870
my ($self, $request) = @_;
11871
my ($len, $content_length) = (0, $request->{headers}{'content-length'});
11873
$len += $self->write($request->{content});
11875
$len == $content_length
11876
or croak(qq/Content-Length missmatch (got: $len expected: $content_length)/);
11881
sub read_response_header {
11882
@_ == 1 || croak(q/Usage: $handle->read_response_header()/);
11885
my $line = $self->readline;
11887
$line =~ /\A (HTTP\/(0*\d+\.0*\d+)) [\x09\x20]+ ([0-9]{3}) [\x09\x20]+ ([^\x0D\x0A]*) \x0D?\x0A/x
11888
or croak(q/Malformed Status-Line: / . $Printable->($line));
11890
my ($protocol, $version, $status, $reason) = ($1, $2, $3, $4);
11895
headers => $self->read_header_lines,
11896
protocol => $protocol,
11900
sub write_request_header {
11901
@_ == 4 || croak(q/Usage: $handle->write_request_header(method, request_uri, headers)/);
11902
my ($self, $method, $request_uri, $headers) = @_;
11904
return $self->write("$method $request_uri HTTP/1.1\x0D\x0A")
11905
+ $self->write_header_lines($headers);
11909
my ($self, $type, $timeout) = @_;
11910
$timeout = $self->{timeout}
11911
unless defined $timeout && $timeout >= 0;
11913
my $fd = fileno $self->{fh};
11914
defined $fd && $fd >= 0
11915
or croak(q/select(2): 'Bad file descriptor'/);
11917
my $initial = time;
11918
my $pending = $timeout;
11921
vec(my $fdset = '', $fd, 1) = 1;
11924
$nfound = ($type eq 'read')
11925
? select($fdset, undef, undef, $pending)
11926
: select(undef, $fdset, undef, $pending) ;
11927
if ($nfound == -1) {
11929
or croak(qq/select(2): '$!'/);
11930
redo if !$timeout || ($pending = $timeout - (time - $initial)) > 0;
11940
@_ == 1 || @_ == 2 || croak(q/Usage: $handle->can_read([timeout])/);
11942
return $self->_do_timeout('read', @_)
11946
@_ == 1 || @_ == 2 || croak(q/Usage: $handle->can_write([timeout])/);
11948
return $self->_do_timeout('write', @_)
11703
package HTTP::Micro::Handle;
11706
use warnings FATAL => 'all';
11707
use English qw(-no_match_vars);
11709
use Carp qw(croak);
11710
use Errno qw(EINTR EPIPE);
11711
use IO::Socket qw(SOCK_STREAM);
11713
sub BUFSIZE () { 32768 }
11715
my $Printable = sub {
11720
s/([^\x20-\x7E])/sprintf('\\x%.2X', ord($1))/ge;
11725
my ($class, %args) = @_;
11729
max_line_size => 16384,
11734
my $ssl_verify_args = {
11735
check_cn => "when_only",
11736
wildcards_in_alt => "anywhere",
11737
wildcards_in_cn => "anywhere"
11741
@_ == 4 || croak(q/Usage: $handle->connect(scheme, host, port)/);
11742
my ($self, $scheme, $host, $port) = @_;
11744
if ( $scheme eq 'https' ) {
11745
eval "require IO::Socket::SSL"
11746
unless exists $INC{'IO/Socket/SSL.pm'};
11747
croak(qq/IO::Socket::SSL must be installed for https support\n/)
11748
unless $INC{'IO/Socket/SSL.pm'};
11750
elsif ( $scheme ne 'http' ) {
11751
croak(qq/Unsupported URL scheme '$scheme'\n/);
11754
$self->{fh} = IO::Socket::INET->new(
11758
Type => SOCK_STREAM,
11759
Timeout => $self->{timeout}
11760
) or croak(qq/Could not connect to '$host:$port': $@/);
11762
binmode($self->{fh})
11763
or croak(qq/Could not binmode() socket: '$!'/);
11765
if ( $scheme eq 'https') {
11766
IO::Socket::SSL->start_SSL($self->{fh});
11767
ref($self->{fh}) eq 'IO::Socket::SSL'
11768
or die(qq/SSL connection failed for $host\n/);
11769
if ( $self->{fh}->can("verify_hostname") ) {
11770
$self->{fh}->verify_hostname( $host, $ssl_verify_args );
11773
my $fh = $self->{fh};
11774
_verify_hostname_of_cert($host, _peer_certificate($fh), $ssl_verify_args)
11775
or die(qq/SSL certificate not valid for $host\n/);
11779
$self->{host} = $host;
11780
$self->{port} = $port;
11786
@_ == 1 || croak(q/Usage: $handle->close()/);
11788
CORE::close($self->{fh})
11789
or croak(qq/Could not close socket: '$!'/);
11793
@_ == 2 || croak(q/Usage: $handle->write(buf)/);
11794
my ($self, $buf) = @_;
11796
my $len = length $buf;
11799
local $SIG{PIPE} = 'IGNORE';
11803
or croak(q/Timed out while waiting for socket to become ready for writing/);
11804
my $r = syswrite($self->{fh}, $buf, $len, $off);
11808
last unless $len > 0;
11810
elsif ($! == EPIPE) {
11811
croak(qq/Socket closed by remote server: $!/);
11813
elsif ($! != EINTR) {
11814
croak(qq/Could not write to socket: '$!'/);
11821
@_ == 2 || @_ == 3 || croak(q/Usage: $handle->read(len)/);
11822
my ($self, $len) = @_;
11825
my $got = length $self->{rbuf};
11828
my $take = ($got < $len) ? $got : $len;
11829
$buf = substr($self->{rbuf}, 0, $take, '');
11835
or croak(q/Timed out while waiting for socket to become ready for reading/);
11836
my $r = sysread($self->{fh}, $buf, $len, length $buf);
11841
elsif ($! != EINTR) {
11842
croak(qq/Could not read from socket: '$!'/);
11846
croak(q/Unexpected end of stream/);
11852
@_ == 1 || croak(q/Usage: $handle->readline()/);
11856
if ($self->{rbuf} =~ s/\A ([^\x0D\x0A]* \x0D?\x0A)//x) {
11860
or croak(q/Timed out while waiting for socket to become ready for reading/);
11861
my $r = sysread($self->{fh}, $self->{rbuf}, BUFSIZE, length $self->{rbuf});
11865
elsif ($! != EINTR) {
11866
croak(qq/Could not read from socket: '$!'/);
11869
croak(q/Unexpected end of stream while looking for line/);
11872
sub read_header_lines {
11873
@_ == 1 || @_ == 2 || croak(q/Usage: $handle->read_header_lines([headers])/);
11874
my ($self, $headers) = @_;
11880
my $line = $self->readline;
11882
if ($line =~ /\A ([^\x00-\x1F\x7F:]+) : [\x09\x20]* ([^\x0D\x0A]*)/x) {
11883
my ($field_name) = lc $1;
11884
$val = \($headers->{$field_name} = $2);
11886
elsif ($line =~ /\A [\x09\x20]+ ([^\x0D\x0A]*)/x) {
11888
or croak(q/Unexpected header continuation line/);
11889
next unless length $1;
11890
$$val .= ' ' if length $$val;
11893
elsif ($line =~ /\A \x0D?\x0A \z/x) {
11897
croak(q/Malformed header line: / . $Printable->($line));
11903
sub write_header_lines {
11904
(@_ == 2 && ref $_[1] eq 'HASH') || croak(q/Usage: $handle->write_header_lines(headers)/);
11905
my($self, $headers) = @_;
11908
while (my ($k, $v) = each %$headers) {
11909
my $field_name = lc $k;
11910
$field_name =~ /\A [\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7A\x7C\x7E]+ \z/x
11911
or croak(q/Invalid HTTP header field name: / . $Printable->($field_name));
11912
$field_name =~ s/\b(\w)/\u$1/g;
11913
$buf .= "$field_name: $v\x0D\x0A";
11915
$buf .= "\x0D\x0A";
11916
return $self->write($buf);
11919
sub read_content_body {
11920
@_ == 3 || @_ == 4 || croak(q/Usage: $handle->read_content_body(callback, response, [read_length])/);
11921
my ($self, $cb, $response, $len) = @_;
11922
$len ||= $response->{headers}{'content-length'};
11924
croak("No content-length in the returned response, and this "
11925
. "UA doesn't implement chunking") unless defined $len;
11928
my $read = ($len > BUFSIZE) ? BUFSIZE : $len;
11929
$cb->($self->read($read), $response);
11936
sub write_content_body {
11937
@_ == 2 || croak(q/Usage: $handle->write_content_body(request)/);
11938
my ($self, $request) = @_;
11939
my ($len, $content_length) = (0, $request->{headers}{'content-length'});
11941
$len += $self->write($request->{content});
11943
$len == $content_length
11944
or croak(qq/Content-Length missmatch (got: $len expected: $content_length)/);
11949
sub read_response_header {
11950
@_ == 1 || croak(q/Usage: $handle->read_response_header()/);
11953
my $line = $self->readline;
11955
$line =~ /\A (HTTP\/(0*\d+\.0*\d+)) [\x09\x20]+ ([0-9]{3}) [\x09\x20]+ ([^\x0D\x0A]*) \x0D?\x0A/x
11956
or croak(q/Malformed Status-Line: / . $Printable->($line));
11958
my ($protocol, $version, $status, $reason) = ($1, $2, $3, $4);
11963
headers => $self->read_header_lines,
11964
protocol => $protocol,
11968
sub write_request_header {
11969
@_ == 4 || croak(q/Usage: $handle->write_request_header(method, request_uri, headers)/);
11970
my ($self, $method, $request_uri, $headers) = @_;
11972
return $self->write("$method $request_uri HTTP/1.1\x0D\x0A")
11973
+ $self->write_header_lines($headers);
11977
my ($self, $type, $timeout) = @_;
11978
$timeout = $self->{timeout}
11979
unless defined $timeout && $timeout >= 0;
11981
my $fd = fileno $self->{fh};
11982
defined $fd && $fd >= 0
11983
or croak(q/select(2): 'Bad file descriptor'/);
11985
my $initial = time;
11986
my $pending = $timeout;
11989
vec(my $fdset = '', $fd, 1) = 1;
11992
$nfound = ($type eq 'read')
11993
? select($fdset, undef, undef, $pending)
11994
: select(undef, $fdset, undef, $pending) ;
11995
if ($nfound == -1) {
11997
or croak(qq/select(2): '$!'/);
11998
redo if !$timeout || ($pending = $timeout - (time - $initial)) > 0;
12008
@_ == 1 || @_ == 2 || croak(q/Usage: $handle->can_read([timeout])/);
12010
return $self->_do_timeout('read', @_)
12014
@_ == 1 || @_ == 2 || croak(q/Usage: $handle->can_write([timeout])/);
12016
return $self->_do_timeout('write', @_)
12018
} # HTTP::Micro::Handle
11951
12020
my $prog = <<'EOP';