use IO::File qw[SEEK_SET];
use Symbol qw[];
-__PACKAGE__->mk_accessors( qw[ is_setuped
+__PACKAGE__->mk_accessors( qw[ is_setup
is_prepared
is_restored
}
if ( exists $params->{environment} ) {
- $self->environment( $params->{environment} );
+ $self->environment( { %{ $params->{environment} } } );
}
else {
$self->environment( {} );
sub setup {
my $self = shift;
+ if ( $self->is_setup ) {
+ croak("An attempt was made to setup environment variables and STD handles which has already been setup.");
+ }
+
$self->setup_content;
$self->setup_stdin;
$self->setup_stdout;
CGI::initialize_globals();
}
- $self->is_setuped(1);
+ $self->is_setup(1);
return $self;
}
if ( defined($$content) && length($$content) ) {
print( { $self->stdin } $$content )
- or croak("Couldn't write request content to stdin handle: '$!'");
+ or croak("Couldn't write request content SCALAR to stdin handle: '$!'");
if ( $self->should_rewind ) {
seek( $self->stdin, 0, SEEK_SET )
- or croak("Couldn't seek stdin handle: '$!'");
+ or croak("Couldn't rewind stdin handle: '$!'");
}
}
}
if ( defined($chunk) && length($chunk) ) {
print( { $self->stdin } $chunk )
- or croak("Couldn't write request content chunk to stdin handle: '$!'");
+ or croak("Couldn't write request content callback to stdin handle: '$!'");
}
else {
last;
if ( $self->should_rewind ) {
seek( $self->stdin, 0, SEEK_SET )
- or croak("Couldn't seek stdin handle: '$!'");
+ or croak("Couldn't rewind stdin handle: '$!'");
}
}
else {
sub setup_content {
my $self = shift;
- if ( $self->has_stdin && $self->should_setup_content ) {
+ if ( $self->should_setup_content && $self->has_stdin ) {
$self->write_content($self->stdin);
}
}
$self->{restore}->{stdin} = $stdin;
}
- STDIN->fdopen( $self->stdin, '<' )
+ open( STDIN, '<&' . fileno($self->stdin) )
or croak("Couldn't dup stdin handle to STDIN: '$!'");
}
else {
$self->{restore}->{stdout} = $stdout;
}
- STDOUT->fdopen( $self->stdout, '>' )
+ open( STDOUT, '>&' . fileno($self->stdout) )
or croak("Couldn't dup stdout handle to STDOUT: '$!'");
}
else {
$self->{restore}->{stderr} = $stderr;
}
- STDERR->fdopen( $self->stderr, '>' )
- or croak("Couldn't dup stderr handle to STDERR: '$!'");
+ open( STDERR, '>&' . fileno($self->stderr) )
+ or croak("Couldn't dup stdout handle to STDOUT: '$!'");
}
else {
$response->protocol('HTTP/1.1');
while ( my $line = readline($self->stdout) ) {
- $message .= $line;
+
+ if ( !$message && $line =~ /^\x0d?\x0a$/ ) {
+ next;
+ }
+ else {
+ $message .= $line;
+ }
+
last if $message =~ /\x0d?\x0a\x0d?\x0a$/;
}
}
if ( !$response->date ) {
- $response->date(time);
+ $response->date(time());
}
if ( $params{headers_only} ) {
sub restore {
my $self = shift;
- if ( $self->should_restore ) {
-
- $self->restore_environment;
- $self->restore_stdin;
- $self->restore_stdout;
- $self->restore_stderr;
+ if ( !$self->should_restore ) {
+ croak("An attempt was made to restore environment variables and STD handles which has not been saved.");
+ }
- $self->{restore} = {};
+ if ( !$self->is_setup ) {
+ croak("An attempt was made to restore environment variables and STD handles which has not been setup.");
+ }
- $self->is_restored(1);
+ if ( $self->is_restored ) {
+ croak("An attempt was made to restore environment variables and STD handles which has already been restored.");
}
+ $self->restore_environment;
+ $self->restore_stdin;
+ $self->restore_stdout;
+ $self->restore_stderr;
+
+ $self->{restore} = {};
+
+ $self->is_restored(1);
+
return $self;
}
if ( $self->should_dup ) {
- STDIN->fdopen( $stdin, '<' )
+ STDIN->fdopen( fileno($stdin), '<' )
or croak("Couldn't restore STDIN: '$!'");
}
else {
if ( $self->should_rewind ) {
seek( $self->stdin, 0, SEEK_SET )
- or croak("Couldn't seek stdin handle: '$!'");
+ or croak("Couldn't rewind stdin handle: '$!'");
}
}
}
STDOUT->flush
or croak("Couldn't flush STDOUT: '$!'");
- STDOUT->fdopen( $stdout, '>' )
+ STDOUT->fdopen( fileno($stdout), '>' )
or croak("Couldn't restore STDOUT: '$!'");
}
else {
if ( $self->should_rewind ) {
seek( $self->stdout, 0, SEEK_SET )
- or croak("Couldn't seek stdout handle: '$!'");
+ or croak("Couldn't rewind stdout handle: '$!'");
}
}
}
STDERR->flush
or croak("Couldn't flush STDERR: '$!'");
- STDERR->fdopen( $stderr, '>' )
+ STDERR->fdopen( fileno($stderr), '>' )
or croak("Couldn't restore STDERR: '$!'");
}
else {
if ( $self->should_rewind ) {
seek( $self->stderr, 0, SEEK_SET )
- or croak("Couldn't seek stderr handle: '$!'");
+ or croak("Couldn't rewind stderr handle: '$!'");
}
}
}
sub DESTROY {
my $self = shift;
- if ( $self->should_restore && $self->is_setuped && !$self->is_restored ) {
+ if ( $self->should_restore && $self->is_setup && !$self->is_restored ) {
$self->restore;
}
}
$stdout = $c->stdout;
- # environment and descriptors will automatically be restored
+ # environment and descriptors is automatically restored
# when $c is destructed.
}
=over 4
-=item new ( $request [, key => value ] )
+=item * new
+
+Contructor
+
+ HTTP::Request->new( $request, %environment );
+
+ HTTP::Request->new( request => $request, environment => \%environment );
+
+=over 8
+
+=item * request
-Contructor, first argument must be a instance of HTTP::Request
-followed by optional pairs of environment key and value.
+ request => HTTP::Request->new( GET => 'http://www.host.com/' )
+
+=item * stdin
+
+Filehandle to be used as C<STDIN>, defaults to a temporary file. If value is
+C<undef>, C<STDIN> will be left as is.
+
+ stdin => IO::File->new_tmpfile
+ stdin => IO::String->new
+ stdin => $fh
+ stdin => undef
+
+=item * stdout
+
+Filehandle to be used as C<STDOUT>, defaults to a temporary file. If value is
+C<undef>, C<STDOUT> will be left as is.
+
+ stdout => IO::File->new_tmpfile
+ stdout => IO::String->new
+ stdout => $fh
+ stdout => undef
+
+=item * stderr
+
+Filehandle to be used as C<STDERR>, defaults to C<undef>. If value is C<undef>,
+C<STDERR> will be left as is.
+
+ stderr => IO::File->new_tmpfile
+ stderr => IO::String->new
+ stderr => $fh
+ stderr => undef
+
+=item * environment
+
+ environment => \%ENV
+ environment => { PATH => '/bin:/usr/bin' }
+
+=item * dup
+
+ dup => 0
+ dup => 1
+
+=item * restore
+
+ restore => 0
+ restore => 1
+
+=item * rewind
+
+ rewind => 0
+ rewind => 1
+
+=item * content
+
+ content => 0
+ content => 1
+
+=back
=item environment
=item stdin
Accessor for handle that will be used for STDIN, must be a real seekable
-handle with an file descriptor. Defaults to a tempoary IO::File instance.
+handle with an file descriptor. Defaults to a temporary IO::File instance.
=item stdout
Accessor for handle that will be used for STDOUT, must be a real seekable
-handle with an file descriptor. Defaults to a tempoary IO::File instance.
+handle with an file descriptor. Defaults to a temporary IO::File instance.
=item stderr