As Sloth As Possible

��ǽ�ʸ¤�ʥޥ���ΤǤ��ꤿ��

������HTTP::Engine

���������Ф��ʤ��������ɤ��Υ����ɤϰ��ڥƥ��Ȥ�񤫤ʤ��ä����ɡ�����Ϥ������̵�����ޤä�����äƼ����ȿ���뤷��Ruby�ΤȤ��Ϥ�����Spec�񤤤��Τ�Perl�ΤȤ��Ͻ񤫤ʤ����Ȥ��դ����Ƥ롢�Ȼפä��Τǥƥ��Ȥ�񤤤Ƥߤ뤳�Ȥˤ�����

���ƥƥ��Ȥ����ɡ�HTTP::Engine�ˤϤ������ƥ����ѤΥ��󥿡��ե��������Ѱդ���Ƥ��롣���ȡ��ƥ��ȥꥯ�����Ȥ���������⥸�塼���⤢�롣�ʤ�������㤢�äϴ�ñ����

  1. interface => { module => 'Test' } ��engine����
  2. HTTP::Engine::Test::Request��request����
  3. engine��run�᥽�åɤ˥ƥ��ȥꥯ�����Ȥ��ꤲ�Ƥ��
  4. �֤äƤ����쥹�ݥ󥹤�����å�����

�äƤ��ȤǤ��͡��狼��ޤ���

�ޤ�����ľ�˽񤤤Ƥߤ�

�������̾��ʤ��ΤǤϤäĤ����㤪����Udon::App��GET�ꥯ�����Ȥ��ꤲ��ƥ��ȤϤ���ʴ�����

use strict;
use warnings;
use FindBin qw($Bin);
use Udon::App;
use Test::More;
use HTTP::Engine::Test::Request;

plan tests => 1;

my $app = Udon::App->new( { viewdir => "$Bin/../view" } );
my $engine = $app->setup_engine( { module => 'Test' } );
my $req = HTTP::Engine::Test::Request->new(
    uri => 'http://udon.example.org/',
    method => 'GET'
);
my $res = $engine->run($req);
is $res->code, 403, 'should return "Forbidden" when GET request';

�դࡢ�ޤ�����ñ�Ǥ��͡����ȤϤ���ʴ����Ǥɤ�ɤ�$req���äƤɤ�ɤ�$engine->run���Ƥ����ɤ���

Test::Declare

�Ȥ����ǡ�Test::More�Ϥޤ�������Ƥ��ǻȤ������¤����Ȥ�̵��������ɤ⡢���ʤ���RSpec���繥�����������ޤä�Objective-C�Υƥ��Ȥˤޤ�RSpec��Ȥä��㤦�ͤȤ��ƤϾ������ɤ�����������ʤ����Τ�Test::Declare�äƤ�Ĥ�ȤäƤߤ뤳�Ȥˤ�����

use strict;
use warnings;
use FindBin qw($Bin);
use Udon::App;
use Test::Declare;
use HTTP::Engine::Test::Request;

plan tests => blocks;

describe 'GET' => run {
    my $res; 
    init {
        my $app = Udon::App->new( { viewdir => "$Bin/../view" } );
        my $engine = $app->setup_engine( { module => 'Test' } );
    };
    test 'should return "Forbidden"' => run {
        $res = $engine->run(
            HTTP::Engine::Test::Request->new(
                uri => 'http://udon.example.org/',
                method => 'GET'
            ),
        );  
        is $res->code, 403;
    };  
};  

�褦�����������ɤ����ɤ��ʤä������䡢�١��̤� describe �����äƤ뤫�鵤�����ä��󤸤�ʤ�������顣�����Ȥۤ顢�������Ʋ����Ф���ƥ��ȤʤΤ��������Ƚ��֤ȥƥ��ȥ����ɤȤ��ҤȤޤȤ�ˤʤäƤ������狼��䤹������󡣤͡�

������ɤ�������ɡ�setup_engine�Ȥ�HTTP::Engine::Test::Request->new�Ȥ������٤��������ʤ������Υ����ɤ��Ȱ�Ĥ����񤤤Ƥʤ�����ޤ���������ɡ��������404�פ�Spec���餤�����夷�褦�Ȼפ��Ȥ���äȤ���ʤꤹ�롣����ʤ������Ʊ���ʤ�����鲿�٤�񤭤����ʤ��������ˤ�����

Test::HTTP::Engine

����������Rack�ΤȤ���Rack::Test��Ȥä����Ū�ˤ��äѤꤷ�������㤢Ʊ����ˡ�Dz�褷�Ƥߤ���ɤ��󤸤�ʤ����������Ȼפ�Ω�ä�Ŭ���ˤ���ʤ�Τ��Ϥ��Ƥߤ���

package Test::HTTP::Engine;

use strict; 
use warnings;
use Exporter;
use HTTP::Engine::Test::Request;
our @ISA    = qw(Exporter);
our @EXPORT = qw(engine get);

sub engine { die }
    
sub get {
    my $path = shift;
    engine->run(
        HTTP::Engine::Test::Request->new(
            uri    => "http://example.org/$path",
            method => 'GET'
        ),  
        env => \%ENV
    );
}   

1;

�ǡ������Ȥ��Ȥ��ä��Υƥ��ȤϤ����ʤ롣

use strict;
use warnings;
use FindBin qw($Bin);
use Udon::App;
use Test::Declare;
use Test::HTTP::Engine;

plan tests => blocks;

# engine�������ϳƥƥ��ȤǾ�񤭤����Ѥ���
no warnings 'redefine';
*Test::HTTP::Engine::engine = sub {
    my $app = Udon::App->new( { viewdir => "$Bin/../view" } );
    $app->setup_engine( { module => 'Test' } );
};
    
describe 'GET' => run {
    test 'should return "Forbidden"' => run {
        is get('/')->code,    403;
        is get('/get')->code, 403;
    };  
    test 'should return "I\'m a teapot" with mode="prev"' => run {
        is get('/?mode=prev')->code, 418;
    };
    test 'should return "Gone" with mode="next"' => run {
        is get('/?mode=next')->code, 410;
    };
};

���äѤꤷ��������äȥƥ������䤷�����ɤ��ä���긫�פ����������Ϥ��Ȥʤ�RSpec�Ǥ˶��դ����������뤾�����Ȥ�post�Ȥ�delete�Ȥ����äƤ���Rack::Test�Ǥ�ä��Τȶᤤ���Ȥ��Ǥ��롣�פ��դ��Ǻ�ä����ɰճ����ɤ��ʡ�

�ƥ��Ȥ��ñ�������դ��Ƥʤ��ǽ񤱤��

�Ȥ����櫓��Apache��ServerSimple�ǥ����Хץ�������Ω���夲���ꤷ�ʤ��Ƥ⥵���äȥ��ץ�Υƥ��Ȥ��������ä��ɤ��Ǥ��͡�����ʴ�ñ�ʤ�ǽ餫��ƥ��Ƚ񤱤�äƸ���줽���Ǥ��͡��䡢���ޤ��衣�����ȸ�Ǥ��ɤ󲰤Τ�Ĥˤ�ƥ����ɲä��Ȥ��ޤ��äơ��Ҥ���

�ɵ�

��ʬ�Ǥ�Test::HTTP::Engine::engine������֤�������Τ�̵����ʡ����ʤ󤫰㤦�ʡ��ȻפäƤ��顢yappo���󤫤�

engine {}; �� setup �����ۤ��������⡼

�ȤΤ��ȡ��Ȥ������Ǽ�ľ���档

�轵�����餳�ä����ɤ��򤤤��ä�ͷ��Ǥ��Τ����ɡ�HTTP::Engine�ˤ�HTTP::Engine::Middleware�Ȥ����ߥɥ륦����������Ȥߤ⤢��Τǡ����ä����ʤΤ�UdonMap(Rack::URLMap��ɤ�)��ߥɥ륦�����Ǽ������Ƥߤ���

gist: 117012 - GitHub

����ε����ΤȤ��ȹ������Ѥ�äƤ뤱�ɵ��ˤ��ʤ������ǡ����Ȥ����ε���ľ���Ȥ������ε�������­������Udon::Middleware::URLMap���ߥɥ륦�����ǡ�server-middleware.pl���ߥɥ륦������UdonMap��Ȥäƽ�ľ������Ρ�

�ߥɥ륦�������Τϴ�ñ�˺�줿��use HTTP::Engine::Middleware�����Moose�ν���������򤷤���ߥɥ륦�����ѤΥ᥽�åɤ����䤷���ꤷ�Ƥ����Τǡ�HTTP::Engine��new����Ȥ��˻��ꤷ���ϥ�ɥ������˼¹Ԥ���������ꤿ���Ȥ��ϡ�before_handle��HTTP::Engine::Request������Ȥä�HTTP::Engine::Response���֤�������񤤤Ƥ��Ф��������� ���Υߥɥ륦�������������٤�Request����ʤ��Ȥ��䡢Request��ù����Ƽ����Ϥ������Ȥ��ϡ�Response����ʤ���Request���֤��Ƥ��ȼ��Υߥɥ륦������ϥ�ɥ�˽������Ϥ��ͻҡ���ñ��ñ�����ȥ⥸�塼��κǸ��__MIDDLEWARE__��񤯤Τ�˺�줺�ˡ�����Ǹ�����⤷�Ƥ���롣

���礤��­����̩�˸����ȡ�before_handle���֤��ͤ�HTTP::Engine::Response���ä��Ȥ��˸¤ꡢ������before_handle�Υ롼�פ���λ���롣�ʤΤǼ��Υߥɥ륦�����˽�����󤷤����Ȥ��ϡ��̤�HTTP::Engine::Request���֤��ʤ��㤤���ʤ��櫓�ǤϤʤ������������Υߥɥ륦�������֤����ͤ����Τޤ޼��Υߥɥ륦�����⤷����request_handler�˥ꥯ�����ȤȤ����Ϥ�Τǡ����̤�HTTP::Engine::Request�������Ʊ�������񤤤򤹤륪�֥������Ȥ��֤���Τ��Ȼפ����������ʤ��ȥߥɥ륦������Ťͤ��ʤ�����

�ǡ����θ�request_handler��after_handle�ν����ؤ�³��������ɡ��⤷before_handle������Τ����Τɤ줫��HTTP::Engine::Response���֤��Ƥ�����request_handler�ϸƤФ�ʤ����Ǥ�after_handle�ϥ��顼�Ǥ�ФƤʤ��¤�ϸƤФ�뤷����ǻߤޤ뤳�Ȥ�ʤ����Ĥޤ�after_handle����äƤ�ߥɥ륦�����������¹Ԥ�������Ȥ�����ư�ΤϤ���

�Ȥ����Ǽ¤Ϥ��켫�ΤϤ����äȺ�줿������ɡ��������褦�Ȼפäƥե�����ξ��ܤ��ƥ⥸�塼���̾���Ѥ����餤���ʤ�ư���ʤ��ʤäƤ���äȤ����ϥޤä����ǽ�˽񤤤Ƥ��Ȥ���NetaKit::Middleware::URLMap�ä�̾���ˤ��Ƥ�������ɡ�UdonMap2�ä�̾���ˤ���Ȳ��Τ���before_handle����__MIDDLEWARE__���Ρ�����ʤ��͡��衢���ۤ��פ�Perl������ܤ��롣�ʤ󤸤�����Ȼפ��Ĥĥ������ɤ�Ǥ�Ȥ��ˤ�����ͳ�˵��դ�����HTTP::Engine::Middleware��use���Ƥ��ĤΥ⥸�塼��̾�����Middleware�äƤΤ��ޤޤ�Ƥʤ��ȡ����Υ⥸�塼���ߥɥ륦�����Ȥ��ƽ�������Ƥ���ʤ���

# HTTP/Engine/Middleware.pm����ȴ��
sub import {
    my($class, ) = @_;
    my $caller = caller;

    return unless $caller =~ /(?:\:)?Middleware\:\:.+/;

    strict->import;
    warnings->import;

    init_class($caller);

    if (Any::Moose::moose_is_preferred()) {
        Moose->import({ into_level => 1 });
    } else {
        Mouse->export_to_level( 1 );
    }

    no strict 'refs';
    *{"$caller\::__MIDDLEWARE__"} = sub {
        use strict;
        my $caller = caller(0);
        __MIDDLEWARE__($caller);
    };

    *{"$caller\::before_handle"}     = sub (&) { goto \&before_handle     };
    *{"$caller\::after_handle"}      = sub (&) { goto \&after_handle      };
    *{"$caller\::middleware_method"} = sub     { goto \&middleware_method };
}

�ʤ�Ǥ��ʡ��Ȥ���äȹͤ���������ɡ��ߥɥ륦�������Ȥ���Ȥ��Ȥ���use HTTP::Engine::Middleware�ʤ�����ɡ�import����Ǥ������������������Ƥ�Τǡ����⤷�ʤ���лȤ�¦�ΤȤ��Ǥ�Moose�ν����������before_handle�����䤷���ꤷ�Ƥ��ޤ���������¿ʬ�⥸�塼��̾��������դ��Ƥ����Ф褷�ʤˤ�äƤ����褦�ˤ��Ƥ����������Ȥ��פäƤ���������������äƤ�����󡣵��դ��貶�ġ�

�Ȥ����櫓��HTTP::Engine��HTTP::Engine::Middleware�λȤ������ʤ�Ȥʤ�ʬ���äƤ����Τǡ������������ɤ󲰤ȵ����ΤϽ����ˤ��ơ����̤�WAF�äݤ�ư���򤹤��ΤǤ��äƤߤ褦���ʡ�

���Υ֥����ǤϤޤ���¿��Perl���ä�񤫤ʤ��Τ����ɡ��¤ϻŻ��Ǥ�Perl�Фä���񤤤Ƥ��ꤹ�롣�ˤ⤫����餺�Ƕ�RubyRuby���������ʤΤǡ����ΤޤޤǤϥޥ����������Perl Monger�������˥ȥ����塼���˲��Ƥ������줿����˲֤����줿�ꤷ�Ƥ��ޤ�(��)���Ȥ������ȤǺ�������HTTP::Engine�򤤤��äƤߤ뤳�Ȥˤ�����

��Perl Monger�Ϥ���ʱ����ʤ�����Ϥ��ޤ��󤷡�Rubyist��������Ƥ�ȼ����Ω�줬�������ʤ�ʤ�Ƥ��Ȥ������󤢤�ޤ��󤷡����������Хȥ����塼���ʤ����������Ȥʤ��䡣

��Ӥΰ٤ˡ������404�פ��������Ȼפä�������ɡ����Τޤ��Ʊ���Τ��äƤ⤢��ޤ�ݤ��ʤ��Τǡ֤��ɤ󲰤�403�פˤ��Ƥߤ�������Τ�Ʊ����GET��POST��PUT��DELETE���б����ƤƤ��줾��㤦�쥹�ݥ󥹤��֤��Τǡ�Ŭ���˥ꥯ�������ꤲ�ƤߤƤ���������

�ե�����ι����Ϥ���ʴ�����

UdonApp.pm
���ɤ󲰤Υ��ơ��������֤����ץꡣ
UdonMap.pm
Rack::URLMap��ɤ����ѥ��ȥ��ץ���Ϣ�դ��ƥ��ץ��handle_request��Ƥ֡���Path::Dispatcher��
UdonHandler.pm
UdonMap��Ƥ֤����mod_perl2�ѤΥϥ�ɥ顣PerlSetEnv��APP_BASE_DIR(ɬ��)��APP_LOCATION(Ǥ��)������Ǥ��롣APP_BASE_DIR��view�Υǥ��쥯�ȥ����ꤹ��Τˡ�APP_LOCATION���㤨��/perl/resource/udon�ߤ����ʥѥ��ǥ����������������Ȥ��ˡ�PerlSetEnv /perl�פߤ����ˤ��ƻȤ���
server.pl
�¹Ԥ���ȥ�����ɥ�����ǥ�����Ω���夲�롣
server-switch.pl
server.pl���HTTP::Engine ��Ĥ��ä�����������ץ�ʥץ���������(The simple example code for HTTP::Engine) - TokuLog ����B�����פ򻲹ͤ�ľ������Ρ���Perl5.10���ʤ�Ǻǽ餫�餽���񤫤ʤ��ä��Τ��ȸ����ȡ�Mac������Perl��5.8�ʤΤǡġ�given-when���������ߤ��ʤ���
server-urlmap.pl
server.pl��UdonMap��Ȥ��褦��ľ������Ρ����줬���֤��ä��ꤹ�뤫�ʤ����Ƥ��������ʤ���UdonMap�ΰ�̵̣�����ɡ�
udon.cgi
CGI�����̤�Apache�Ȥ���ư����
*.msn
view�ե����롣

����äȹ����Ѥ������⥸�塼���Udon*.pm����lib/Udon/*.pm�ˡ��ƥ�ץ졼�Ȥ�*.msn����view/*.msn�ˡ�������ץȤ�*.pl����bin/*.pl�˰�ư��

Ruby���ε�ư�ˤʤ�٤����碌��褦�ˤ��褦�Ȥ��ơ��虜�虜URLMap��ɤ����äƤ��ޤä���Path::Dispatcher��̵�̸����ʴ����ݤ�ʤ���������Path::Dispatcher�Ϥ�äȿ����Ǥ���ⵡǽ�ʥǥ����ѥå���ʤΤǡ�WAF����Ȥ���UdonMap�ˤ�����Ȥ������ǥ����ѥå����UdonApp�����ץꥱ������󤸤�ʤ��ƥ���ȥ����顢Ū�ʹ����ˤ���Ȼפ����ɡ��ޤ�Rack�Υץ����ץ�Ȥ���ӤäƤ��ȤǤ����դϸ氦�ȡ�

���פä����ɡ�����HTTP::Engine::Middleware�Ȥ��Ǽ������٤������顣�Ȥ��������Ǥˤ���ʤΤ��ä��ꤷ�������ޤ�Middleware�����Ϥ������ɤ��Ƥʤ��ΤǸ�ǡ���äƤߤ������ε������ȡ�

���ʤߤ˥ƥ�ץ졼�Ȥˤ�Text::MicroMason::SafeServerPages��Ȥä������ʻȤäƤʤ��ƥ�ץ졼�ȥ��󥸥���Ƥߤ����ä��äƤ����ʤΤǡ��ä˰�̣�Ϥʤ����Ǥ��ɤ��ʡ�TT����äݤ���ľ�˽񤱤ƹ�������

���ͤˤ������

�����Υڡ����Υȥåץ�