__PACKAGE__->mk_accessors(qw[ enviroment request stdin stdout stderr ]);
-our $VERSION = 0.1;
+our $VERSION = 0.2;
sub new {
my $class = shift;
unless ( @_ % 2 == 0 && eval { $request->isa('HTTP::Request') } ) {
croak(qq/usage: $class->new( \$request [, key => value] )/);
}
-
- my $self = {
- request => $request,
- restored => 0,
- setuped => 0,
- stdin => IO::File->new_tmpfile,
- stdout => IO::File->new_tmpfile
- };
+
+ my $self = $class->SUPER::new( { restored => 0, setuped => 0 } );
+ $self->request($request);
+ $self->stdin( IO::File->new_tmpfile );
+ $self->stdout( IO::File->new_tmpfile );
my $host = $request->header('Host');
my $uri = $request->uri->clone;
$uri->host('localhost') unless $uri->host;
$uri->port(80) unless $uri->port;
$uri->host_port($host) unless !$host || ( $host eq $uri->host_port );
+
+ $uri = $uri->canonical;
- $self->{enviroment} = {
+ my $enviroment = {
GATEWAY_INTERFACE => 'CGI/1.1',
HTTP_HOST => $uri->host_port,
HTTPS => ( $uri->scheme eq 'https' ) ? 'ON' : 'OFF', # not in RFC 3875
REMOTE_ADDR => '127.0.0.1',
REMOTE_HOST => 'localhost',
REMOTE_PORT => int( rand(64000) + 1000 ), # not in RFC 3875
- REQUEST_URI => $uri->path_query || '/', # not in RFC 3875
+ REQUEST_URI => $uri->path_query, # not in RFC 3875
REQUEST_METHOD => $request->method,
@_
};
foreach my $field ( $request->headers->header_field_names ) {
- my $key = uc($field);
+ my $key = uc("HTTP_$field");
$key =~ tr/-/_/;
- $key = 'HTTP_' . $key unless $field =~ /^Content-(Length|Type)$/;
+ $key =~ s/^HTTP_// if $field =~ /^Content-(Length|Type)$/;
- unless ( exists $self->{enviroment}->{$key} ) {
- $self->{enviroment}->{$key} = $request->headers->header($field);
+ unless ( exists $enviroment->{$key} ) {
+ $enviroment->{$key} = $request->headers->header($field);
}
}
- return $class->SUPER::new($self);
+ unless ( $enviroment->{SCRIPT_NAME} eq '/' && $enviroment->{PATH_INFO} ) {
+ $enviroment->{PATH_INFO} =~ s/^\Q$enviroment->{SCRIPT_NAME}\E/\//;
+ $enviroment->{PATH_INFO} =~ s/^\/+/\//;
+ }
+
+ $self->enviroment($enviroment);
+
+ return $self;
}
sub setup {
$self->{restore}->{enviroment} = {%ENV};
- open( $self->{restore}->{stdin}, '>&', STDIN->fileno )
- or croak("Can't dup stdin: $!");
-
- open( STDIN, '<&=', $self->stdin->fileno )
- or croak("Can't open stdin: $!");
-
binmode( $self->stdin );
- binmode( STDIN );
if ( $self->request->content_length ) {
or croak("Can't seek stdin handle: $!");
}
+ open( $self->{restore}->{stdin}, '>&', STDIN->fileno )
+ or croak("Can't dup stdin: $!");
+
+ open( STDIN, '<&=', $self->stdin->fileno )
+ or croak("Can't open stdin: $!");
+
+ binmode( STDIN );
+
if ( $self->stdout ) {
open( $self->{restore}->{stdout}, '>&', STDOUT->fileno )
=item new ( $request [, key => value ] )
Contructor, first argument must be a instance of HTTP::Request
-followed by optional pairs of environment keys and values.
+followed by optional pairs of environment key and value.
=item enviroment
use HTTP::Request;
use HTTP::Request::AsCGI;
-my $r = HTTP::Request->new( GET => 'http://www.host.com/my/path/?a=1&b=2', [ 'X-Test' => 'Test' ] );
-my $c = HTTP::Request::AsCGI->new($r);
+my $r = HTTP::Request->new( GET => 'http://www.host.com/cgi-bin/script.cgi/my/path/?a=1&b=2', [ 'X-Test' => 'Test' ] );
+my %e = ( SCRIPT_NAME => '/cgi-bin/script.cgi' );
+my $c = HTTP::Request::AsCGI->new( $r, %e );
$c->stdout(undef);
$c->setup;
is( $ENV{HTTP_X_TEST}, 'Test', 'HTTP_X_TEST' );
is( $ENV{PATH_INFO}, '/my/path/', 'PATH_INFO' );
is( $ENV{QUERY_STRING}, 'a=1&b=2', 'QUERY_STRING' );
-is( $ENV{SCRIPT_NAME}, '/', 'SCRIPT_NAME' );
+is( $ENV{SCRIPT_NAME}, '/cgi-bin/script.cgi', 'SCRIPT_NAME' );
is( $ENV{REQUEST_METHOD}, 'GET', 'REQUEST_METHOD' );
is( $ENV{SERVER_NAME}, 'www.host.com', 'SERVER_NAME' );
is( $ENV{SERVER_PORT}, '80', 'SERVER_PORT' );
--- /dev/null
+#!perl
+
+use Test::More tests => 8;
+
+use strict;
+use warnings;
+
+use IO::File;
+use HTTP::Request;
+use HTTP::Request::AsCGI;
+
+my $response;
+
+{
+ my $r = HTTP::Request->new( GET => 'http://www.host.com/' );
+ my $c = HTTP::Request::AsCGI->new($r);
+
+ $c->setup;
+
+ print "HTTP/1.0 200 OK\n";
+ print "Content-Type: text/plain\n";
+ print "Status: 200\n";
+ print "X-Field: 1\n";
+ print "X-Field: 2\n";
+ print "\n";
+ print "Hello!";
+
+ $response = $c->restore->response;
+}
+
+isa_ok( $response, 'HTTP::Response' );
+is( $response->code, 200, 'Response Code' );
+is( $response->message, 'OK', 'Response Message' );
+is( $response->protocol, 'HTTP/1.0', 'Response Protocol' );
+is( $response->content, 'Hello!', 'Response Content' );
+is( $response->content_length, 6, 'Response Content-Length' );
+is( $response->content_type, 'text/plain', 'Response Content-Type' );
+is_deeply( [ $response->header('X-Field') ], [ 1, 2 ], 'Response Header X-Field' );