Show
Ignore:
Timestamp:
08/28/08 08:08:56 (4 months ago)
Author:
tokuhirom
Message:

rewrote

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • lang/perl/HTTP-Engine-Compat/trunk/lib/HTTP/Engine/Compat.pm

    r18062 r18361  
    55#extends 'HTTP::Engine'; 
    66use HTTP::Engine; 
    7 use HTTP::Engine::RequestProcessor; 
    87use HTTP::Engine::Request; 
     8use HTTP::Engine::ResponseFinalizer; 
    99use HTTP::Engine::Compat::Context; 
     10use HTTP::Engine::Role::Interface; 
     11 
     12our $rh; 
     13my @wraps; 
    1014 
    1115sub import { 
    12     my($class, %args) = @_; 
    13  
    14     $class->_wrap( \&_extract_context ); 
     16    my ( $class, %args ) = @_; 
    1517 
    1618    $class->_modify( 
     
    4345 
    4446                    if (@_) { 
    45                         $self->location( shift ); 
     47                        $self->location(shift); 
    4648                        $self->status( shift || 302 ); 
    4749                    } 
     
    5456 
    5557    $class->_modify( 
    56         'HTTP::Engine::ResponseFinalizer', 
     58        'HTTP::Engine', 
    5759        sub { 
    5860            my $meta = shift; 
    5961            $meta->add_around_method_modifier( 
    60                 finalize => sub { 
    61                     my $code = shift; 
    62                     my ($self, $req, $res) = @_; 
    63                     if (my $location = $res->location) { 
    64                         $res->header( Location => $req->absolute_url($location) ); 
    65                         $res->body($res->status . ': Redirect') unless $res->body; 
    66                     } 
    67                     $code->(@_); 
     62                'new' => sub { 
     63                    my ($next, @args) = @_; 
     64                    my $instance = $next->(@args); 
     65 
     66                    $class->_setup_interface($instance->interface->meta); 
     67                    $instance; 
    6868                }, 
    69             ) 
    70         } 
    71     ); 
     69            ); 
     70        }, 
     71    ); 
     72 
     73    do { 
     74        my $meta = 
     75          Class::MOP::Class->initialize('HTTP::Engine::ResponseFinalizer') 
     76          or die "cannot get meta"; 
     77        $meta->add_around_method_modifier( 
     78            finalize => sub { 
     79                my $code = shift; 
     80                my ( $self, $req, $res ) = @_; 
     81                if ( my $location = $res->location ) { 
     82                    $res->header( Location => $req->absolute_url($location) ); 
     83                    $res->body( $res->status . ': Redirect' ) unless $res->body; 
     84                } 
     85                $code->(@_); 
     86            }, 
     87        ); 
     88    }; 
    7289 
    7390    return unless $args{middlewares} && ref $args{middlewares} eq 'ARRAY'; 
    74     $class->load_middlewares(@{ $args{middlewares} }); 
     91    $class->load_middlewares( @{ $args{middlewares} } ); 
     92} 
     93 
     94my %initialized; 
     95sub _setup_interface { 
     96    my ($class, $inter) = @_; 
     97 
     98    $inter->make_mutable; 
     99 
     100    $inter->add_method( 
     101        'call_handler' => sub { 
     102            my $req = shift; 
     103            $rh->( $req ); 
     104        } 
     105    ); 
     106    $class->_wrap( $inter, \&_extract_context ); 
     107    $class->_wrap( $inter, $_ ) for @wraps; 
     108 
     109    $inter->make_mutable; 
     110    $inter->add_method( 
     111        'handle_request' => sub { 
     112            my ( $self, %args ) = @_; 
     113 
     114            my $c = HTTP::Engine::Compat::Context->new( 
     115                req => HTTP::Engine::Request->new( 
     116                    request_builder => $self->request_builder, 
     117                    %args, 
     118                ), 
     119                res => HTTP::Engine::Response->new( status => 200 ), 
     120            ); 
     121 
     122            eval { 
     123                local $rh = $self->request_handler; 
     124                my $res = $inter->get_method('call_handler')->($c); 
     125                if (Scalar::Util::blessed($res) && $res->isa('HTTP::Engine::Response')) { 
     126                    $c->res( $res ); 
     127                } 
     128            }; 
     129            if ( my $e = $@ ) { 
     130                print STDERR $e; 
     131                $c->res->status(500); 
     132                $c->res->body('internal server error'); 
     133            } 
     134 
     135            HTTP::Engine::ResponseFinalizer->finalize( $c->req => $c->res ); 
     136 
     137            $self->response_writer->finalize( $c->req => $c->res ); 
     138            return $c->res; 
     139        }, 
     140    ); 
     141 
     142    $inter->make_immutable; 
    75143} 
    76144 
     
    101169 
    102170    if ($pkg->meta->has_method('wrap')) { 
    103         $class->_wrap( $pkg->meta->get_method('wrap')->body ); 
    104         $class->_wrap( \&_extract_context ); 
     171        push @wraps, $pkg->meta->get_method('wrap')->body; 
    105172    } 
    106173} 
    107174 
    108175sub _wrap { 
    109     my ($class, $code ) = @_; 
    110     $class->_modify( 
    111         'HTTP::Engine::RequestProcessor', 
    112         sub { 
    113             my $meta = shift; 
    114             $meta->add_around_method_modifier( 
    115                 call_handler => $code, 
    116             ); 
    117         }, 
    118     ); 
     176    my ($class, $interface, $code ) = @_; 
     177    $interface->make_mutable; 
     178    $interface->add_around_method_modifier( 
     179        call_handler => $code, 
     180    ); 
     181    $interface->make_immutable; 
    119182} 
    120183 
     
    124187    # process argument 
    125188    if (Scalar::Util::blessed($arg) ne 'HTTP::Engine::Compat::Context') { 
    126         $arg = HTTP::Engine::Compat::Context->new( 
    127             req => $arg, 
    128             res => HTTP::Engine::Response->new( 
    129                 status => 200 
    130             ), 
    131         ); 
    132189    } 
    133190 
     
    148205    my ($class, $target, $cb) = @_; 
    149206    my $meta = $target->meta; 
    150     $meta->make_mutable; 
     207    $meta->make_mutable if $meta->can('make_mutable'); 
    151208    $cb->($meta); 
    152     $meta->make_immutable; 
     209    $meta->make_immutable if $meta->can('make_immutable'); 
    153210} 
    154211