typo
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Engine / CGI.pm
CommitLineData
fc7ec1d9 1package Catalyst::Engine::CGI;
2
3use strict;
4use base 'Catalyst::Engine';
5use URI;
6
7require CGI::Simple;
8require CGI::Cookie;
9
7833fdfc 10$CGI::Simple::POST_MAX = 1048576;
11$CGI::Simple::DISABLE_UPLOADS = 0;
12
fc7ec1d9 13__PACKAGE__->mk_accessors('cgi');
14
15=head1 NAME
16
17Catalyst::Engine::CGI - The CGI Engine
18
19=head1 SYNOPSIS
20
23f9d934 21A script using the Catalyst::Engine::CGI module might look like:
22
9a33da6a 23 #!/usr/bin/perl -w
24
25 use strict;
26 use lib '/path/to/MyApp/lib';
27 use MyApp;
28
29 MyApp->run;
30
23f9d934 31The application module (C<MyApp>) would use C<Catalyst>, which loads the
32appropriate engine module.
fc7ec1d9 33
34=head1 DESCRIPTION
35
23f9d934 36This is the Catalyst engine specialized for the CGI environment (using the
37C<CGI::Simple> and C<CGI::Cookie> modules). Normally Catalyst will select the
38appropriate engine according to the environment that it detects, however you
39can force Catalyst to use the CGI engine by specifying the following in your
40application module:
41
42 use Catalyst qw(-Engine=CGI);
fc7ec1d9 43
23f9d934 44Catalyst::Engine::CGI generates a full set of HTTP headers, which means that
45applications using the engine must be be configured as "Non-parsed Headers"
46scripts (at least when running under Apache). To configure this under Apache
47name the starting with C<nph->.
9a33da6a 48
49The performance of this way of using Catalyst is not expected to be
50useful in production applications, but it may be helpful for development.
51
23f9d934 52=head1 METHODS
fc7ec1d9 53
23f9d934 54=over 4
55
23f9d934 56=item $c->cgi
fc7ec1d9 57
58This config parameter contains the C<CGI::Simple> object.
59
23f9d934 60=back
61
62=head1 OVERLOADED METHODS
fc7ec1d9 63
45374ac6 64This class overloads some methods from C<Catalyst::Engine>.
fc7ec1d9 65
23f9d934 66=over 4
67
68=item $c->finalize_headers
fc7ec1d9 69
70=cut
71
72sub finalize_headers {
73 my $c = shift;
e646f111 74 my %headers;
fc7ec1d9 75 $headers{-status} = $c->response->status if $c->response->status;
76 for my $name ( $c->response->headers->header_field_names ) {
77 $headers{"-$name"} = $c->response->headers->header($name);
78 }
79 my @cookies;
80 while ( my ( $name, $cookie ) = each %{ $c->response->cookies } ) {
81 push @cookies, $c->cgi->cookie(
82 -name => $name,
83 -value => $cookie->{value},
84 -expires => $cookie->{expires},
85 -domain => $cookie->{domain},
86 -path => $cookie->{path},
87 -secure => $cookie->{secure} || 0
88 );
89 }
90 $headers{-cookie} = \@cookies if @cookies;
91 print $c->cgi->header(%headers);
92}
93
23f9d934 94=item $c->finalize_output
95
96Prints the response output to STDOUT.
fc7ec1d9 97
98=cut
99
100sub finalize_output {
101 my $c = shift;
102 print $c->response->output;
103}
104
0556eb49 105=item $c->prepare_connection
106
107=cut
108
109sub prepare_connection {
110 my $c = shift;
111 $c->req->hostname( $c->cgi->remote_host );
112 $c->req->address( $c->cgi->remote_addr );
113}
114
23f9d934 115=item $c->prepare_cookies
116
117Sets up cookies.
fc7ec1d9 118
119=cut
120
121sub prepare_cookies { shift->req->cookies( { CGI::Cookie->fetch } ) }
122
23f9d934 123=item $c->prepare_headers
fc7ec1d9 124
125=cut
126
127sub prepare_headers {
128 my $c = shift;
129 $c->req->method( $c->cgi->request_method );
130 for my $header ( $c->cgi->http ) {
131 ( my $field = $header ) =~ s/^HTTPS?_//;
132 $c->req->headers->header( $field => $c->cgi->http($header) );
133 }
49faa307 134 $c->req->headers->header( 'Content-Type' => $c->cgi->content_type );
135 $c->req->headers->header( 'Content-Length' => $c->cgi->content_length );
fc7ec1d9 136}
137
23f9d934 138=item $c->prepare_parameters
fc7ec1d9 139
140=cut
141
142sub prepare_parameters {
143 my $c = shift;
523d44ec 144
145 $c->cgi->parse_query_string;
146
fc7ec1d9 147 my %vars = $c->cgi->Vars;
148 while ( my ( $key, $value ) = each %vars ) {
149 my @values = split "\0", $value;
150 $vars{$key} = @values <= 1 ? $values[0] : \@values;
151 }
152 $c->req->parameters( {%vars} );
153}
154
23f9d934 155=item $c->prepare_path
fc7ec1d9 156
157=cut
158
159sub prepare_path {
160 my $c = shift;
8b4483b3 161
162 my $base;
163 {
164 my $scheme = $ENV{HTTPS} ? 'https' : 'http';
165 my $host = $ENV{HTTP_HOST} || $ENV{SERVER_NAME};
166 my $port = $ENV{SERVER_PORT} || 80;
167 my $path = $ENV{SCRIPT_NAME} || '/';
168
169 $base = URI->new;
170 $base->scheme($scheme);
171 $base->host($host);
172 $base->port($port);
173 $base->path($path);
174
175 $base = $base->canonical->as_string;
7833fdfc 176 }
8b4483b3 177
178 my $path = $ENV{PATH_INFO} || '/';
179 $path =~ s/^\///;
180
181 $c->req->base($base);
182 $c->req->path($path);
fc7ec1d9 183}
184
23f9d934 185=item $c->prepare_request
fc7ec1d9 186
187=cut
188
189sub prepare_request { shift->cgi( CGI::Simple->new ) }
190
23f9d934 191=item $c->prepare_uploads
fc7ec1d9 192
193=cut
194
195sub prepare_uploads {
196 my $c = shift;
197 for my $name ( $c->cgi->upload ) {
b0b7c5e0 198 next unless defined $name;
fc7ec1d9 199 $c->req->uploads->{$name} = {
7833fdfc 200 fh => $c->cgi->upload($name),
201 size => $c->cgi->upload_info( $name, 'size' ),
202 type => $c->cgi->upload_info( $name, 'mime' )
fc7ec1d9 203 };
204 }
205}
206
c9afa5fc 207=item $c->run
208
209=cut
210
fc7ec1d9 211sub run { shift->handler }
212
23f9d934 213=back
214
fc7ec1d9 215=head1 SEE ALSO
216
217L<Catalyst>.
218
219=head1 AUTHOR
220
221Sebastian Riedel, C<sri@cpan.org>
222
223=head1 COPYRIGHT
224
225This program is free software, you can redistribute it and/or modify it under
226the same terms as Perl itself.
227
228=cut
229
2301;