added synopsis to Engine subclassed and documented a couple of methods to make podcov...
[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
64This class overloads some methods from C<Catalyst>.
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;
144 my %vars = $c->cgi->Vars;
145 while ( my ( $key, $value ) = each %vars ) {
146 my @values = split "\0", $value;
147 $vars{$key} = @values <= 1 ? $values[0] : \@values;
148 }
149 $c->req->parameters( {%vars} );
150}
151
23f9d934 152=item $c->prepare_path
fc7ec1d9 153
154=cut
155
156sub prepare_path {
157 my $c = shift;
8b4483b3 158
159 my $base;
160 {
161 my $scheme = $ENV{HTTPS} ? 'https' : 'http';
162 my $host = $ENV{HTTP_HOST} || $ENV{SERVER_NAME};
163 my $port = $ENV{SERVER_PORT} || 80;
164 my $path = $ENV{SCRIPT_NAME} || '/';
165
166 $base = URI->new;
167 $base->scheme($scheme);
168 $base->host($host);
169 $base->port($port);
170 $base->path($path);
171
172 $base = $base->canonical->as_string;
7833fdfc 173 }
8b4483b3 174
175 my $path = $ENV{PATH_INFO} || '/';
176 $path =~ s/^\///;
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
186sub prepare_request { shift->cgi( CGI::Simple->new ) }
187
23f9d934 188=item $c->prepare_uploads
fc7ec1d9 189
190=cut
191
192sub prepare_uploads {
193 my $c = shift;
194 for my $name ( $c->cgi->upload ) {
b0b7c5e0 195 next unless defined $name;
fc7ec1d9 196 $c->req->uploads->{$name} = {
7833fdfc 197 fh => $c->cgi->upload($name),
198 size => $c->cgi->upload_info( $name, 'size' ),
199 type => $c->cgi->upload_info( $name, 'mime' )
fc7ec1d9 200 };
201 }
202}
203
c9afa5fc 204=item $c->run
205
206=cut
207
fc7ec1d9 208sub run { shift->handler }
209
23f9d934 210=back
211
fc7ec1d9 212=head1 SEE ALSO
213
214L<Catalyst>.
215
216=head1 AUTHOR
217
218Sebastian Riedel, C<sri@cpan.org>
219
220=head1 COPYRIGHT
221
222This program is free software, you can redistribute it and/or modify it under
223the same terms as Perl itself.
224
225=cut
226
2271;