# Make it easier to mount PSGI apps under catalyst
+my $psgi_app = sub {
+ my $req = Plack::Request->new(shift);
+ return [200,[],[$req->path]];
+};
+
{
+ package MyApp::PSGIObject;
+
+ sub as_psgi {
+ return [200, ['Content-Type' => 'text/plain'], ['as_psgi']];
+ };
+
package MyApp::Controller::Docs;
+ $INC{'MyApp/Controller/Docs.pm'} = __FILE__;
use base 'Catalyst::Controller';
use Plack::Request;
use Catalyst::Utils;
- my $psgi_app = sub {
- my $req = Plack::Request->new(shift);
- return [200,[],[$req->path]];
- };
+ sub as_psgi :Local {
+ my ($self, $c) = @_;
+ my $as_psgi = bless +{}, 'MyApp::PSGIObject';
+ $c->res->from_psgi_response($as_psgi);
+ }
sub name :Local {
my ($self, $c) = @_;
$psgi_app->($env));
}
+ sub filehandle :Local {
+ my ($self, $c, $arg) = @_;
+ my $path = File::Spec->catfile('t', 'utf8.txt');
+ open(my $fh, '<', $path) || die "trouble: $!";
+ $c->res->from_psgi_response([200, ['Content-Type'=>'text/html'], $fh]);
+ }
+
+ sub direct :Local {
+ my ($self, $c, $arg) = @_;
+ $c->res->from_psgi_response([200, ['Content-Type'=>'text/html'], ["hello","world"]]);
+ }
+
+ sub streaming_body :Local {
+ my ($self, $c) = @_;
+ my $psgi_app = sub {
+ my $respond = shift;
+ my $writer = $respond->([200,["Content-Type" => "text/plain"]]);
+ $writer->write("body");
+ $writer->close;
+ };
+ $c->res->from_psgi_response($psgi_app);
+ }
+ sub streaming_body_with_charset :Local {
+ my ($self, $c) = @_;
+ my $psgi_app = sub {
+ my $respond = shift;
+ my $writer = $respond->([200,["Content-Type" => "text/plain; charset=utf-8"]]);
+ $writer->write("body");
+ $writer->close;
+ };
+ #$c->clear_encoding;
+ $c->res->from_psgi_response($psgi_app);
+ }
+
package MyApp::Controller::User;
+ $INC{'MyApp/Controller/User.pm'} = __FILE__;
use base 'Catalyst::Controller';
use Plack::Request;
use Catalyst::Utils;
- my $psgi_app = sub {
- my $req = Plack::Request->new(shift);
- return [200,[],[$req->path]];
- };
-
sub local_example :Local {
my ($self, $c) = @_;
my $env = $self->get_env($c);
$c->res->from_psgi_response(
$psgi_app->($env));
}
-
+
+ sub mounted :Local Args(1) {
+ my ($self, $c, $arg) = @_;
+ our $app ||= ref($c)->psgi_app;
+ my $env = $self->get_env($c);
+ $c->res->from_psgi_response(
+ $app->($env));
+ }
+
+ sub mount_arg :Path(/mounted) Arg(1) {
+ my ($self, $c, $arg) = @_;
+ my $uri = $c->uri_for( $self->action_for('local_example_args1'),$arg);
+ $c->res->body("$uri");
+ }
+
+ sub mount_noarg :Path(/mounted_no_arg) {
+ my ($self, $c) = @_;
+ my $uri = $c->uri_for( $self->action_for('local_example_args1'),444);
+ $c->res->body("$uri");
+ }
+
+
sub get_env {
my ($self, $c) = @_;
if($c->req->query_parameters->{path_prefix}) {
}
}
- $INC{'MyApp/Controller/User.pm'} = __FILE__;
-
package MyApp;
use Catalyst;
MyApp->setup;
use Test::More;
use Catalyst::Test 'MyApp';
+{
+ my ($res, $c) = ctx_request('/docs/as_psgi');
+ is $res->content, 'as_psgi';
+}
+
+{
+ my ($res, $c) = ctx_request('/user/mounted/111?path_prefix=1');
+ is $c->action, 'user/mounted';
+ is $res->content, 'http://localhost/user/user/local_example_args1/111';
+ is_deeply $c->req->args, [111];
+}
+
+{
+ my ($res, $c) = ctx_request('/user/mounted/mounted_no_arg?env_path=1');
+ is $c->action, 'user/mounted';
+ is $res->content, 'http://localhost/user/mounted/user/local_example_args1/444';
+ is_deeply $c->req->args, ['mounted_no_arg'];
+}
+
# BEGIN [user/local_example]
{
my ($res, $c) = ctx_request('/user/local_example');
# END [/user/local_example_args1/***/]
-# BEGIN [/user/path-example]
+# BEGIN [/user/path-example]
{
my ($res, $c) = ctx_request('/user/path-example');
is_deeply $c->req->args, [111];
}
-done_testing();
-
-__END__
-
-
-use Plack::App::URLMap;
-use HTTP::Request::Common;
-use HTTP::Message::PSGI;
-
-my $urlmap = Plack::App::URLMap->new;
-
-my $app1 = sub {
- my $env = shift;
- return [200, [], [
- "REQUEST_URI: $env->{REQUEST_URI}, FROM: $env->{MAP_TO}, PATH_INFO: $env->{PATH_INFO}, SCRIPT_NAME $env->{SCRIPT_NAME}"]];
-};
-
-$urlmap->map("/" => sub { my $env = shift; $env->{MAP_TO} = '/'; $app1->($env)});
-$urlmap->map("/foo" => sub { my $env = shift; $env->{MAP_TO} = '/foo'; $app1->($env)});
-$urlmap->map("/bar/baz" => sub { my $env = shift; $env->{MAP_TO} = '/foo/bar'; $app1->($env)});
+{
+ use utf8;
+ use Encode;
+ my ($res, $c) = ctx_request('/docs/filehandle');
+ is Encode::decode_utf8($res->content), "<p>This is stream_body_fh action ♥</p>\n";
+}
-my $app = $urlmap->to_app;
+{
+ my ($res, $c) = ctx_request('/docs/direct');
+ is $res->content, "helloworld";
+}
-warn $app->(req_to_psgi(GET '/'))->[2]->[0];
-warn $app->(req_to_psgi(GET '/111'))->[2]->[0];
-warn $app->(req_to_psgi(GET '/foo'))->[2]->[0];
-warn $app->(req_to_psgi(GET '/foo/222'))->[2]->[0];
-warn $app->(req_to_psgi(GET '/bar/baz'))->[2]->[0];
-warn $app->(req_to_psgi(GET '/bar/baz/333'))->[2]->[0];
+{
+ my ($res, $c) = ctx_request('/docs/streaming_body');
+ is $res->content, "body";
+}
+{
+ my ($res, $c) = ctx_request('/docs/streaming_body_with_charset');
+ is $res->content, "body";
+}
+done_testing();