package Catalyst::Engine::CGI;
use strict;
-use base 'Catalyst::Engine';
-use URI;
+use base 'Catalyst::Engine::CGI::Base';
-require CGI::Simple;
-
-$CGI::Simple::POST_MAX = 1048576;
-$CGI::Simple::DISABLE_UPLOADS = 0;
-
-__PACKAGE__->mk_accessors('cgi');
+use CGI;
=head1 NAME
=head1 DESCRIPTION
This is the Catalyst engine specialized for the CGI environment (using the
-C<CGI::Simple> and C<CGI::Cookie> modules). Normally Catalyst will select the
+C<CGI> and C<CGI::Cookie> modules). Normally Catalyst will select the
appropriate engine according to the environment that it detects, however you
can force Catalyst to use the CGI engine by specifying the following in your
application module:
The performance of this way of using Catalyst is not expected to be
useful in production applications, but it may be helpful for development.
-=head1 METHODS
-
-=over 4
-
-=item $c->cgi
-
-This config parameter contains the C<CGI::Simple> object.
-
-=back
-
=head1 OVERLOADED METHODS
-This class overloads some methods from C<Catalyst::Engine>.
+This class overloads some methods from C<Catalyst::Engine::CGI::Base>.
=over 4
-=item $c->finalize_headers
+=item $c->prepare_body
=cut
-sub finalize_headers {
+sub prepare_body {
my $c = shift;
- my %headers;
- $headers{-status} = $c->response->status if $c->response->status;
+ # XXX this is undocumented in CGI.pm. If Content-Type is not
+ # application/x-www-form-urlencoded or multipart/form-data
+ # CGI.pm will read STDIN into a param, POSTDATA.
- for my $name ( $c->response->headers->header_field_names ) {
- $headers{"-$name"} = $c->response->header($name);
- }
-
- print $c->cgi->header(%headers);
+ $c->request->body( $c->cgi->param('POSTDATA') );
}
-=item $c->finalize_output
-
-Prints the response output to STDOUT.
-
-=cut
-
-sub finalize_output {
- my $c = shift;
- print $c->response->output;
-}
-
-=item $c->prepare_connection
+=item $c->prepare_parameters
=cut
-sub prepare_connection {
+sub prepare_parameters {
my $c = shift;
- $c->req->hostname( $c->cgi->remote_host );
- $c->req->address( $c->cgi->remote_addr );
-}
-=item $c->prepare_headers
+ my ( @params );
-=cut
+ if ( $c->request->method eq 'POST' ) {
+ for my $param ( $c->cgi->url_param ) {
+ for my $value ( $c->cgi->url_param($param) ) {
+ push ( @params, $param, $value );
+ }
+ }
+ }
-sub prepare_headers {
- my $c = shift;
- $c->req->method( $c->cgi->request_method );
- for my $header ( $c->cgi->http ) {
- ( my $field = $header ) =~ s/^HTTPS?_//;
- $c->req->headers->header( $field => $c->cgi->http($header) );
+ for my $param ( $c->cgi->param ) {
+ for my $value ( $c->cgi->param($param) ) {
+ push ( @params, $param, $value );
+ }
}
- $c->req->headers->header( 'Content-Type' => $c->cgi->content_type );
- $c->req->headers->header( 'Content-Length' => $c->cgi->content_length );
+
+ $c->request->param(@params);
}
-=item $c->prepare_parameters
+=item $c->prepare_request
=cut
-sub prepare_parameters {
- my $c = shift;
-
- $c->cgi->parse_query_string;
-
- my %vars = $c->cgi->Vars;
- while ( my ( $key, $value ) = each %vars ) {
- my @values = split "\0", $value;
- $vars{$key} = @values <= 1 ? $values[0] : \@values;
- }
- $c->req->parameters( {%vars} );
+sub prepare_request {
+ my ( $c, $cgi ) = @_;
+ $c->cgi( $cgi || CGI->new );
+ $c->cgi->_reset_globals;
}
-=item $c->prepare_path
+=item $c->prepare_uploads
=cut
-sub prepare_path {
+sub prepare_uploads {
my $c = shift;
- my $base;
- {
- my $scheme = $ENV{HTTPS} ? 'https' : 'http';
- my $host = $ENV{HTTP_HOST} || $ENV{SERVER_NAME};
- my $port = $ENV{SERVER_PORT} || 80;
- my $path = $ENV{SCRIPT_NAME} || '/';
+ my @uploads;
- $base = URI->new;
- $base->scheme($scheme);
- $base->host($host);
- $base->port($port);
- $base->path($path);
+ for my $param ( $c->cgi->param ) {
- $base = $base->canonical->as_string;
- }
+ my @values = $c->cgi->param($param);
- my $path = $ENV{PATH_INFO} || '/';
- $path =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
- $path =~ s/^\///;
+ next unless ref( $values[0] );
- $c->req->base($base);
- $c->req->path($path);
-}
+ for my $fh (@values) {
-=item $c->prepare_request
+ next unless my $size = ( stat $fh )[7];
-=cut
+ my $info = $c->cgi->uploadInfo($fh);
+ my $tempname = $c->cgi->tmpFileName($fh);
+ my $type = $info->{'Content-Type'};
+ my $disposition = $info->{'Content-Disposition'};
+ my $filename = ( $disposition =~ / filename="([^;]*)"/ )[0];
-sub prepare_request { shift->cgi( CGI::Simple->new ) }
+ my $upload = Catalyst::Request::Upload->new(
+ filename => $filename,
+ size => $size,
+ tempname => $tempname,
+ type => $type
+ );
-=item $c->prepare_uploads
-
-=cut
-
-sub prepare_uploads {
- my $c = shift;
- for my $name ( $c->cgi->upload ) {
- next unless defined $name;
- $c->req->uploads->{$name} = {
- fh => $c->cgi->upload($name),
- size => $c->cgi->upload_info( $name, 'size' ),
- type => $c->cgi->upload_info( $name, 'mime' )
- };
+ push( @uploads, $param, $upload );
+ }
}
-}
-
-=item $c->run
-=cut
-
-sub run { shift->handler }
+ $c->request->upload(@uploads);
+}
=back
=head1 SEE ALSO
-L<Catalyst>.
+L<Catalyst> L<Catalyst::Engine> L<Catalyst::Engine::CGI::Base>.
=head1 AUTHOR
Sebastian Riedel, C<sri@cpan.org>
+Christian Hansen, C<ch@ngmedia.com>
=head1 COPYRIGHT