Added simple IO test
[catagits/HTTP-Request-AsCGI.git] / lib / HTTP / Request / AsCGI.pm
CommitLineData
b2e1304d 1package HTTP::Request::AsCGI;
2
3use strict;
4use warnings;
5use base 'Class::Accessor::Fast';
6
7use Carp;
bd7813ac 8use IO::File;
b2e1304d 9
10__PACKAGE__->mk_accessors( qw[ enviroment request stdin stdout stderr ] );
11
12our $VERSION = 0.1;
13
14sub new {
15 my $class = shift;
16 my $request = shift;
17
18 my $self = {
19 request => $request,
20 restored => 0,
bd7813ac 21 stdin => IO::File->new_tmpfile,
22 stdout => IO::File->new_tmpfile,
23 stderr => IO::File->new_tmpfile
b2e1304d 24 };
25
26 $self->{enviroment} = {
27 GATEWAY_INTERFACE => 'CGI/1.1',
28 HTTP_HOST => $request->uri->host_port,
29 QUERY_STRING => $request->uri->query || '',
30 SCRIPT_NAME => $request->uri->path || '/',
31 SERVER_NAME => $request->uri->host,
32 SERVER_PORT => $request->uri->port,
33 SERVER_PROTOCOL => $request->protocol || 'HTTP/1.1',
34 SERVER_SOFTWARE => __PACKAGE__ . "/" . $VERSION,
35 REMOTE_ADDR => '127.0.0.1',
36 REMOTE_HOST => 'localhost',
37 REMOTE_PORT => int( rand(64000) + 1000 ), # not in RFC 3875
38 REQUEST_URI => $request->uri->path || '/', # not in RFC 3875
39 REQUEST_METHOD => $request->method,
40 @_
41 };
42
43 foreach my $field ( $request->headers->header_field_names ) {
44
45 my $key = uc($field);
46 $key =~ tr/_/-/;
47 $key = 'HTTP_' . $key unless $field =~ /^Content-(Length|Type)$/;
48
49 unless ( exists $self->{enviroment}->{$key} ) {
50 $self->{enviroment}->{$key} = $request->headers->header($field);
51 }
52 }
53
54 return $class->SUPER::new($self);
55}
56
57sub setup {
58 my $self = shift;
59
60 open( my $stdin, '>&', STDIN->fileno )
61 or croak("Can't dup stdin: $!");
62
63 open( my $stdout, '>&', STDOUT->fileno )
64 or croak("Can't dup stdout: $!");
65
66 open( my $stderr, '>&', STDERR->fileno )
67 or croak("Can't dup stderr: $!");
68
69 $self->{restore} = {
70 stdin => $stdin,
71 stdout => $stdout,
72 stderr => $stderr,
73 enviroment => {%ENV}
74 };
75
76 if ( $self->request->content_length ) {
77
12852959 78 $self->stdin->syswrite( $self->request->content )
79 or croak("Can't write content to stdin: $!");
b2e1304d 80
12852959 81 $self->stdin->sysseek( 0, SEEK_SET )
b2e1304d 82 or croak("Can't seek stdin: $!");
83 }
84
85 %ENV = %{ $self->enviroment };
86
87 open( STDIN, '<&=', $self->stdin->fileno )
88 or croak("Can't open stdin: $!");
89
90 open( STDOUT, '>&=', $self->stdout->fileno )
91 or croak("Can't open stdout: $!");
92
93 open( STDERR, '>&=', $self->stderr->fileno )
94 or croak("Can't open stderr: $!");
95
96 return $self;
97}
98
99sub restore {
100 my $self = shift;
101
102 %ENV = %{ $self->{restore}->{enviroment} };
103
104 open( STDIN, '>&', $self->{restore}->{stdin} )
105 or croak("Can't restore stdin: $!");
106
107 open( STDOUT, '>&', $self->{restore}->{stdout} )
108 or croak("Can't restore stdout: $!");
109
110 open( STDERR, '>&', $self->{restore}->{stderr} )
111 or croak("Can't restore stderr: $!");
12852959 112
113 $self->stdin->sysseek( 0, SEEK_SET )
114 or croak("Can't seek stdin: $!");
115
116 $self->stdout->sysseek( 0, SEEK_SET )
117 or croak("Can't seek stdout: $!");
118
119 $self->stderr->sysseek( 0, SEEK_SET )
120 or croak("Can't seek stderr: $!");
121
b2e1304d 122 $self->{restored}++;
123}
124
125sub DESTROY {
126 my $self = shift;
127 $self->restore unless $self->{restored};
128}
129
1301;
131
132__END__
133
134=head1 NAME
135
bd7813ac 136HTTP::Request::AsCGI - Setup a CGI enviroment from a HTTP::Request
b2e1304d 137
138=head1 SYNOPSIS
139
bd7813ac 140 use CGI;
141 use HTTP::Request;
142 use HTTP::Request::AsCGI;
143
144 my $request = HTTP::Request->new( GET => 'http://www.host.com/' );
145 my $stdout;
146
147 {
148 my $c = HTTP::Request::AsCGI->new($request)->setup;
149 my $q = CGI->new;
150
151 print $q->header,
152 $q->start_html('Hello World'),
153 $q->h1('Hello World'),
154 $q->end_html;
155
156 $stdout = $c->stdout;
157
158 # enviroment and descriptors will automatically be restored when $c is destructed.
159 }
160
bd7813ac 161 while ( my $line = $stdout->getline ) {
162 print $line;
163 }
164
b2e1304d 165=head1 DESCRIPTION
166
167=head1 METHODS
168
169=over 4
170
171=item new
172
bd7813ac 173=item enviroment
174
b2e1304d 175=item setup
176
177=item restore
178
179=item request
180
181=item stdin
182
183=item stdout
184
185=item stderr
186
187=back
188
189=head1 BUGS
190
191=head1 AUTHOR
192
193Christian Hansen, C<ch@ngmedia.com>
194
195=head1 LICENSE
196
197This library is free software. You can redistribute it and/or modify
198it under the same terms as perl itself.
199
200=cut