ASP4

 view release on metacpan or  search on metacpan

lib/ASP4/ModPerl.pm  view on Meta::CPAN


package ASP4::ModPerl;

use strict;
use warnings 'all';
use APR::Table ();
use APR::Socket ();
use Apache2::RequestRec ();
use Apache2::RequestIO ();
use Apache2::Connection ();
use Apache2::RequestUtil ();
use ASP4::HTTPContext ();
use CGI( ':cgi' );


#==============================================================================
sub handler : method
{
  my ($class, $r) = @_;
  
  $ENV{DOCUMENT_ROOT}   = $r->document_root;
  $ENV{REMOTE_ADDR}     = $r->connection->get_remote_host();
  $ENV{HTTP_HOST}       = $r->hostname;
  
  my $context = ASP4::HTTPContext->new();
  $r->pool->cleanup_register(sub { $context->DESTROY });
  
  if( ($r->headers_in->{'content-type'}||'') =~ m/multipart\/form\-data/ )
  {
    $context->{r} = $r;
    if( $@ )
    {
      warn $@;
      $r->status( 500 );
      return $r->status;
    }# end if()
    
    my $handler_class = eval {
      $context->config->web->handler_resolver->new()->resolve_request_handler( $r->uri )
    };
    if( $@ )
    {
      warn $@;
      $r->status( 500 );
      return $r->status;
    }# end if()
    
    return 404 unless $handler_class;
    
    eval {
      my $cgi = CGI->new( $r );
      my %args = map { my ($k,$v) = split /\=/, $_; ( $k => $v ) } split /&/, $ENV{QUERY_STRING};
      map { $cgi->param($_ => $args{$_}) } keys %args;
      $context->setup_request( $r, $cgi);
      $context->execute;
    };
    if( $@ )
    {
      if( $@ =~ m/Software\scaused\sconnection\sabort/ )
      {
        return 0;
      }# end if()
      warn $@;
      $r->status( 500 );
    }# end if()
    return $r->status =~ m/^2/ ? 0 : $r->status == 500 ? 0 : $r->status;
  }
  else
  {
    my $cgi = CGI->new( $r );
    eval {
      $context->setup_request( $r, $cgi );
      $context->execute;
    };
    if( $@ =~ m/Software\scaused\sconnection\sabort/ )
    {
      return 0;
    }# end if()
    warn $@ if $@;
    
    
    if( $context->response->Status == 200 )
    {
      $r->status( 200 );
      if( $context->did_end && $context->did_send_headers )
      {
        $r->rflush();
      }# end if()
      return 0;
    }
    else
    {
      $r->status( $context->response->Status );
      if( $context->did_end && $context->did_send_headers )
      {
        $r->rflush();
      }
      else
      {
        # Make sure we send our headers now, since we haven't done so already:
        $context->send_headers();
        $context->did_end(1);
        $r->rflush();
      }# end if()
      return $context->response->Status == 500 ? 0 : $context->response->Status;
    }# end if()
  }# end if()
  
}# end handler()

1;# return true:

=pod



( run in 1.058 second using v1.01-cache-2.11-cpan-39bf76dae61 )