Fixed Request/Response body
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Engine / CGI.pm
CommitLineData
fc7ec1d9 1package Catalyst::Engine::CGI;
2
3use strict;
4use base 'Catalyst::Engine';
e7c0c583 5
6use CGI;
fc7ec1d9 7use URI;
399ed680 8use URI::http;
fc7ec1d9 9
fc7ec1d9 10__PACKAGE__->mk_accessors('cgi');
11
12=head1 NAME
13
14Catalyst::Engine::CGI - The CGI Engine
15
16=head1 SYNOPSIS
17
23f9d934 18A script using the Catalyst::Engine::CGI module might look like:
19
9a33da6a 20 #!/usr/bin/perl -w
21
22 use strict;
23 use lib '/path/to/MyApp/lib';
24 use MyApp;
25
26 MyApp->run;
27
23f9d934 28The application module (C<MyApp>) would use C<Catalyst>, which loads the
29appropriate engine module.
fc7ec1d9 30
31=head1 DESCRIPTION
32
23f9d934 33This is the Catalyst engine specialized for the CGI environment (using the
e7c0c583 34C<CGI> and C<CGI::Cookie> modules). Normally Catalyst will select the
23f9d934 35appropriate engine according to the environment that it detects, however you
36can force Catalyst to use the CGI engine by specifying the following in your
37application module:
38
39 use Catalyst qw(-Engine=CGI);
fc7ec1d9 40
9a33da6a 41The performance of this way of using Catalyst is not expected to be
42useful in production applications, but it may be helpful for development.
43
23f9d934 44=head1 METHODS
fc7ec1d9 45
23f9d934 46=over 4
47
23f9d934 48=item $c->cgi
fc7ec1d9 49
e7c0c583 50This config parameter contains the C<CGI> object.
fc7ec1d9 51
23f9d934 52=back
53
54=head1 OVERLOADED METHODS
fc7ec1d9 55
45374ac6 56This class overloads some methods from C<Catalyst::Engine>.
fc7ec1d9 57
23f9d934 58=over 4
59
06e1b616 60=item $c->finalize_body
61
62Prints the response output to STDOUT.
63
64=cut
65
66sub finalize_body {
67 my $c = shift;
68 print $c->response->output;
69}
70
23f9d934 71=item $c->finalize_headers
fc7ec1d9 72
73=cut
74
75sub finalize_headers {
76 my $c = shift;
6dc87a0f 77
e7c0c583 78 $c->response->header( Status => $c->response->status );
6dc87a0f 79
e7c0c583 80 print $c->response->headers->as_string("\015\012");
81 print "\015\012";
fc7ec1d9 82}
83
06e1b616 84=item $c->prepare_body
fc7ec1d9 85
86=cut
87
06e1b616 88sub prepare_body {
fc7ec1d9 89 my $c = shift;
06e1b616 90
91 # XXX this is undocumented in CGI.pm. If Content-Type is not
92 # application/x-www-form-urlencoded or multipart/form-data
93 # CGI.pm will read STDIN into a param, POSTDATA.
94
e060fe05 95 $c->request->body( $c->cgi->param('POSTDATA') );
fc7ec1d9 96}
97
0556eb49 98=item $c->prepare_connection
99
100=cut
101
102sub prepare_connection {
103 my $c = shift;
e7c0c583 104 $c->req->hostname( $ENV{REMOTE_HOST} );
105 $c->req->address( $ENV{REMOTE_ADDR} );
0556eb49 106}
107
23f9d934 108=item $c->prepare_headers
fc7ec1d9 109
110=cut
111
112sub prepare_headers {
113 my $c = shift;
e7c0c583 114
115 while ( my ( $header, $value ) = each %ENV ) {
116
117 next unless $header =~ /^(HTTP|CONTENT)/i;
118
fc7ec1d9 119 ( my $field = $header ) =~ s/^HTTPS?_//;
e7c0c583 120
121 $c->req->headers->header( $field => $value );
fc7ec1d9 122 }
e7c0c583 123
124 $c->req->method( $ENV{REQUEST_METHOD} || 'GET' );
fc7ec1d9 125}
126
23f9d934 127=item $c->prepare_parameters
fc7ec1d9 128
129=cut
130
131sub prepare_parameters {
e7c0c583 132 my $c = shift;
5b387dfc 133
134 my ( @params );
e7c0c583 135
08cf3dd6 136 for my $param ( $c->cgi->url_param ) {
137 for my $value ( $c->cgi->url_param($param) ) {
5b387dfc 138 push ( @params, $param, $value );
139 }
fc7ec1d9 140 }
08cf3dd6 141
142 for my $param ( $c->cgi->param ) {
143 for my $value ( $c->cgi->param($param) ) {
5b387dfc 144 push ( @params, $param, $value );
145 }
146 }
08cf3dd6 147
5b387dfc 148 $c->req->_assign_values( $c->req->parameters, \@params );
fc7ec1d9 149}
150
23f9d934 151=item $c->prepare_path
fc7ec1d9 152
153=cut
154
155sub prepare_path {
156 my $c = shift;
8b4483b3 157
158 my $base;
159 {
160 my $scheme = $ENV{HTTPS} ? 'https' : 'http';
e7c0c583 161 my $host = $ENV{HTTP_HOST} || $ENV{SERVER_NAME};
8b4483b3 162 my $port = $ENV{SERVER_PORT} || 80;
163 my $path = $ENV{SCRIPT_NAME} || '/';
164
165 $base = URI->new;
166 $base->scheme($scheme);
167 $base->host($host);
168 $base->port($port);
169 $base->path($path);
170
171 $base = $base->canonical->as_string;
7833fdfc 172 }
8b4483b3 173
174 my $path = $ENV{PATH_INFO} || '/';
6dc87a0f 175 $path =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
e7c0c583 176 $path =~ s/^\///;
8b4483b3 177
178 $c->req->base($base);
179 $c->req->path($path);
fc7ec1d9 180}
181
23f9d934 182=item $c->prepare_request
fc7ec1d9 183
184=cut
185
e7c0c583 186sub prepare_request {
187 my $c = shift;
188 $c->cgi( CGI->new );
189 $c->cgi->_reset_globals;
190}
fc7ec1d9 191
23f9d934 192=item $c->prepare_uploads
fc7ec1d9 193
194=cut
195
196sub prepare_uploads {
197 my $c = shift;
e7c0c583 198
199 my @uploads;
200
201 for my $param ( $c->cgi->param ) {
202
203 my @values = $c->cgi->param($param);
204
205 next unless ref( $values[0] );
206
207 for my $fh (@values) {
208
209 next unless my $size = ( stat $fh )[7];
210
211 my $info = $c->cgi->uploadInfo($fh);
212 my $tempname = $c->cgi->tmpFileName($fh);
213 my $type = $info->{'Content-Type'};
214 my $disposition = $info->{'Content-Disposition'};
215 my $filename = ( $disposition =~ / filename="([^;]*)"/ )[0];
216
146554c5 217 my $upload = Catalyst::Request::Upload->new(
e7c0c583 218 filename => $filename,
219 size => $size,
220 tempname => $tempname,
221 type => $type
146554c5 222 );
e7c0c583 223
224 push( @uploads, $param, $upload );
225 }
fc7ec1d9 226 }
e7c0c583 227
228 $c->req->_assign_values( $c->req->uploads, \@uploads );
fc7ec1d9 229}
230
c9afa5fc 231=item $c->run
232
233=cut
234
fc7ec1d9 235sub run { shift->handler }
236
23f9d934 237=back
238
fc7ec1d9 239=head1 SEE ALSO
240
241L<Catalyst>.
242
243=head1 AUTHOR
244
245Sebastian Riedel, C<sri@cpan.org>
246
247=head1 COPYRIGHT
248
249This program is free software, you can redistribute it and/or modify it under
250the same terms as Perl itself.
251
252=cut
253
2541;