improved Catalyst::Test::request
[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;
78 my %headers = ( -nph => 1 );
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;
162 $c->req->path( $c->cgi->url( -absolute => 1, -path_info => 1 ) );
163 my $loc = $c->cgi->url( -absolute => 1 );
164 no warnings 'uninitialized';
165 $c->req->{path} =~ s/^($loc)?\///;
166 $c->req->{path} .= '/' if $c->req->path eq $loc;
167 my $base = $c->cgi->url;
7833fdfc 168 if ( $ENV{CATALYST_TEST} ) {
169 my $script = $c->cgi->script_name;
170 $base =~ s/$script$//i;
171 }
fc7ec1d9 172 $base = URI->new($base);
173 $base->path('/') if ( $ENV{CATALYST_TEST} || !$base->path );
174 $c->req->base( $base->as_string );
175}
176
23f9d934 177=item $c->prepare_request
fc7ec1d9 178
179=cut
180
181sub prepare_request { shift->cgi( CGI::Simple->new ) }
182
23f9d934 183=item $c->prepare_uploads
fc7ec1d9 184
185=cut
186
187sub prepare_uploads {
188 my $c = shift;
189 for my $name ( $c->cgi->upload ) {
fc7ec1d9 190 $c->req->uploads->{$name} = {
7833fdfc 191 fh => $c->cgi->upload($name),
192 size => $c->cgi->upload_info( $name, 'size' ),
193 type => $c->cgi->upload_info( $name, 'mime' )
fc7ec1d9 194 };
195 }
196}
197
198sub run { shift->handler }
199
23f9d934 200=back
201
fc7ec1d9 202=head1 SEE ALSO
203
204L<Catalyst>.
205
206=head1 AUTHOR
207
208Sebastian Riedel, C<sri@cpan.org>
209
210=head1 COPYRIGHT
211
212This program is free software, you can redistribute it and/or modify it under
213the same terms as Perl itself.
214
215=cut
216
2171;