/usr/local/CPAN/mobirc/App/Mobirc/Web/Handler.pm
package App::Mobirc::Web::Handler;
use Moose;
use Scalar::Util qw/blessed/;
use Data::Visitor::Encode;
use HTTP::MobileAgent;
use HTTP::MobileAgent::Plugin::Charset;
use HTTP::Session;
use HTTP::Session::Store::OnMemory;
use HTTP::Session::State::Cookie;
use HTTP::Session::State::GUID;
use HTTP::Session::State::MobileAttributeID;
use Module::Find;
use App::Mobirc;
use App::Mobirc::Util;
use App::Mobirc::Web::Router;
useall 'App::Mobirc::Web::C';
my $session_store = HTTP::Session::Store::OnMemory->new(data => {});
sub context () { App::Mobirc->context } ## no critic
sub handler {
my $req = shift;
my $session = _create_session($req);
my $res = _handler($req, $session);
context->run_hook('response_filter', $res);
$session->response_filter( $res );
$res;
}
sub _handler {
my ($req, $session) = @_;
context->run_hook('request_filter', $req);
if ($session->get('authorized')) {
return process_request_authorized($req, $session);
} else {
return process_request_noauth($req, $session);
}
}
sub _create_session {
my $req = shift;
my $conf = context->config->{global}->{session};
my $ma = HTTP::MobileAttribute->new($req->headers);
HTTP::Session->new(
store => $session_store,
state => sub {
if ($ma->is_docomo) {
HTTP::Session::State::GUID->new(
mobile_attribute => $ma,
);
} elsif ($ma->can('user_id') && $ma->user_id) {
HTTP::Session::State::MobileAttributeID->new(
mobile_attribute => $ma,
);
} else {
HTTP::Session::State::Cookie->new(
name => 'mobirc_sid',
expires => '+1y',
)
}
}->(),
request => $req,
);
}
sub authorize {
my $req = shift;
if (context->run_hook_first('authorize', $req)) {
DEBUG "AUTHORIZATION SUCCEEDED";
return 1; # authorization succeeded.
} else {
return 0; # authorization failed
}
}
sub process_request_authorized {
my ($req, $session) = @_;
if (my $rule = App::Mobirc::Web::Router->match($req)) {
return do_dispatch($rule, $req, $session);
} else {
# hook by plugins
if (my $res = context->run_hook_first( 'httpd', $req )) {
# XXX we should use html filter?
return $res;
}
# doesn't match.
return res_404($req);
}
}
sub process_request_noauth {
my ($req, $session) = @_;
if (my $rule = App::Mobirc::Web::Router->match($req)) {
if ($rule->{controller} eq 'Account') {
return do_dispatch($rule, $req, $session);
} else {
return HTTP::Engine::Response->new(
status => 302,
headers => {
Location => '/account/login'
}
);
}
} else {
return res_404($req);
}
}
sub do_dispatch {
my ($rule, $req, $session) = @_;
my $controller = "App::Mobirc::Web::C::$rule->{controller}";
my $meth = $rule->{action};
my $post_meth = "post_dispatch_$meth";
my $get_meth = "dispatch_$meth";
my $args = Data::Visitor::Encode->decode( $req->mobile_agent->encoding, $rule->{args} );
$args->{session} = $session;
if ( $req->method =~ /POST/i && $controller->can($post_meth)) {
return $controller->$post_meth($req, $args);
} else {
return $controller->$get_meth($req, $args);
}
}
sub res_404 {
my ($req, ) = @_;
my $uri = $req->uri->path;
warn "dan the 404 not found: $uri" if $uri ne '/favicon.ico';
return HTTP::Engine::Response->new(
status => 404,
body => "404 not found: $uri",
);
}
no Moose;__PACKAGE__->meta->make_immutable;
1;