]> git.decadent.org.uk Git - maypole.git/blobdiff - lib/Apache/MVC.pm
hopefully fixed Apache::MVC with HTTP::Body fallback to handle url args
[maypole.git] / lib / Apache / MVC.pm
index 3ee8541a3882a58cb9b2a9c10bf18aacf64afc2d..0f6b7d0e9fc8c0dda03506ff398da25900b17cf0 100644 (file)
@@ -1,33 +1,44 @@
 package Apache::MVC;
 
-our $VERSION = '2.10';
+our $VERSION = '2.11';
 
 use strict;
 use warnings;
 
+use URI;
+use URI::QueryParam;
+
 use base 'Maypole';
 use Maypole::Headers;
 use Maypole::Constants;
 
 __PACKAGE__->mk_accessors( qw( ar ) );
 
+our $MODPERL2;
+our $modperl_version;
+
 BEGIN {
-    my $version;
-    eval 'use mod_perl2; $version = $mod_perl2::VERSION; ';
-    if ($@) {
-       use mod_perl;
-       $version = 0;
-       require Apache;
-       require Apache::Request;
+    $MODPERL2  = ( exists $ENV{MOD_PERL_API_VERSION} and
+                        $ENV{MOD_PERL_API_VERSION} >= 2 );
+    if ($MODPERL2) {
+     eval 'use mod_perl2; $modperl_version = $mod_perl2::VERSION;';
+     if ($@) {
+      $modperl_version = $Apache2::RequestRec::VERSION;
+     }
+     require Apache2::RequestIO;
+     require Apache2::RequestRec;
+     require Apache2::RequestUtil;
+     eval 'use Apache2::Const -compile => qw/REDIRECT/;'; # -compile 4 no import
+     require APR::URI;
+     require HTTP::Body;
     } else {
-       require Apache2::RequestIO;
-       require Apache2::RequestRec;
-       require Apache2::RequestUtil;
-       require APR::URI;
-       require Apache2::Request;
+     eval ' use mod_perl; ';
+     require Apache;
+     require Apache::Request;
+     eval 'use Apache::Constants -compile => qw/REDIRECT/;';
+     $modperl_version = 1;
     }
 
-    use constant APACHE2 => $version;
 }
 
 =head1 NAME
@@ -82,7 +93,7 @@ functionality. See L<Maypole> for these:
 
 sub get_request {
     my ($self, $r) = @_;
-    my $ar = (APACHE2) ? Apache2::Request->new($r) : Apache::Request->new($r);
+    my $ar = ($MODPERL2) ? $r : Apache::Request->instance($r);
     $self->ar($ar);
 }
 
@@ -96,12 +107,11 @@ sub parse_location {
     # Reconstruct the request headers
     $self->headers_in(Maypole::Headers->new);
     my %headers;
-    if (APACHE2) { %headers = %{$self->ar->headers_in};
+    if ($MODPERL2) { %headers = %{$self->ar->headers_in};
     } else { %headers = $self->ar->headers_in; }
     for (keys %headers) {
         $self->headers_in->set($_, $headers{$_});
     }
-
     my $path = $self->ar->uri;
     my $loc  = $self->ar->location;
     {
@@ -110,7 +120,6 @@ sub parse_location {
         $path =~ s/^($loc)?\///;
     }
     $self->path($path);
-    
     $self->parse_path;
     $self->parse_args;
 }
@@ -129,12 +138,12 @@ sub parse_args {
 
 =cut
 
-# FIXME: use headers_in to gather host and other information?
-sub redirect_request 
+sub redirect_request
 {
   my $r = shift;
   my $redirect_url = $_[0];
-  my $status = "302";
+  my $status = $MODPERL2 ? eval 'Apache2::Const::REDIRECT;' :
+          eval 'Apache::Constants::REDIRECT;'; # why have to eval this?
   if ($_[1]) {
     my %args = @_;
     if ($args{url}) {
@@ -148,8 +157,8 @@ sub redirect_request
     $status = $args{status} if ($args{status});
   }
 
-  $r->headers_out->set('Status' => $status);
-  $r->headers_out->set('Location' => $redirect_url);
+  $r->ar->status($status);
+  $r->ar->headers_out->set('Location' => $redirect_url);
   return OK;
 }
 
@@ -183,7 +192,7 @@ sub send_output {
         $r->ar->headers_out->set($_ => $r->headers_out->get($_));
     }
 
-    APACHE2 || $r->ar->send_http_header;
+    $MODPERL2 || $r->ar->send_http_header;
     $r->ar->print( $r->output );
 }
 
@@ -196,23 +205,73 @@ sub get_template_root {
     $r->ar->document_root . "/" . $r->ar->location;
 }
 
+=back
+
+=cut
+
+#########################################################
+# private / internal methods and subs
+
+
 sub _mod_perl_args {
     my ( $self, $apr ) = @_;
     my %args;
-    foreach my $key ( $apr->param ) {
+    if ($apr->isa('Apache::Request')) {
+      foreach my $key ( $apr->param ) {
         my @values = $apr->param($key);
         $args{$key} = @values == 1 ? $values[0] : \@values;
+      }
+    } else {
+      my $body = $self->_prepare_body($apr);
+      %args = %{$body->param};
+      my $uri = URI->new($self->ar->uri);
+      foreach my $key ($uri->query_param) {
+       if (ref $args{$key}) {
+         push (@{$args{$key}}, $uri->query_param($key));
+       } else {
+         if ($args{$key}) {
+           $args{$key} = [ $args{$key}, $uri->query_param($key) ];
+         } else {
+           my @args = $uri->query_param($key);
+           if (scalar @args > 1) {
+             $args{$key} = [ $uri->query_param($key) ];
+           } else {
+             $args{$key} = $uri->query_param($key);
+           }
+         }
+       }
+      }
     }
     return %args;
 }
 
-1;
+sub _prepare_body {
+    my ( $self, $r ) = @_;
+
+    unless ($self->{__http_body}) {
+        my $content_type   = $r->headers_in->get('Content-Type');
+        my $content_length = $r->headers_in->get('Content-Length');
+        my $body   = HTTP::Body->new( $content_type, $content_length );
+        my $length = $content_length;
+        while ( $length ) {
+            $r->read( my $buffer, ( $length < 8192 ) ? $length : 8192 );
+            $length -= length($buffer);
+            $body->add($buffer);
+        }
+       $self->{__http_body} = $body;
+    }
+    return $self->{__http_body};
+}
+
 
-=back
 
 =head1 AUTHOR
 
 Simon Cozens, C<simon@cpan.org>
+
+=head1 CREDITS
+
+Aaron Trevena
 Marcus Ramberg, C<marcus@thefeed.no>
 Sebastian Riedel, C<sri@oook.de>
 
@@ -221,3 +280,5 @@ Sebastian Riedel, C<sri@oook.de>
 You may distribute this code under the same terms as Perl itself.
 
 =cut
+
+1;