#!/usr/bin/perl
# -*- mode: perl; coding: utf-8 -*-
# keitairc
-# $Id: keitairc,v 1.82 2010-05-19 00:36:18 ishikawa Exp $
-# $Source: /home/ishikawa/work/keitairc/tmp/keitairc/keitairc,v $
#
-# Copyright (c) 2003-2008 Jun Morimoto <morimoto@mrmt.net>
+# Copyright (c) 2003-2010 Jun Morimoto <morimoto@mrmt.net>
# This program is covered by the GNU General Public License 2
#
# Depends: libpoe-component-irc-perl,
use URI::Escape;
use HTML::Template;
use HTTP::Response;
+use HTTP::Status;
use FindBin;
use lib ("$FindBin::Bin/lib", '/usr/share/keitairc/lib');
use strict;
use warnings;
-our $cf = new Keitairc::Config({version => '2.0', argv => \@ARGV});
-our $ib = new Keitairc::IrcBuffer({history => $cf->web_lines()});
-our $sm = new Keitairc::SessionManager({default_ttl => $cf->session_ttl()});
-our $pl = new Keitairc::Plugins({config => $cf});
+our $cf = new Keitairc::Config({version => '2.1a1', argv => \@ARGV});
# daemonize
if($cf->daemonize()){
- use Proc::Daemon;
-
- Proc::Daemon::Init;
- if(length $cf->pid_dir()){
- if (open(PID, '> ' . $cf->pid_dir() . '/' . $cf->pid_file())) {
- print PID $$, "\n";
- close(PID);
+ if (eval 'require Proc::Daemon') {
+ require Proc::Daemon;
+ Proc::Daemon::Init();
+ if(length $cf->pid_dir()){
+ if (open(PID, '> ' . $cf->pid_dir() . '/' . $cf->pid_file())) {
+ print PID $$, "\n";
+ close(PID);
+ }
}
+ $poe_kernel->has_forked if ($poe_kernel->can('has_forked'));
+ } else {
+ warn('Proc::Daemon module is not installed, could not daemonize');
}
- $poe_kernel->has_forked if ($poe_kernel->can('has_forked'));
}
+our $log = new Keitairc::Log({config => $cf});
+our $ib = new Keitairc::IrcBuffer({history => $cf->web_lines()});
+our $sm = new Keitairc::SessionManager({default_ttl => $cf->session_ttl()});
+our $pl = new Keitairc::Plugins({config => $cf});
+
# create irc component
our $irc = POE::Component::IRC->spawn(
Alias => 'keitairc_irc',
# the responses as they are and finish up.
if($request->isa('HTTP::Response')){
$heap->{client}->put($request);
+ $log->log_error($request->as_string());
}elsif(my $response = dispatch($request)){
$heap->{client}->put($response);
+ $log->log_access($heap->{'remote_ip'}, $request, $response);
}
$kernel->yield('shutdown');
my $uri = $request->uri();
my $ci = new Keitairc::ClientInfo($request);
- Keitairc::Log::log_debug("dispatch: $uri");
+ $log->log_debug("dispatch: $uri");
{
# chop off $cf->web_root()
if($sm->verify({session_id => $1, user_agent => $ci->user_agent()})){
return add_cookie($pl->{plugins}->{$name}->{action_imprementation}($request, $name, $1, $2), $1);
}
- if ($ci->is_ipod() && $cf->webkit_newui()) {
- return action_401($request);
+ if ($ci->is_webkit() && $cf->webkit_newui()) {
+ return action_error($request, 401);
} else {
return action_redirect_root($request);
}
}
}
- return action_public($request, $uri) || action_404($request);
+ return action_public($request, $uri) || action_error($request, 404);
}
################################################################
my $content = $request->decoded_content();
my ($password) = ($content =~ /^password=(.*)/);
- Keitairc::Log::log_debug("password [$password]");
- Keitairc::Log::log_debug("web_password [" . $cf->web_password() . "]");
+ $log->log_debug("password [$password]");
+ $log->log_debug("web_password [" . $cf->web_password() . "]");
if($cf->web_password() eq $password){
my $s = $sm->add($ci->user_agent(), $ci->serial_key());
my $view = new Keitairc::View($cf, $ci, $s->{id});
- if ($ci->is_ipod() && $cf->webkit_newui()) {
+ if ($ci->is_webkit() && $cf->webkit_newui()) {
return add_cookie($view->redirect('/'), $s->{id});
} else {
return $view->redirect("/$s->{id}/index");
}
################################################################
-sub action_401{
+sub action_error {
my $request = shift;
+ my $error_code = shift;
my $ci = new Keitairc::ClientInfo($request);
my $view = new Keitairc::View($cf, $ci);
- return $view->render('401.html', { action => $request->uri(), _http_status_code => 401 });
-}
-
-sub action_404{
- my $request = shift;
- my $ci = new Keitairc::ClientInfo($request);
- my $view = new Keitairc::View($cf, $ci);
- return $view->render('404.html', { action => $request->uri(), _http_status_code => 404 });
+ return $view->render('error.html', { action => $request->uri(),
+ _http_status_code => $error_code,
+ _http_status_message => status_message($error_code) });
}
################################################################
-sub action_public{
+sub action_public {
my $request = shift;
my $uri = shift; # such as '/favicon.ico'
my $ci = new Keitairc::ClientInfo($request);
my $view = new Keitairc::View($cf, $ci);
- return $view->public($uri);
+ return $view->public($request, $uri);
}
################################################################
if(length $docomo_foma_icc){
if(my $s = $sm->verify({serial_key => $docomo_foma_icc,
user_agent => $ci->user_agent()})){
- Keitairc::Log::log_debug("redirect to /$s->{id}/index from docomo_foma_icc");
+ $log->log_debug("redirect to /$s->{id}/index from docomo_foma_icc");
my $view = new Keitairc::View($cf, $ci, $s->{id});
return $view->redirect("/$s->{id}/index");
}
if($docomo_foma_icc eq $cf->docomo_foma_icc()){
my $s = $sm->add($ci->user_agent(), $docomo_foma_icc);
- Keitairc::Log::log_debug("redirect to /$s->{id}/index from docomo_foma_icc");
+ $log->log_debug("redirect to /$s->{id}/index from docomo_foma_icc");
my $view = new Keitairc::View($cf, $ci, $s->{id});
return $view->redirect("/$s->{id}/index");
}
if(length $docomo_imodeid){
if(my $s = $sm->verify({serial_key => $docomo_imodeid,
user_agent => $ci->user_agent()})){
- Keitairc::Log::log_debug("redirect to /$s->{id}/index from docomo_imodeid");
+ $log->log_debug("redirect to /$s->{id}/index from docomo_imodeid");
my $view = new Keitairc::View($cf, $ci, $s->{id});
return $view->redirect("/$s->{id}/index");
}
if($docomo_imodeid eq $cf->docomo_imodeid()){
my $s = $sm->add($ci->user_agent(), $docomo_imodeid);
- Keitairc::Log::log_debug("redirect to /$s->{id}/index from docomo_imodeid");
+ $log->log_debug("redirect to /$s->{id}/index from docomo_imodeid");
my $view = new Keitairc::View($cf, $ci, $s->{id});
return $view->redirect("/$s->{id}/index");
}
if(defined($session_id) && length($session_id)){
if($sm->verify({session_id => $session_id,
user_agent => $ci->user_agent()})){
- Keitairc::Log::log_debug("redirect to /$session_id/index from cookie");
+ $log->log_debug("redirect to /$session_id/index from cookie");
my $view = new Keitairc::View($cf, $ci, $session_id);
- if ($ci->is_ipod() && $cf->webkit_newui()) {
+ if ($ci->is_webkit() && $cf->webkit_newui()) {
return add_cookie($view->render('root_home.html', {sid => $session_id}), $session_id);
} else {
return $view->redirect("/$session_id/index");
if(length $subscriber_id){
if(my $s = $sm->verify({serial_key => $subscriber_id,
user_agent => $ci->user_agent()})){
- Keitairc::Log::log_debug("redirect to /$s->{id}/index from subscriber_id");
+ $log->log_debug("redirect to /$s->{id}/index from subscriber_id");
my $view = new Keitairc::View($cf, $ci, $s->{id});
return $view->redirect("/$s->{id}/index");
}
if($subscriber_id eq $cf->au_subscriber_id()){
my $s = $sm->add($ci->user_agent(), $subscriber_id);
- Keitairc::Log::log_debug("redirect to /$s->{id}/index from au_subscriber_id");
+ $log->log_debug("redirect to /$s->{id}/index from au_subscriber_id");
my $view = new Keitairc::View($cf, $ci, $s->{id});
return $view->redirect("/$s->{id}/index");
}
if(length $serial_key){
if(my $s = $sm->verify({serial_key => $serial_key,
user_agent => $ci->user_agent()})){
- Keitairc::Log::log_debug("redirect to /$s->{id}/index from softbank serial_key");
+ $log->log_debug("redirect to /$s->{id}/index from softbank serial_key");
my $view = new Keitairc::View($cf, $ci, $s->{id});
return $view->redirect("/$s->{id}/index");
}
if($serial_key eq $cf->softbank_serial_key()){
my $s = $sm->add($ci->user_agent(), $serial_key);
- Keitairc::Log::log_debug("redirect to /$s->{id}/index from softbank_serial_key");
+ $log->log_debug("redirect to /$s->{id}/index from softbank_serial_key");
my $view = new Keitairc::View($cf, $ci, $s->{id});
return $view->redirect("/$s->{id}/index");
}
if(length $userid){
if(my $s = $sm->verify({serial_key => $userid,
user_agent => $ci->user_agent()})){
- Keitairc::Log::log_debug("redirect to /$s->{id}/index from userid");
+ $log->log_debug("redirect to /$s->{id}/index from userid");
my $view = new Keitairc::View($cf, $ci, $s->{id});
return $view->redirect("/$s->{id}/index");
}
if($userid eq $cf->emobile_userid()){
my $s = $sm->add($ci->user_agent(), $userid);
- Keitairc::Log::log_debug("redirect to /$s->{id}/index from emobile_userid");
+ $log->log_debug("redirect to /$s->{id}/index from emobile_userid");
my $view = new Keitairc::View($cf, $ci, $s->{id});
return $view->redirect("/$s->{id}/index");
}
if(length($message)){
($message, $timestamp) = split(/&/, $message);
+
$timestamp =~ s/^stamp=//g;
$message =~ s/^m=//;
$message =~ s/\+/ /g;
$message = uri_unescape($message);
- if($ci->is_ipod()){
- $message = fix_iui_escape($message);
+
+ if($ci->is_webkit() && !$cf->webkit_newui()){
+ $message = fix_webkit_escape($message);
}
}
-
+ if ($cf->webkit_newui()) {
+ # ajax で投げ込んでるので utf8 できます
+ $message = Encode::decode('utf8', $message);
+ } else {
+ $message = Encode::decode($cf->web_charset(), $message);
+ }
return ($message, $timestamp);
}
my ($message, $timestamp) = parse_message($request);
if(length($message) && length($channel)){
- my $jis = $message;
- Encode::from_to($jis, $cf->web_charset(), $cf->irc_charset());
- my $euc = Encode::decode($cf->web_charset(), $message);
if($ib->update_timestamp($timestamp)){
- $irc->yield(privmsg => $channel => $jis);
+ my $enc_message = Encode::encode($cf->irc_charset(), $message);
+ my $enc_channel = Encode::encode($cf->irc_charset(), $channel);
+ $irc->yield(privmsg => $enc_channel => $enc_message);
my $cid = $ib->name2cid($channel);
- $ib->add_message($cid, $euc, $cf->irc_nick());
+ $ib->add_message($cid, $message, $cf->irc_nick());
}
}
}
my ($message, $timestamp) = parse_message($request);
if(length($message)){
- Encode::from_to($message, $cf->web_charset(), $cf->irc_charset());
if($message =~ s|^/||) {
my ($params, $trailing) = split(/ :/, $message, 2);
my @postcmd = split(/ /, $params);
return;
}
}
- $irc->yield(@postcmd);
+ $irc->yield(map { Encode::encode($cf->irc_charset(), $_) } @postcmd);
}
}
}
################################################################
-# posted string from iPhone/iPod touch (with iui framework)
+# posted string from Webkit browser
# contains escaped utf-8 in the form %uXXXX
# and may contains escaped Shift-JIS (web_charset) in the form \xXX
# when operated from Safari/Mac OS X
-sub fix_iui_escape{
+sub fix_webkit_escape{
# charset: $cf->irc_charset()
my $in = shift;
$in =~ s/\\x([0-9A-F]{2})/pack('C',hex($1))/egi;
- my $pi = Encode::decode($cf->web_charset(), $in);
- $pi =~ s/%u([0-9A-F]{4})/pack('U',hex($1))/egi;
- return Encode::encode($cf->web_charset(), $pi);
+ #my $pi = Encode::decode('utf8', $in);
+ $in =~ s/%u([0-9A-F]{4})/pack('U',hex($1))/egi;
+ return $in;
}
__END__