added C::E::CGI::NPH
[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
56=item $c->run
fc7ec1d9 57
58To be called from a CGI script to start the Catalyst application.
59
23f9d934 60=item $c->cgi
fc7ec1d9 61
62This config parameter contains the C<CGI::Simple> object.
63
23f9d934 64=back
65
66=head1 OVERLOADED METHODS
fc7ec1d9 67
68This class overloads some methods from C<Catalyst>.
69
23f9d934 70=over 4
71
72=item $c->finalize_headers
fc7ec1d9 73
74=cut
75
76sub finalize_headers {
77 my $c = shift;
e646f111 78 my %headers;
fc7ec1d9 79 $headers{-status} = $c->response->status if $c->response->status;
80 for my $name ( $c->response->headers->header_field_names ) {
81 $headers{"-$name"} = $c->response->headers->header($name);
82 }
83 my @cookies;
84 while ( my ( $name, $cookie ) = each %{ $c->response->cookies } ) {
85 push @cookies, $c->cgi->cookie(
86 -name => $name,
87 -value => $cookie->{value},
88 -expires => $cookie->{expires},
89 -domain => $cookie->{domain},
90 -path => $cookie->{path},
91 -secure => $cookie->{secure} || 0
92 );
93 }
94 $headers{-cookie} = \@cookies if @cookies;
95 print $c->cgi->header(%headers);
96}
97
23f9d934 98=item $c->finalize_output
99
100Prints the response output to STDOUT.
fc7ec1d9 101
102=cut
103
104sub finalize_output {
105 my $c = shift;
106 print $c->response->output;
107}
108
0556eb49 109=item $c->prepare_connection
110
111=cut
112
113sub prepare_connection {
114 my $c = shift;
115 $c->req->hostname( $c->cgi->remote_host );
116 $c->req->address( $c->cgi->remote_addr );
117}
118
23f9d934 119=item $c->prepare_cookies
120
121Sets up cookies.
fc7ec1d9 122
123=cut
124
125sub prepare_cookies { shift->req->cookies( { CGI::Cookie->fetch } ) }
126
23f9d934 127=item $c->prepare_headers
fc7ec1d9 128
129=cut
130
131sub prepare_headers {
132 my $c = shift;
133 $c->req->method( $c->cgi->request_method );
134 for my $header ( $c->cgi->http ) {
135 ( my $field = $header ) =~ s/^HTTPS?_//;
136 $c->req->headers->header( $field => $c->cgi->http($header) );
137 }
49faa307 138 $c->req->headers->header( 'Content-Type' => $c->cgi->content_type );
139 $c->req->headers->header( 'Content-Length' => $c->cgi->content_length );
fc7ec1d9 140}
141
23f9d934 142=item $c->prepare_parameters
fc7ec1d9 143
144=cut
145
146sub prepare_parameters {
147 my $c = shift;
148 my %vars = $c->cgi->Vars;
149 while ( my ( $key, $value ) = each %vars ) {
150 my @values = split "\0", $value;
151 $vars{$key} = @values <= 1 ? $values[0] : \@values;
152 }
153 $c->req->parameters( {%vars} );
154}
155
23f9d934 156=item $c->prepare_path
fc7ec1d9 157
158=cut
159
160sub prepare_path {
161 my $c = shift;
8b4483b3 162
163 my $base;
164 {
165 my $scheme = $ENV{HTTPS} ? 'https' : 'http';
166 my $host = $ENV{HTTP_HOST} || $ENV{SERVER_NAME};
167 my $port = $ENV{SERVER_PORT} || 80;
168 my $path = $ENV{SCRIPT_NAME} || '/';
169
170 $base = URI->new;
171 $base->scheme($scheme);
172 $base->host($host);
173 $base->port($port);
174 $base->path($path);
175
176 $base = $base->canonical->as_string;
7833fdfc 177 }
8b4483b3 178
179 my $path = $ENV{PATH_INFO} || '/';
180 $path =~ s/^\///;
181
182 $c->req->base($base);
183 $c->req->path($path);
fc7ec1d9 184}
185
23f9d934 186=item $c->prepare_request
fc7ec1d9 187
188=cut
189
190sub prepare_request { shift->cgi( CGI::Simple->new ) }
191
23f9d934 192=item $c->prepare_uploads
fc7ec1d9 193
194=cut
195
196sub prepare_uploads {
197 my $c = shift;
198 for my $name ( $c->cgi->upload ) {
b0b7c5e0 199 next unless defined $name;
fc7ec1d9 200 $c->req->uploads->{$name} = {
7833fdfc 201 fh => $c->cgi->upload($name),
202 size => $c->cgi->upload_info( $name, 'size' ),
203 type => $c->cgi->upload_info( $name, 'mime' )
fc7ec1d9 204 };
205 }
206}
207
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;