Index: /lang/perl/HTTP-Engine-Middleware/trunk/t/200_middlewares/encode.t
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/200_middlewares/encode.t (revision 29321)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/t/200_middlewares/encode.t (revision 29321)
@@ -0,0 +1,65 @@
+use strict;
+use warnings;
+use lib '.';
+use Test::Base;
+eval q{ use Data::Visitor::Encode };
+plan skip_all => "Data::Visitor::Encode is not installed" if $@;
+eval q{ use HTTP::Request };
+plan skip_all => "HTTP::Request is not installed" if $@;
+eval q{ use HTTP::Engine };
+plan skip_all => "HTTP::Engine is not installed: $@" if $@;
+
+eval q{ use HTTP::Engine::Middleware };
+
+plan tests => 3 * blocks;
+
+use Encode;
+use URI;
+
+filters { params => [qw/eval/], };
+
+run {
+    my $block = shift;
+
+    my $mw = HTTP::Engine::Middleware->new;
+    $mw->install( 'HTTP::Engine::Middleware::Encode', );
+
+    my $request = HTTP::Request->new(
+        GET => $block->uri,
+        [ 'Content-Type' => $block->content_type ]
+    );
+
+    my $do_test = sub {
+        my $req = shift;
+        ok Encode::is_utf8( $req->params->{'nite'} );
+        is_deeply $req->params, $block->params, $block->name;
+        HTTP::Engine::Response->new( body => 'OK!' );
+    };
+
+    my $response = HTTP::Engine->new(
+        interface => {
+            module          => 'Test',
+            request_handler => $mw->handler($do_test),
+        },
+    )->run($request);
+
+    is $response->content, 'OK!';
+};
+
+__END__
+
+=== ascii
+--- uri: http://localhost/?nite=nipotan
+--- content_type: text/plain;charset=ascii
+--- params : {nite => 'nipotan'}
+
+=== utf-8
+--- uri: http://localhost/?nite=%E3%81%97%E3%83%BC%E3%81%88%E3%81%99%E3%81%88%E3%81%99
+--- content_type : text/plain; charset=utf-8
+--- params: { nite => "\x{3057}\x{30fc}\x{3048}\x{3059}\x{3048}\x{3059}" }
+
+=== euc-jp
+--- uri: http://localhost/?nite=%A4%B7%A1%BC%A4%A8%A4%B9%A4%A8%A4%B9
+--- content_type: text/plain; charset=euc-jp
+--- params: { nite => "\x{3057}\x{30fc}\x{3048}\x{3059}\x{3048}\x{3059}" }
+
Index: /lang/perl/HTTP-Engine-Middleware/trunk/t/200_middlewares/reverseproxy.t
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/200_middlewares/reverseproxy.t (revision 29321)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/t/200_middlewares/reverseproxy.t (revision 29321)
@@ -0,0 +1,108 @@
+use strict;
+use warnings;
+use Test::Base;
+use HTTP::Engine;
+use HTTP::Engine::Middleware;
+use HTTP::Request;
+use HTTP::Headers;
+
+filters { input => [qw/yaml/] };
+
+plan tests => 17;
+
+run {
+    my $block = shift;
+    local %ENV = ();
+    $ENV{REMOTE_ADDR}    = '127.0.0.1';
+    $ENV{REQUEST_METHOD} = 'GET';
+    $ENV{SERVER_PORT}    = 80;
+    $ENV{HTTP_HOST}      = 'example.com';
+    $ENV{QUERY_STRING}   = 'foo=bar';
+
+    my $mw = HTTP::Engine::Middleware->new;
+    $mw->install( 'HTTP::Engine::Middleware::ReverseProxy', );
+
+    my $headers = HTTP::Headers->new;
+    $headers->header( %{ $block->input } );
+
+    # $headers->header(HOST => 'example.com:80');
+    HTTP::Engine->new(
+        interface => {
+            module          => 'Test',
+            request_handler => $mw->handler(
+                sub {
+                    my $req = shift;
+
+                    for my $attr (qw/secure address/) {
+                        if ( $block->$attr ) {
+                            is( $req->$attr, $block->$attr,
+                                $block->name . " of $attr" );
+                        }
+                    }
+                    for my $url (qw/uri base /) {
+                        if ( $block->$url ) {
+                            is( $req->$url->as_string, $block->$url,
+                                $block->name . " of $url" );
+                        }
+                    }
+
+                    HTTP::Engine::Response->new( body => 'OK' );
+                }
+            ),
+        },
+        )->run(
+        HTTP::Request->new( GET => 'http://example.com/?foo=bar', $headers ),
+        env => \%ENV
+        );
+};
+
+__END__
+
+=== with https
+--- input
+x-forwarded-https: on
+--- secure: 1
+--- base: https://example.com:80/
+--- uri:  https://example.com:80/?foo=bar
+
+=== without https
+--- input
+x-forwarded-https: off
+--- secure: 0
+--- base: http://example.com:80/
+--- uri:  http://example.com:80/?foo=bar
+
+===
+--- input
+dummy: 1
+--- secure: 0
+--- base: http://example.com:80/
+--- uri: http://example.com:80/?foo=bar
+
+=== https with HTTP_X_FORWARDED_PROTO
+--- input
+x-forwarded-proto: https
+--- secure: 1
+--- base: https://example.com:80/
+--- uri:  https://example.com:80/?foo=bar
+
+=== with HTTP_X_FORWARDED_FOR
+--- input
+x-forwarded-for: 192.168.3.2
+--- address: 192.168.3.2
+--- base: http://example.com:80/
+--- uri:  http://example.com:80/?foo=bar
+
+=== with HTTP_X_FORWARDED_HOST
+--- input
+x-forwarded-host: 192.168.1.2:5235
+--- base: http://192.168.1.2:5235/
+--- uri:  http://192.168.1.2:5235/?foo=bar
+
+=== with HTTP_X_FORWARDED_HOST and HTTP_X_FORWARDED_PORT
+--- input
+x-forwarded-host: 192.168.1.5
+x-forwarded-port: 1984
+--- base: http://192.168.1.5:1984/
+--- uri:  http://192.168.1.5:1984/?foo=bar
+
Index: /lang/perl/HTTP-Engine-Middleware/trunk/t/200_middlewares/debugscreen.t
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/200_middlewares/debugscreen.t (revision 29321)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/t/200_middlewares/debugscreen.t (revision 29321)
@@ -0,0 +1,34 @@
+use strict;
+use warnings;
+use Test::More;
+
+eval q{ use CGI::ExceptionManager };
+plan skip_all => "CGI::ExceptionManager is not installed" if $@;
+eval q{ use Scope::Upper };
+plan skip_all => "Scope::Upper is not installed: $@" if $@;
+
+plan tests => 4;
+
+use HTTP::Engine;
+use HTTP::Engine::Response;
+use HTTP::Request;
+
+use HTTP::Engine::Middleware;
+
+my $mw = HTTP::Engine::Middleware->new;
+$mw->install( 'HTTP::Engine::Middleware::DebugScreen', { powerd_by => 'HE::Middleware test' } );
+
+my $res = HTTP::Engine->new(
+    interface => {
+        module          => 'Test',
+        request_handler => $mw->handler(
+            sub { die 'ERROR TEST HE' }
+        ),
+    },
+)->run( HTTP::Request->new( GET => 'http://localhost/') );
+my $out = $res->content;
+
+is $res->code, '500';
+like $out, qr/ERROR TEST HE/;
+like $out, qr/Powered by HE::Middleware test/;
+like $out, qr/request_handler =&gt; \$mw-&gt;handler\(/;
Index: /lang/perl/HTTP-Engine-Middleware/trunk/t/200_middlewares/docomo_guid.t
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/200_middlewares/docomo_guid.t (revision 29321)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/t/200_middlewares/docomo_guid.t (revision 29321)
@@ -0,0 +1,56 @@
+use strict;
+use warnings;
+use utf8;
+use lib '.';
+use Test::Base;
+eval q{ use HTML::StickyQuery };
+plan skip_all => "HTML::StickyQuery is not installed" if $@;
+eval q{ use HTTP::Engine };
+plan skip_all => "HTTP::Engine is not installed: $@" if $@;
+
+plan tests => 1 * blocks;
+
+use Encode;
+use URI;
+use HTTP::Request;
+use HTTP::Engine::Response;
+eval q{ use HTTP::Engine::Middleware };
+
+filters( { expected => qw/ chomp /, } );
+
+run {
+    my $block = shift;
+
+    my $mw = HTTP::Engine::Middleware->new;
+    $mw->install( 'HTTP::Engine::Middleware::DoCoMoGUID', );
+
+    my $code = sub {
+        my $req = shift;
+        HTTP::Engine::Response->new(
+            content_type => 'text/html',
+            body         => $block->input,
+        );
+    };
+
+    my $response = HTTP::Engine->new(
+        interface => {
+            module          => 'Test',
+            request_handler => $mw->handler($code),
+        },
+    )->run( HTTP::Request->new( GET => '/' ) );
+
+    is $response->content, $block->expected;
+};
+
+__END__
+
+=== 
+--- input
+<a href="/foo">bar</a>
+--- expected
+<a href="/foo?guid=ON">bar</a>
+===
+--- input
+<a href="http://192.168.1.3/?page=1">&lt; 2008-05-18</a>
+--- expected
+<a href="http://192.168.1.3/?page=1&amp;guid=ON">&lt; 2008-05-18</a>
Index: /lang/perl/HTTP-Engine-Middleware/trunk/t/200_middlewares/mobile_attribute.t
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/200_middlewares/mobile_attribute.t (revision 29321)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/t/200_middlewares/mobile_attribute.t (revision 29321)
@@ -0,0 +1,54 @@
+use strict;
+use warnings;
+use Test::More;
+
+eval { require HTTP::Engine; };
+plan skip_all => "HTTP::Engine is not installed." if $@;
+
+use HTTP::Request;
+use HTTP::Engine::Response;
+
+eval { require HTTP::MobileAttribute; };
+plan skip_all => "HTTP::MobileAttribute is not installed." if $@;
+
+plan tests => 3;
+use_ok 'HTTP::Engine::Middleware';
+
+sub do_test {
+    my $coderef = shift;
+
+    my $mw = HTTP::Engine::Middleware->new(
+        { method_class => 'HTTP::Engine::Request' } );
+    $mw->install( 'HTTP::Engine::Middleware::MobileAttribute', );
+
+    HTTP::Engine->new(
+        interface => {
+            module          => 'Test',
+            request_handler => sub {
+                my $req = shift;
+
+                $coderef->($req);
+
+                HTTP::Engine::Response->new( body => 'OK' );
+            },
+        },
+    )->run( HTTP::Request->new( GET => 'http://example.org' ) );
+}
+
+do_test(
+    sub {
+        my $req = shift;
+        $req->user_agent('IE');
+        isa_ok $req->mobile_attribute,
+            'HTTP::MobileAttribute::Agent::NonMobile';
+    }
+);
+
+do_test(
+    sub {
+        my $req = shift;
+        $req->user_agent('DoCoMo/1.0/D501i');
+        isa_ok $req->mobile_attribute, 'HTTP::MobileAttribute::Agent::DoCoMo';
+    }
+);
+
Index: /lang/perl/HTTP-Engine-Middleware/trunk/t/perlcriticrc
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/perlcriticrc (revision 11509)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/t/perlcriticrc (revision 29321)
@@ -1,2 +1,4 @@
+[TestingAndDebugging::RequireUseStrict]
+equivalent_modules = Mouse Mouse::Role HTTP::Engine::Middleware
 [TestingAndDebugging::ProhibitNoStrict]
 allow=refs
Index: /lang/perl/HTTP-Engine-Middleware/trunk/t/lib/Foo/Middleware/Bar.pm
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/lib/Foo/Middleware/Bar.pm (revision 29321)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/t/lib/Foo/Middleware/Bar.pm (revision 29321)
@@ -0,0 +1,20 @@
+package Foo::Middleware::Bar;
+use HTTP::Engine::Middleware;
+
+has 'key' => (
+    is => 'rw',
+);
+
+before_handle {
+    my($c, $self, $req) = @_;
+    $req->header( 'X-Key' => $self->key );
+    $req;
+};
+
+after_handle {
+    my($c, $self, $req, $res) = @_;
+    $res->body( $res->body . ', key=' . $self->key );
+    $res;
+};
+
+__MIDDLEWARE__
Index: /lang/perl/HTTP-Engine-Middleware/trunk/t/lib/Foo/Middleware/Inner.pm
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/lib/Foo/Middleware/Inner.pm (revision 29321)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/t/lib/Foo/Middleware/Inner.pm (revision 29321)
@@ -0,0 +1,10 @@
+package Foo::Middleware::Inner;
+use HTTP::Engine::Middleware;
+
+after_handle {
+    my($c, $self, $req, $res) = @_;
+    $res->body( 'ok' );
+    $res;
+};
+
+__MIDDLEWARE__
Index: /lang/perl/HTTP-Engine-Middleware/trunk/t/lib/Foo/Middleware/Baz.pm
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/lib/Foo/Middleware/Baz.pm (revision 29321)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/t/lib/Foo/Middleware/Baz.pm (revision 29321)
@@ -0,0 +1,6 @@
+package Foo::Middleware::Baz;
+use HTTP::Engine::Middleware;
+
+middleware_method 'foo' => sub { 'foo' };
+
+__MIDDLEWARE__
Index: /lang/perl/HTTP-Engine-Middleware/trunk/t/lib/Foo/Middleware/Middle.pm
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/lib/Foo/Middleware/Middle.pm (revision 29321)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/t/lib/Foo/Middleware/Middle.pm (revision 29321)
@@ -0,0 +1,19 @@
+package Foo::Middleware::Middle;
+use HTTP::Engine::Middleware;
+
+outer_middleware 'Foo::Middleware::Outer';
+inner_middleware 'Foo::Middleware::Inner';
+
+before_handle {
+    my($c, $self, $req) = @_;
+    $req->header( 'X-Middle' => $c->method_class->before );
+    $req;
+};
+
+after_handle {
+    my($c, $self, $req, $res) = @_;
+    $res->body( 'from inner (' . $res->body . ')' ) if $res->body eq 'ok';
+    $res;
+};
+
+__MIDDLEWARE__
Index: /lang/perl/HTTP-Engine-Middleware/trunk/t/lib/Foo/Middleware/Outer.pm
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/lib/Foo/Middleware/Outer.pm (revision 29321)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/t/lib/Foo/Middleware/Outer.pm (revision 29321)
@@ -0,0 +1,13 @@
+package Foo::Middleware::Outer;
+use HTTP::Engine::Middleware;
+
+my $param;
+middleware_method 'before' => sub { $param };
+
+before_handle {
+    my($c, $self, $req) = @_;
+    $param = $req->param('param');
+    $req;
+};
+
+__MIDDLEWARE__
Index: /lang/perl/HTTP-Engine-Middleware/trunk/t/100_core/dependency.t
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/100_core/dependency.t (revision 29321)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/t/100_core/dependency.t (revision 29321)
@@ -0,0 +1,45 @@
+use strict;
+use warnings;
+use lib 't/lib';
+use Test::More tests => 7;
+
+use HTTP::Engine;
+use HTTP::Engine::Response;
+use HTTP::Engine::Middleware;
+use HTTP::Request;
+
+eval {
+    my $mw = HTTP::Engine::Middleware->new({ method_class => 'main' });
+    $mw->install(
+        'Foo::Middleware::Inner',
+        'Foo::Middleware::Middle',
+    );
+    my $handler = $mw->handler( sub {} );
+};
+like $@, qr/'Foo::Middleware::Middle' need to 'Foo::Middleware::Outer'/, 'dependency error';
+
+my $mw = HTTP::Engine::Middleware->new({ method_class => 'main' });
+$mw->install(
+    'Foo::Middleware::Middle',
+    'Foo::Middleware::Inner',
+    'Foo::Middleware::Outer'
+);
+
+is $mw->middlewares->[0], 'Foo::Middleware::Outer', 'outer';
+is $mw->middlewares->[1], 'Foo::Middleware::Middle', 'middle';
+is $mw->middlewares->[2], 'Foo::Middleware::Inner', 'inner';
+
+my $res = HTTP::Engine->new(
+    interface => {
+        module => 'Test',
+        request_handler => $mw->handler( \&handler ),
+    }
+)->run( HTTP::Request->new( GET => 'http://localhost/?param=yappo') );
+is $res->content, 'from inner (ok)';
+
+sub handler {
+    my $req = shift;
+    is(main->before, 'yappo', 'before_method');
+    is $req->header('X-Middle'), 'yappo', 'middle set data';
+    HTTP::Engine::Response->new( body => 'ng' );
+}
Index: /lang/perl/HTTP-Engine-Middleware/trunk/t/100_core/method_injection.t
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/100_core/method_injection.t (revision 29321)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/t/100_core/method_injection.t (revision 29321)
@@ -0,0 +1,32 @@
+use strict;
+use warnings;
+use lib 't/lib';
+use Test::More tests => 2;
+
+use HTTP::Engine;
+use HTTP::Engine::Response;
+use HTTP::Engine::Middleware;
+use HTTP::Request;
+
+my $mw = HTTP::Engine::Middleware->new({ method_class => 'MethodInject' });
+$mw->install(
+    'Foo::Middleware::Baz',
+);
+
+my $res = HTTP::Engine->new(
+    interface => {
+        module => 'Test',
+        request_handler => $mw->handler( \&handler ),
+    }
+)->run( HTTP::Request->new( GET => 'http://localhost/') );
+is $res->content, 'ok', 'end of request';
+
+sub handler {
+    my $req = shift;
+    is MethodInject->foo, 'foo', 'inject method';
+    HTTP::Engine::Response->new( body => 'ok' );
+}
+
+{
+    package MethodInject;
+}
Index: /lang/perl/HTTP-Engine-Middleware/trunk/t/100_core/install_middleware.t
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/100_core/install_middleware.t (revision 29321)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/t/100_core/install_middleware.t (revision 29321)
@@ -0,0 +1,17 @@
+use strict;
+use warnings;
+use lib 't/lib';
+use Test::More tests => 3;
+
+use HTTP::Engine::Middleware;
+
+my $mw = HTTP::Engine::Middleware->new;
+$mw->install(
+    'Foo::Middleware::Bar' => { key => 'value' },
+    'Foo::Middleware::Baz'
+);
+
+is $mw->middlewares->[0], 'Foo::Middleware::Bar', 'installed middleware is Foo::Middleware::Bar';
+is $mw->middlewares->[1], 'Foo::Middleware::Baz', 'installed middleware is Foo::Middleware::Baz';
+
+is $mw->instance_of('Foo::Middleware::Bar')->key, 'value', 'config';
Index: /lang/perl/HTTP-Engine-Middleware/trunk/t/100_core/wrap.t
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/100_core/wrap.t (revision 29321)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/t/100_core/wrap.t (revision 29321)
@@ -0,0 +1,28 @@
+use strict;
+use warnings;
+use lib 't/lib';
+use Test::More tests => 2;
+
+use HTTP::Engine;
+use HTTP::Engine::Response;
+use HTTP::Engine::Middleware;
+use HTTP::Request;
+
+my $mw = HTTP::Engine::Middleware->new;
+$mw->install(
+    'Foo::Middleware::Bar' => { key => 'yappo' },
+);
+
+my $res = HTTP::Engine->new(
+    interface => {
+        module => 'Test',
+        request_handler => $mw->handler( \&handler ),
+    }
+)->run( HTTP::Request->new( GET => 'http://localhost/') );
+is $res->content, 'header=yappo, key=yappo', 'after_handle';
+
+sub handler {
+    my $req = shift;
+    is $req->header('X-Key'), 'yappo', 'before_handle';
+    HTTP::Engine::Response->new( body => 'header=' . $req->header('X-Key') );
+}
Index: /lang/perl/HTTP-Engine-Middleware/trunk/t/100_core/use.t
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/100_core/use.t (revision 29321)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/t/100_core/use.t (revision 29321)
@@ -0,0 +1,12 @@
+use strict;
+use warnings;
+use lib 't/lib';
+use Test::More tests => 3;
+
+use_ok 'HTTP::Engine::Middleware';
+
+eval { before_handle(sub {}) };
+ok($@, 'before_handle is not export');
+
+eval { after_handle( sub {} ) };
+ok($@, 'after_handle is not export');
Index: /ng/perl/HTTP-Engine-Middleware/trunk/t/01_encode.t
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/01_encode.t (revision 29266)
+++  (revision )
@@ -1,61 +1,0 @@
-use strict;
-use warnings;
-use lib '.';
-use Test::Base;
-eval q{ use Data::Visitor::Encode };
-plan skip_all => "Data::Visitor::Encode is not installed" if $@;
-eval q{ use HTTP::Request };
-plan skip_all => "HTTP::Request is not installed" if $@;
-eval q{ use HTTP::Engine };
-plan skip_all => "HTTP::Engine is not installed: $@" if $@;
-
-eval q{ use HTTP::Engine::Middleware::Encode };
-
-plan tests => 3*blocks;
-
-use Encode;
-use URI;
-
-filters {
-    params => [qw/eval/],
-};
-
-run {
-    my $block = shift;
-
-    my $request = HTTP::Request->new( GET => $block->uri, ['Content-Type' => $block->content_type] );
-
-    my $do_test = sub {
-        my $req = shift;
-        ok Encode::is_utf8($req->params->{'nite'});
-        is_deeply $req->params, $block->params, $block->name;
-        HTTP::Engine::Response->new(body => 'OK!');
-    };
-
-    my $response = HTTP::Engine->new(
-        interface => {
-            module => 'Test',
-            request_handler => HTTP::Engine::Middleware::Encode->wrap($do_test),
-        },
-    )->run($request);
-
-    is $response->content, 'OK!';
-};
-
-__END__
-
-=== ascii
---- uri: http://localhost/?nite=nipotan
---- content_type: text/plain;charset=ascii
---- params : {nite => 'nipotan'}
-
-=== utf-8
---- uri: http://localhost/?nite=%E3%81%97%E3%83%BC%E3%81%88%E3%81%99%E3%81%88%E3%81%99
---- content_type : text/plain; charset=utf-8
---- params: { nite => "\x{3057}\x{30fc}\x{3048}\x{3059}\x{3048}\x{3059}" }
-
-=== euc-jp
---- uri: http://localhost/?nite=%A4%B7%A1%BC%A4%A8%A4%B9%A4%A8%A4%B9
---- content_type: text/plain; charset=euc-jp
---- params: { nite => "\x{3057}\x{30fc}\x{3048}\x{3059}\x{3048}\x{3059}" }
-
Index: /ng/perl/HTTP-Engine-Middleware/trunk/t/15_middleware_reverseproxy.t
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/15_middleware_reverseproxy.t (revision 29266)
+++  (revision )
@@ -1,97 +1,0 @@
-use strict;
-use warnings;
-use Test::Base;
-use HTTP::Engine;
-use HTTP::Engine::Middleware::ReverseProxy;
-use HTTP::Request;
-use HTTP::Headers;
-
-filters { input => [qw/yaml/] };
-
-plan tests => 17;
-
-run {
-    my $block = shift;
-    local %ENV = ();
-    $ENV{REMOTE_ADDR}    = '127.0.0.1';
-    $ENV{REQUEST_METHOD} = 'GET';
-    $ENV{SERVER_PORT}    = 80;
-    $ENV{HTTP_HOST}      = 'example.com';
-    $ENV{QUERY_STRING}   = 'foo=bar';
-
-    my $headers = HTTP::Headers->new;
-    $headers->header(%{ $block->input });
-    # $headers->header(HOST => 'example.com:80');
-    HTTP::Engine->new(
-        interface => {
-            module => 'Test',
-            request_handler => HTTP::Engine::Middleware::ReverseProxy->wrap(sub {
-                my $req = shift;
-
-                for my $attr ( qw/secure address/ ) {
-                    if ( $block->$attr ) {
-                      is($req->$attr, $block->$attr, $block->name . " of $attr");
-                    }
-                }
-                for my $url ( qw/uri base / ) {
-                  if ( $block->$url ) {
-                    is($req->$url->as_string, $block->$url, $block->name . " of $url");
-                  }
-                }
-
-                HTTP::Engine::Response->new(body  => 'OK');
-            }),
-        },
-    )->run(HTTP::Request->new(GET => 'http://example.com/?foo=bar', $headers),env => \%ENV);
-};
-
-__END__
-
-=== with https
---- input
-x-forwarded-https: on
---- secure: 1
---- base: https://example.com:80/
---- uri:  https://example.com:80/?foo=bar
-
-=== without https
---- input
-x-forwarded-https: off
---- secure: 0
---- base: http://example.com:80/
---- uri:  http://example.com:80/?foo=bar
-
-===
---- input
-dummy: 1
---- secure: 0
---- base: http://example.com:80/
---- uri: http://example.com:80/?foo=bar
-
-=== https with HTTP_X_FORWARDED_PROTO
---- input
-x-forwarded-proto: https
---- secure: 1
---- base: https://example.com:80/
---- uri:  https://example.com:80/?foo=bar
-
-=== with HTTP_X_FORWARDED_FOR
---- input
-x-forwarded-for: 192.168.3.2
---- address: 192.168.3.2
---- base: http://example.com:80/
---- uri:  http://example.com:80/?foo=bar
-
-=== with HTTP_X_FORWARDED_HOST
---- input
-x-forwarded-host: 192.168.1.2:5235
---- base: http://192.168.1.2:5235/
---- uri:  http://192.168.1.2:5235/?foo=bar
-
-=== with HTTP_X_FORWARDED_HOST and HTTP_X_FORWARDED_PORT
---- input
-x-forwarded-host: 192.168.1.5
-x-forwarded-port: 1984
---- base: http://192.168.1.5:1984/
---- uri:  http://192.168.1.5:1984/?foo=bar
-
Index: /ng/perl/HTTP-Engine-Middleware/trunk/t/02_docomo_guid.t
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/02_docomo_guid.t (revision 29266)
+++  (revision )
@@ -1,55 +1,0 @@
-use strict;
-use warnings;
-use utf8;
-use lib '.';
-use Test::Base;
-eval q{ use HTML::StickyQuery };
-plan skip_all => "HTML::StickyQuery is not installed" if $@;
-eval q{ use HTTP::Engine };
-plan skip_all => "HTTP::Engine is not installed: $@" if $@;
-
-plan tests => 1*blocks;
-
-use Encode;
-use URI;
-use HTTP::Request;
-use HTTP::Engine::Response;
-eval q{ use HTTP::Engine::Middleware::DoCoMoGUID };
-
-filters({
-    expected  => qw/ chomp /,
-});
-
-run {
-    my $block = shift;
-
-    my $code = sub {
-        my $req = shift;
-        HTTP::Engine::Response->new(
-          content_type  => 'text/html',
-          body          => $block->input,
-        );
-    };
-
-    my $response = HTTP::Engine->new(
-        interface => {
-            module => 'Test',
-            request_handler => HTTP::Engine::Middleware::DoCoMoGUID->wrap($code),
-        },
-    )->run(HTTP::Request->new( GET => '/' ));
-
-    is $response->content, $block->expected;
-};
-
-__END__
-
-=== 
---- input
-<a href="/foo">bar</a>
---- expected
-<a href="/foo?guid=ON">bar</a>
-===
---- input
-<a href="http://192.168.1.3/?page=1">&lt; 2008-05-18</a>
---- expected
-<a href="http://192.168.1.3/?page=1&amp;guid=ON">&lt; 2008-05-18</a>
Index: /ng/perl/HTTP-Engine-Middleware/trunk/t/12_plugin_mobile_attribute.t
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/t/12_plugin_mobile_attribute.t (revision 29266)
+++  (revision )
@@ -1,48 +1,0 @@
-use strict;
-use warnings;
-use Test::More;
-
-eval {
-    require HTTP::Engine;
-};
-plan skip_all => "HTTP::Engine is not installed." if $@;
-
-eval {
-    require HTTP::MobileAttribute;
-};
-plan skip_all => "HTTP::MobileAttribute is not installed." if $@;
-
-plan tests => 3;
-use_ok 'HTTP::Engine::Middleware::MobileAttribute';
-
-HTTP::Engine::Middleware::MobileAttribute->setup();
-
-sub do_test {
-    my $coderef = shift;
-
-    HTTP::Engine->new(
-        interface => {
-            module  => 'Test',
-            request_handler => sub {
-                my $req = shift;
-
-                $coderef->($req);
-
-                HTTP::Engine::Response->new(body => 'OK');
-            },
-        },
-    )->run(HTTP::Request->new(GET => 'http://example.org'));
-}
-
-do_test(sub {
-    my $req = shift;
-    $req->user_agent('IE');
-    isa_ok $req->mobile_attribute, 'HTTP::MobileAttribute::Agent::NonMobile';
-});
-
-do_test(sub {
-    my $req = shift;
-    $req->user_agent('DoCoMo/1.0/D501i');
-    isa_ok $req->mobile_attribute, 'HTTP::MobileAttribute::Agent::DoCoMo';
-});
-
Index: /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware.pm
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware.pm (revision 12616)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware.pm (revision 29321)
@@ -1,7 +1,191 @@
 package HTTP::Engine::Middleware;
-use strict;
-use warnings;
-use 5.00800;
+use Mouse;
 our $VERSION = '0.01';
+
+use Carp ();
+
+has 'middlewares' => (
+    is      => 'ro',
+    isa     => 'ArrayRef',
+    default => sub { +[] },
+);
+
+has '_instance_of' => (
+    is      => 'ro',
+    isa     => 'HashRef',
+    default => sub { +{} },
+);
+
+has 'method_class' => (
+    is      => 'ro',
+    isa     => 'Str',
+);
+
+sub init_class {
+    my $klass = shift;
+    my $meta  = Mouse::Meta::Class->initialize($klass);
+    $meta->superclasses('Mouse::Object')
+        unless $meta->superclasses;
+
+    no strict 'refs';
+    no warnings 'redefine';
+    *{ $klass . '::meta' } = sub { $meta };
+}
+
+sub import {
+    my($class, ) = @_;
+    my $caller = caller;
+
+    return unless $caller =~ /(?:\:)?Middleware\:\:.+/;
+
+    strict->import;
+    warnings->import;
+
+    init_class($caller);
+
+    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; };
+    *{"$caller\::outer_middleware"}  = sub ($) { goto \&outer_middleware; };
+    *{"$caller\::inner_middleware"}  = sub ($)  { goto \&inner_middleware; };
+}
+
+sub __MIDDLEWARE__ {
+    my ( $caller, ) = @_;
+
+    Mouse::unimport;
+    Mouse::Util::apply_all_roles( $caller, 'HTTP::Engine::Middleware::Role' );
+    $caller->meta->make_immutable( inline_destructor => 1 );
+    "MIDDLEWARE";
+}
+
+sub before_handle {
+    Carp::croak "Can't call before_handle function outside Middleware's load phase";
+}
+
+sub after_handle {
+    Carp::croak "Can't call after_handle function outside Middleware's load phase";
+}
+
+sub middleware_method {
+    Carp::croak "Can't call middleware_method function outside Middleware's load phase";
+}
+
+sub outer_middleware {
+    Carp::croak "Can't call outer_middleware function outside Middleware's load phase";
+}
+
+sub inner_middleware {
+    Carp::croak "Can't call inner_middleware function outside Middleware's load phase";
+}
+
+sub install {
+    my($self, @middlewares) = @_;
+
+    my %config;
+    for my $middleware (@middlewares) {
+        if (ref($middleware) eq 'HASH') {
+            $config{$self->middlewares->[-1]} = $middleware;
+            next;
+        }
+
+        $config{$middleware} = {};
+        push @{ $self->middlewares }, $middleware;
+    }
+
+    # load and create instance
+    my %dependend ;
+    while (my($name, $config) = each %config) {
+        $dependend{$name} = { outer => [], inner => [] };
+
+        unless ($name->can('before_handles')) {
+            # init declear
+            my @before_handles;
+            my @after_handles;
+
+            no strict 'refs';
+            no warnings 'redefine';
+
+            local *before_handle = sub { push @before_handles, @_ };
+            local *after_handle  = sub { push @after_handles, @_ };
+            local *middleware_method = $self->method_class ? sub {
+                no strict 'refs';
+                *{"$name\::$_[0]"}                    = $_[1];
+                *{$self->method_class . '::' . $_[0]} = $_[1];
+            } : sub {};
+            local *outer_middleware = sub { push @{ $dependend{$name}->{outer} }, $_[0] };
+            local *inner_middleware = sub { push @{ $dependend{$name}->{inner} }, $_[0] };
+            local $@;
+            Mouse::load_class($name);
+            $@ and Carp::croak $@;
+
+            *{"$name\::_before_handles"}    = sub () { @before_handles };
+            *{"$name\::_after_handles"}     = sub () { @after_handles };
+            *{"$name\::_outer_middlewares"} = sub () { @{ $dependend{$name}->{outer} } };
+            *{"$name\::_inner_middlewares"} = sub () { @{ $dependend{$name}->{inner} } };
+        } else {
+            $dependend{$name}->{outer} = [ $name->_outer_middlewares ];
+            $dependend{$name}->{inner} = [ $name->_inner_middlewares ];
+        }
+
+        my $instance = $name->new($config);
+        @{ $instance->before_handles } = $name->_before_handles;
+        @{ $instance->after_handles }  = $name->_after_handles;
+
+        $self->_instance_of->{$name} = $instance;
+    }
+    # check dependency and sorting
+    my $i = 0;
+    my %sort = map { $_ => $i++ } @{ $self->middlewares };
+    while (my($from, $conf) = each %dependend) {
+        for my $to (@{ $conf->{outer} }) {
+            Carp::croak "'$from' need to '$to'" unless Mouse::is_class_loaded($to);
+            $sort{$to} = $sort{$from} - 1;
+        }
+        for my $to (@{ $conf->{inner} }) {
+            Carp::croak "'$from' need to '$to'" unless Mouse::is_class_loaded($to);
+            $sort{$to} = $sort{$from} + 1;
+        }
+    }
+    @{ $self->middlewares } = sort { $sort{$a} <=> $sort{$b} } keys %sort;
+}
+
+sub instance_of {
+    my($self, $name) = @_;
+    $self->_instance_of->{$name};
+}
+
+sub handler {
+    my($self, $handle) = @_;
+
+    sub {
+        my $req = shift;
+
+        for my $middleware (@{ $self->middlewares }) {
+            my $instance = $self->_instance_of->{$middleware};
+            for my $code (@{ $instance->before_handles }) {
+                $req = $code->($self, $instance, $req);
+            }
+        }
+        my $res = eval { $handle->($req) };
+        for my $middleware (reverse @{ $self->middlewares }) {
+            my $instance = $self->_instance_of->{$middleware};
+            for my $code (reverse @{ $instance->after_handles }) {
+                $res = $code->($self, $instance, $req, $res);
+            }
+        }
+
+        $res;
+    };
+}
 
 1;
@@ -42,5 +226,5 @@
 hidek
 
-dann
+Takatoshi Kitano E<lt>techmemo@gmail.com<gt>
 
 =head1 SEE ALSO
Index: /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/DebugScreen.pm
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/DebugScreen.pm (revision 11881)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/DebugScreen.pm (revision 29321)
@@ -1,30 +1,78 @@
 package HTTP::Engine::Middleware::DebugScreen;
-use Moose;
-use Carp ();
+use HTTP::Engine::Middleware;
 
-sub wrap {
-    my ($next, $c) = @_;
+use HTTP::Engine::Response;
 
-    local $SIG{__DIE__} = \&_die;
+use Scope::Upper qw( localize_elem :words );
 
-    eval {
-        $next->($c);
-    };
-    if (my $err = $@) {
-        $c->res->status( 500 );
-        $c->res->content_type( 'text/plain' );
-        $c->res->body( $err );
+has 'powerd_by' => (
+    is      => 'rw',
+    default => __PACKAGE__,
+);
+
+has 'renderer' => (
+    is => 'rw',
+);
+
+has 'err_info' => (
+    is => 'rw',
+);
+
+has 'response' => (
+    is => 'rw',
+);
+
+has 'stacktrace_required' => (
+    is  => 'rw',
+    isa => 'Bool',
+);
+
+
+before_handle {
+    my($c, $self, $req) = @_;
+
+    $self->response(undef);
+    $self->err_info(undef);
+    $self->stacktrace_required(0);
+
+    localize_elem '%SIG', '__DIE__' => sub { died($self, @_) } => SUB UP;
+
+    $req;
+};
+
+after_handle {
+    my($c, $self, $req, $res) = @_;
+
+    if ($self->err_info) {
+        $res = HTTP::Engine::Response->new;
+        $res->code(500);
+        $res->body(
+            $self->err_info->as_html(
+                powered_by => $self->powerd_by,
+                ($self->renderer ? (renderer => $self->renderer) : ())
+            )
+        );
     }
+
+    $res;
+};
+
+sub detach { die bless [@_], 'CGI::ExceptionManager::Exception' }
+
+sub died {
+    my($self, $msg) = @_;
+
+    if (ref $msg eq 'CGI::ExceptionManager::Exception') {
+        $self->response($msg->[0]);
+        $self->err_info(undef);
+    } else {
+        unless ($self->stacktrace_required) {
+            require CGI::ExceptionManager::StackTrace;
+            $self->stacktrace_required(1);
+        }
+        $self->err_info( CGI::ExceptionManager::StackTrace->new($msg) );
+    }
+    die $msg;
 }
 
-# copied from Carp::Always. thanks ferreira++
-sub _die {
-    if ( $_[-1] =~ /\n$/s ) {
-        my $arg = pop @_;
-        $arg =~ s/ at .*? line .*?\n$//s;
-        push @_, $arg;
-    }
-    die &Carp::longmess;
-}
-
-1;
+__MIDDLEWARE__
Index: /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/DoCoMoGUID.pm
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/DoCoMoGUID.pm (revision 29266)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/DoCoMoGUID.pm (revision 29321)
@@ -1,37 +1,31 @@
 package HTTP::Engine::Middleware::DoCoMoGUID;
-use Moose;
+use HTTP::Engine::Middleware;
 use Scalar::Util qw/blessed/;
 use HTML::StickyQuery;
 
-sub wrap {
-    my ($class, $next) = @_;
-    
-    sub {
-        my $req = shift;
+after_handle {
+    my ( $c, $self, $req, $res ) = @_;
 
-        my $res = $next->($req);
+    if (   $res->status == 200
+        && $res->content_type =~ /html/
+        && not blessed $res->body
+        && $res->body )
+    {
+        my $body = $res->body;
+        $res->body(
+            sub {
+                my $guid = HTML::StickyQuery->new( 'abs' => 1, );
+                $guid->sticky(
+                    scalarref => \$body,
+                    param     => { guid => 'ON' },
+                );
+                }
+                ->()
+        );
+    }
 
-        if (   $res->status == 200
-            && $res->content_type =~ /html/
-            && not blessed $res->body
-            && $res->body )
-        {
-            my $body = $res->body;
-            $res->body(
-                sub {
-                    my $guid = HTML::StickyQuery->new(
-                        'abs' => 1,
-                    );
-                    $guid->sticky(
-                        scalarref => \$body,
-                        param     => { guid => 'ON' },
-                    );
-                }->()
-            );
-        }
+    $res;
+};
 
-        $res;
-    }
-}
+__MIDDLEWARE__
 
-1;
Index: /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/MobileAttribute.pm
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/MobileAttribute.pm (revision 11524)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/MobileAttribute.pm (revision 29321)
@@ -1,25 +1,9 @@
 package HTTP::Engine::Middleware::MobileAttribute;
-use Moose;
-use HTTP::MobileAttribute;
-use HTTP::Engine::Request;
+use HTTP::Engine::Middleware;
 
-sub setup {
-    my $meta = HTTP::Engine::Request->meta;
-    $meta->make_mutable;
+middleware_method 'mobile_attribute' => sub {
+    my $self = shift;
+    $self->{mobile_attribute} = HTTP::MobileAttribute->new( $self->headers );
+};
 
-    $meta->add_attribute(
-        mobile_attribute => (
-            is => 'ro',
-            isa => 'Object',
-            lazy => 1,
-            default => sub {
-                my $self = shift;
-                $self->{mobile_attribute} = HTTP::MobileAttribute->new($self->headers);
-            },
-        )
-    );
-
-    $meta->make_immutable;
-}
-
-1;
+__MIDDLEWARE__
Index: /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/ModuleReload.pm
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/ModuleReload.pm (revision 29266)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/ModuleReload.pm (revision 29321)
@@ -1,18 +1,14 @@
 package HTTP::Engine::Middleware::ModuleReload;
-use Moose;
+use HTTP::Engine::Middleware;
 use Module::Reload;
 
-sub wrap {
-    my ($class, $next) = shift;
+before_handle {
+    my ( $c, $self, $req ) = @_;
+    Module::Reload->check;
+    $req;
+};
 
-    sub {
-        my $req = shift;
-        Module::Reload->check;
+__MIDDLEWARE__
 
-        $next->($req);
-    };
-}
-
-1;
 __END__
 
Index: /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/Encode.pm
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/Encode.pm (revision 29266)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/Encode.pm (revision 29321)
@@ -1,23 +1,21 @@
 package HTTP::Engine::Middleware::Encode;
-use Moose;
-
+use HTTP::Engine::Middleware;
 use Data::Visitor::Encode;
 
-sub wrap {
-    my ($class, $next) = @_;
+before_handle {
+    my ( $c, $self, $req ) = @_;
 
-    sub {
-        my $req = shift;
-        if (($req->headers->header('Content-Type')||'') =~ /charset=(.+);?$/) {
-            # decode parameters
-            my $encoding = $1;
-            for my $method (qw/params query_params body_params/) {
-                $req->$method( Data::Visitor::Encode->decode($encoding, $req->$method) );
-            }
+    if (( $req->headers->header('Content-Type') || '' ) =~ /charset=(.+);?$/ )
+    {
 
-            $next->($req);
+        # decode parameters
+        my $encoding = $1;
+        for my $method (qw/params query_params body_params/) {
+            $req->$method(
+                Data::Visitor::Encode->decode( $encoding, $req->$method ) );
         }
-    };
-}
+    }
+    $req;
+};
 
-1;
+__MIDDLEWARE__
Index: /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/ReverseProxy.pm
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/ReverseProxy.pm (revision 29266)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/ReverseProxy.pm (revision 29321)
@@ -1,54 +1,58 @@
 package HTTP::Engine::Middleware::ReverseProxy;
-use Moose;
+use HTTP::Engine::Middleware;
 
-sub wrap {
-    my ($class, $next) = @_;
+before_handle {
+    my ( $c, $self, $req ) = @_;
+    my $env = $req->_connection->{env} || {};
 
-    sub {
-        my $req = shift;
+    # in apache httpd.conf (RequestHeader set X-Forwarded-HTTPS %{HTTPS}s)
+    $env->{HTTPS} = $req->headers->{'x-forwarded-https'}
+        if $req->headers->{'x-forwarded-https'};
+    $env->{HTTPS} = 'ON' if $req->headers->{'x-forwarded-proto'};    # Pound
+    $req->secure(1) if $env->{HTTPS} && uc $env->{HTTPS} eq 'ON';
 
-        my $env = $req->_connection->{env} || {};
-        # in apache httpd.conf (RequestHeader set X-Forwarded-HTTPS %{HTTPS}s)
-        $env->{HTTPS} = $req->headers->{'x-forwarded-https'} if $req->headers->{'x-forwarded-https'};
-        $env->{HTTPS} = 'ON'                         if $req->headers->{'x-forwarded-proto'}; # Pound
-        $req->secure(1) if $env->{HTTPS} && uc $env->{HTTPS} eq 'ON';
+    # If we are running as a backend server, the user will always appear
+    # as 127.0.0.1. Select the most recent upstream IP (last in the list)
+    if ( $req->headers->{'x-forwarded-for'} ) {
+        my ( $ip, ) = $req->headers->{'x-forwarded-for'} =~ /([^,\s]+)$/;
+        $req->address($ip);
+    }
 
-        # If we are running as a backend server, the user will always appear
-        # as 127.0.0.1. Select the most recent upstream IP (last in the list)
-        if ($req->headers->{'x-forwarded-for'}) {
-            my ($ip, ) = $req->headers->{'x-forwarded-for'} =~ /([^,\s]+)$/;
-            $req->address($ip);
+    if ( $req->headers->{'x-forwarded-host'} ) {
+        my $host = $req->headers->{'x-forwarded-host'};
+        if ( $host =~ /^(.+):(\d+)$/ ) {
+            $host = $1;
+            $env->{SERVER_PORT} = $2;
         }
+        elsif ( $req->headers->{'x-forwarded-port'} ) {
 
-        if ($req->headers->{'x-forwarded-host'}) {
-            my $host = $req->headers->{'x-forwarded-host'};
-            if ($host =~ /^(.+):(\d+)$/ ) {
-                $host = $1;
-                $env->{SERVER_PORT} = $2;
-            } elsif ($req->headers->{'x-forwarded-port'}) {
-                # in apache httpd.conf (RequestHeader set X-Forwarded-Port 8443)
-                $env->{SERVER_PORT} = $req->headers->{'x-forwarded-port'};
-            }
-            $env->{HTTP_HOST} = $host;
+            # in apache httpd.conf (RequestHeader set X-Forwarded-Port 8443)
+            $env->{SERVER_PORT} = $req->headers->{'x-forwarded-port'};
+        }
+        $env->{HTTP_HOST} = $host;
 
-            $req->headers->header( 'Host' => $env->{HTTP_HOST} );
-        }
-        $req->_connection->{env} = $env;
+        $req->headers->header( 'Host' => $env->{HTTP_HOST} );
+    }
+    $req->_connection->{env} = $env;
 
-        for my $attr (qw/uri base/) {
-            my $scheme = $req->secure ? 'https' : 'http';
-            my $host = $env->{HTTP_HOST} || $env->{SERVER_NAME};
-            my $port = $env->{SERVER_PORT} || ( $req->secure ? 443 : 80 );
-            # my $path_info = $env->{PATH_INFO} || '/';
+    for my $attr (qw/uri base/) {
+        my $scheme = $req->secure ? 'https' : 'http';
+        my $host = $env->{HTTP_HOST} || $env->{SERVER_NAME};
+        my $port = $env->{SERVER_PORT} || ( $req->secure ? 443 : 80 );
 
-            $req->$attr->scheme($scheme);
-            $req->$attr->host($host);
-            $req->$attr->port($port);
-            # $req->$attr->path($path_info);
-            # $req->$attr( $req->$attr->canonical );
-        }
-        $next->($req);
-    };
-}
+        # my $path_info = $env->{PATH_INFO} || '/';
 
-1;
+        $req->$attr->scheme($scheme);
+        $req->$attr->host($host);
+        $req->$attr->port($port);
+
+        # $req->$attr->path($path_info);
+        # $req->$attr( $req->$attr->canonical );
+    }
+    $req;
+};
+
+__MIDDLEWARE__
+
+__END__
+
Index: /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/Role.pm
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/Role.pm (revision 29321)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/lib/HTTP/Engine/Middleware/Role.pm (revision 29321)
@@ -0,0 +1,17 @@
+package HTTP::Engine::Middleware::Role;
+use Mouse::Role;
+
+has 'before_handles' => (
+    is      => 'ro',
+    isa     => 'ArrayRef',
+    default => sub { +[] },
+);
+
+has 'after_handles' => (
+    is      => 'ro',
+    isa     => 'ArrayRef',
+    default => sub { +[] },
+);
+
+1;
+
Index: /lang/perl/HTTP-Engine-Middleware/trunk/Makefile.PL
===================================================================
--- /lang/perl/HTTP-Engine-Middleware/trunk/Makefile.PL (revision 11963)
+++ /lang/perl/HTTP-Engine-Middleware/trunk/Makefile.PL (revision 29321)
@@ -11,5 +11,5 @@
 all_from 'lib/HTTP/Engine/Middleware.pm';
 
-requires 'HTTP::Engine' => '0.0.8';
+requires 'HTTP::Engine' => '0.1.1';
 
 features(
@@ -21,5 +21,6 @@
     'DebugScreen' => [
         -default => 0,
-        recommends_hack('Carp::Always'),
+        recommends_hack('CGI::ExceptionManager'),
+        recommends_hack('Scope::Upper'),
     ],
 
@@ -27,4 +28,19 @@
         -default => 0,
         recommends_hack('HTML::StickyQuery'),
+    ],
+
+    'Encode' => [
+        -default => 0,
+        recommends_hack('Data::Visitor::Encode'),
+    ],
+
+    'MobileAttribute' => [
+        -default => 0,
+        recommends_hack('HTTP::MobileAttribute'),
+    ],
+
+    'MobileAgent' => [
+        -default => 0,
+        recommends_hack('HTTP::MobileAgent'),
     ],
 );
