Changeset 4993

Show
Ignore:
Timestamp:
01/20/08 00:51:09 (5 years ago)
Author:
tokuhirom
Message:

Proxy サーバーとして動作するモードを削除。正直いらなくね。

Location:
lang/perl/Moxy/trunk
Files:
1 removed
4 modified

Legend:

Unmodified
Added
Removed
  • lang/perl/Moxy/trunk/Makefile.PL

    r4942 r4993  
    77 
    88requires('HTTP::MobileAgent'); 
    9 requires('HTTP::Proxy'); 
    109requires('CGI'); 
    1110requires('FindBin'); 
     
    2120requires('Encode::JP::Mobile' => 0.22); 
    2221requires 'HTML::ReplacePictogramMobileJp' => 0.01; 
     22requires 'POE::Component::Server::HTTP' => 0.09; 
    2323 
    2424build_requires('Test::More'); 
  • lang/perl/Moxy/trunk/config.yaml

    r4857 r4993  
    11--- 
    22global: 
    3   application: 
    4     host: localhost 
    5     port: 10000 
    63  storage: 
    74    module: DBM_File 
     
    2825 
    2926plugins: 
    30   - module: Application 
    3127  - module: Pictogram 
    3228  - module: HTMLWidth 
  • lang/perl/Moxy/trunk/lib/Moxy/Plugin/XMLisHTML.pm

    r3983 r4993  
    77 
    88    $context->register_hook( 
    9         response_filter_header => sub { 
     9        response_filter => sub { 
    1010            my ($context, $args) = @_; 
    1111 
  • lang/perl/Moxy/trunk/lib/Moxy/Server/HTTPProxy.pm

    r4971 r4993  
    55use Encode; 
    66use HTTP::Proxy ':log'; 
    7 use HTTP::Proxy::BodyFilter::simple; 
    87use HTTP::Proxy::HeaderFilter::simple; 
    98use HTTP::Proxy::BodyFilter::complete; 
    109use Scalar::Util qw/blessed/; 
     10use LWP::UserAgent; 
     11use URI; 
     12use HTML::Parser; 
     13use HTML::Entities; 
     14use URI::Escape; 
     15use MIME::Base64; 
     16 
     17our $TIMEOUT = 10; # TODO: configurable 
    1118 
    1219sub new { 
     
    2330 
    2431    if ($config->{logmask}) { 
    25         my $mask = 0; # this is bitmask. 
     32        my $bitmask = 0; 
    2633        for my $const ( @{$config->{logmask}} ) { 
    27             $mask |= HTTP::Proxy->$const; 
    28         } 
    29         $proxy->logmask($mask); 
    30     } 
     34            $bitmask |= HTTP::Proxy->$const; 
     35        } 
     36        $proxy->logmask($bitmask); 
     37    } 
     38 
     39    $context->register_hook( 
     40        control_panel => sub { 
     41            my ($context, $args) = @_; 
     42 
     43            my $base = URI->new($args->{response}->request->uri); 
     44            $base->query_form({}); 
     45            return $class->_render_control_panel($base, $args->{response}->request->uri); 
     46        }, 
     47    ); 
    3148 
    3249    $proxy->push_filter( 
    3350        mime     => undef, 
     51        response => HTTP::Proxy::BodyFilter::complete->new, 
    3452        request  => HTTP::Proxy::HeaderFilter::simple->new( 
    3553            sub { 
    3654                my ($filter, $x, $request) = @_; 
    3755 
    38                 my $response = $context->run_hook_and_get_response( 
    39                     'request_filter_before_auth', 
    40                     +{ 
    41                         request => $request,    # HTTP::Request object 
    42                     } 
    43                 ); 
    44                 if ($response) { 
     56                my $uri = URI->new($request->uri); 
     57                $context->log(debug => "Request URI: $uri"); 
     58 
     59                my $base = $uri->clone; 
     60                $base->query_form({}); 
     61 
     62                my $auth_header = $request->header('Authorization'); 
     63                $context->log(debug => "Authorization header: $auth_header"); 
     64                if ($auth_header =~ /^Basic (.+)$/) { 
     65                    my $auth = decode_base64($1); 
     66                    $context->log(debug => "auth: $auth"); 
     67                    my $url = +{$uri->query_form}->{q}; 
     68                    $context->log(info => "REQUEST $auth, @{[ $url || '' ]}"); 
     69                    my $response = 
     70                    $class->_make_response( $context, $url, $request, $base, 
     71                        $auth ); 
    4572                    return $filter->proxy->response($response); # finished 
    46                 } 
    47  
    48                 # password is ignored by Moxy. 
    49                 my ($user, $pass) = $filter->proxy->hop_headers->proxy_authorization_basic(); 
    50                 if ($user) { 
    51                     $filter->proxy->stash(user => $user); 
    5273                } else { 
    53                     my $response = HTTP::Response->new( 407, 'Moxy Authentication required' ); 
    54                     $response->header('Proxy-Authenticate' => 'Basic realm="Moxy(password is dummy)"'); 
    55                     return $filter->proxy->response($response); 
    56                 } 
    57  
    58                 $context->run_hook( 
    59                     'request_filter_process_agent', 
    60                     {   request => $request, # HTTP::Request object 
    61                         user    => $user, 
    62                     } 
    63                 ); 
    64  
    65                 my $agent = $context->get_ua_info($_[1]->header('User-Agent')); 
    66                 my $carrier = $agent->{agent} ? HTTP::MobileAgent->new($agent->{agent})->carrier : 'N'; 
    67  
    68                 for my $hook ('request_filter', "request_filter_$carrier") { 
    69                     my $response = $context->run_hook_and_get_response( 
    70                         $hook, 
    71                         +{ 
    72                             request => $request,    # HTTP::Request object 
    73                             agent   => $agent, 
    74                             user    => $user, 
    75                         } 
     74                    my $response = HTTP::Response->new(401, 'Moxy needs authentication'); 
     75                    $response->header( 'WWW-Authenticate' => 
     76qq{Basic realm="Moxy needs basic auth.Only for identification.Password is dummy."} 
    7677                    ); 
    77                     if ($response) { 
    78                         return $filter->proxy->response($response); # finished 
    79                     } 
    80                 } 
    81             } 
    82         ), 
    83         response => HTTP::Proxy::BodyFilter::complete->new, 
    84         response => HTTP::Proxy::BodyFilter::simple->new( 
    85             make_response_filter($context, 'response_filter') 
    86         ), 
    87         response => HTTP::Proxy::HeaderFilter::simple->new( 
    88             make_response_filter($context, 'response_filter_header') 
     78                    $response->content('authentication required'); 
     79                    return $filter->proxy->response($response); # finished 
     80                } 
     81            } 
    8982        ), 
    9083    ); 
     
    10598} 
    10699 
    107 sub make_response_filter { 
    108     my ($context, $key) = @_; 
    109  
    110     return sub { 
    111         my ($filter, $bodyref, $response) = @_; 
    112  
    113         my $agent = $context->get_ua_info($response->request->header('User-Agent')); 
    114         my $carrier = $agent->{agent} ? HTTP::MobileAgent->new($agent->{agent})->carrier : 'N'; 
    115  
    116         for my $hook ($key, "${key}_$carrier") { 
    117             $context->run_hook( 
    118                 $hook, 
    119                 {   response    => $response, 
    120                     content_ref => $bodyref, 
    121                     agent       => $agent, 
    122                     user        => $filter->proxy->stash('user'), 
    123                 } 
    124             ); 
    125         } 
    126     }; 
     100sub _render_control_panel { 
     101    my ($class, $base, $current_url) = @_; 
     102 
     103    return sprintf(<<"...", encode_entities($current_url)); 
     104    <form method="get" action="$base"> 
     105        <input type="text" name="q" value="\%s" size="40" /> 
     106        <input type="submit" value="go" /> 
     107    </form> 
     108... 
     109} 
     110 
     111sub _ua { 
     112    my ($class, $proxy_url) = @_; 
     113 
     114    my $ua = LWP::UserAgent->new( 
     115        timeout       => $TIMEOUT, 
     116        max_redirects => 0, 
     117    ); 
     118    $ua; 
     119} 
     120 
     121sub _make_response { 
     122    my ($class, $context, $url, $src_req, $base, $auth) = @_; 
     123 
     124    if ($url) { 
     125        # do proxy 
     126        my $res = $class->_do_request($context, $src_req, $url, $auth); 
     127        $context->log(debug => '-- response status: ' . $res->code); 
     128 
     129        if ($res->code == 302) { 
     130            # rewrite redirect 
     131            $res->header( 'Location' => $base . '?q=' 
     132                  . uri_escape( $res->header('Location') ) ); 
     133        } else { 
     134            my $content_type = $res->header('Content-Type'); 
     135            if ($content_type =~ /html/i) { 
     136                $res->content( _rewrite($base, $res->content, $url) ); 
     137            } 
     138        } 
     139        return $res; 
     140    } else { 
     141        # please input url. 
     142        my $res = HTTP::Response->new(200, 'about:blank'); 
     143        $res->header('Content-Type' => 'text/html; charset=utf8'); 
     144        my $panel = $class->_render_control_panel($base, ''); 
     145        $res->content(qq{<html><head></head><body>$panel</body></html>}); 
     146        return $res; 
     147    } 
     148} 
     149 
     150sub _do_request { 
     151    my ($class, $context, $src_req, $url, $auth) = @_; 
     152 
     153    # make request 
     154    my $req = $src_req->clone; 
     155    $req->uri($url); 
     156    $req->header('Host' => URI->new($url)->host); 
     157 
     158    $context->run_hook( 
     159        'request_filter_process_agent', 
     160        {   request => $req, # HTTP::Request object 
     161            user    => $auth, 
     162        } 
     163    ); 
     164    my $agent = $context->get_ua_info($req->header('User-Agent')); 
     165    my $carrier = $agent->{agent} ? HTTP::MobileAgent->new($agent->{agent})->carrier : 'N'; 
     166    for my $hook ('request_filter', "request_filter_$carrier") { 
     167        my $response = $context->run_hook_and_get_response( 
     168            $hook, 
     169            +{ 
     170                request => $req,    # HTTP::Request object 
     171                agent   => $agent, 
     172                user    => $auth, 
     173            } 
     174        ); 
     175        if ($response) { 
     176            return $response; # finished 
     177        } 
     178    } 
     179 
     180    # do request 
     181    my $ua = $class->_ua; 
     182    my $response = $ua->request($req); 
     183    my $bodyref = \($response->content); 
     184    for my $hook ('response_filter', "response_filter_$carrier") { 
     185        $context->run_hook( 
     186            $hook, 
     187            {   response    => $response, # HTTP::Response object 
     188                content_ref => $bodyref, # response body's scalarref. 
     189                agent       => $agent, 
     190                user        => $auth, 
     191            } 
     192        ); 
     193    } 
     194    $response->content($$bodyref); 
     195    $response; 
     196} 
     197 
     198sub _rewrite { 
     199    my ($base, $html, $url) = @_; 
     200 
     201    my $output = ''; 
     202    my $base_url = URI->new($url); 
     203    my $parser = HTML::Parser->new( 
     204        api_version   => 3, 
     205        start_h       => [ sub { 
     206            my ($tagname, $attr, $orig) = @_; 
     207 
     208            if ($tagname eq 'a' || $tagname eq 'A') { 
     209                $output .= "<$tagname"; 
     210                my @parts; 
     211                my $href = delete $attr->{href}; 
     212                if ($href) { 
     213                    $output .= " "; 
     214                    push @parts, 
     215                      sprintf( qq{href="$base?q=%s"}, 
     216                        uri_escape(URI->new($href)->abs($base_url)) ); 
     217                } 
     218                push @parts, map { sprintf qq{%s="%s"}, encode_entities($_), encode_entities($attr->{$_}) } keys %$attr; 
     219                $output .= join " ", @parts; 
     220                $output .= ">"; 
     221            } elsif ($tagname =~ /form/i) { 
     222                $output .= "<$tagname"; 
     223                my @parts; 
     224                my $action = delete $attr->{action}; 
     225                if ($action) { 
     226                    $output .= " "; 
     227                    push @parts, sprintf(qq{action="$base?q=%s"}, 
     228                        uri_escape(URI->new($action)->abs($base_url)) 
     229                    ); 
     230                } 
     231                push @parts, map { sprintf qq{$_="%s"}, encode_entities($attr->{$_}) } keys %$attr; 
     232                $output .= join " ", @parts; 
     233                $output .= ">"; 
     234            } elsif ($tagname =~ /img/i) { 
     235                $output .= "<$tagname"; 
     236                my @parts; 
     237                my $src = delete $attr->{src}; 
     238                if ($src) { 
     239                    $output .= " "; 
     240                    push @parts, sprintf(qq{src="$base?q=%s"}, 
     241                        uri_escape(URI->new($src)->abs($base_url)) 
     242                    ); 
     243                } 
     244                push @parts, map { sprintf qq{%s="%s"}, encode_entities($_), encode_entities($attr->{$_}) } grep !/^\/$/, keys %$attr; 
     245                $output .= join " ", @parts; 
     246                $output .= ">"; 
     247            } else { 
     248                $output .= $orig; 
     249                return; 
     250            } 
     251        }, "tagname, attr, text" ], 
     252        end_h  => [ sub { $output .= shift }, "text"], 
     253        text_h => [ sub { $output .= shift }, "text"], 
     254    ); 
     255 
     256    $parser->boolean_attribute_value('__BOOLEAN__'); 
     257    $parser->parse($html); 
     258    $output; 
    127259} 
    128260