Commit | Line | Data |
aae30f91 |
1 | package Catalyst::Plugin::SubRequest; |
2 | |
3 | use strict; |
61114b68 |
4 | use warnings; |
f3f2edc9 |
5 | use Plack::Request; |
aae30f91 |
6 | |
96e0398b |
7 | our $VERSION = '0.20'; |
aae30f91 |
8 | |
aae30f91 |
9 | =head1 NAME |
10 | |
11 | Catalyst::Plugin::SubRequest - Make subrequests to actions in Catalyst |
12 | |
13 | =head1 SYNOPSIS |
14 | |
15 | use Catalyst 'SubRequest'; |
16 | |
87c672db |
17 | my $res_body = $c->subreq('/test/foo/bar', { template => 'magic.tt' }); |
aae30f91 |
18 | |
87c672db |
19 | my $res_body = $c->subreq( { |
20 | path => '/test/foo/bar', |
21 | body => $body |
22 | }, { |
23 | template => 'magic.tt' |
24 | }); |
25 | |
26 | # Get the full response object |
27 | my $res = $c->subreq_res('/test/foo/bar', { |
28 | template => 'mailz.tt' |
29 | }, { |
30 | param1 => 23 |
31 | }); |
32 | $c->log->warn( $res->content_type ); |
4f38f6a7 |
33 | |
aae30f91 |
34 | =head1 DESCRIPTION |
35 | |
8c464987 |
36 | Make subrequests to actions in Catalyst. Uses the catalyst |
37 | dispatcher, so it will work like an external url call. |
87c672db |
38 | Methods are provided both to get the body of the response and the full |
39 | response (L<Catalyst::Response>) object. |
aae30f91 |
40 | |
41 | =head1 METHODS |
42 | |
a1e0150f |
43 | =over 4 |
aae30f91 |
44 | |
4f38f6a7 |
45 | =item subreq [path as string or hash ref], [stash as hash ref], [parameters as hash ref] |
aae30f91 |
46 | |
51589f61 |
47 | =item subrequest |
48 | |
aae30f91 |
49 | =item sub_request |
50 | |
4f38f6a7 |
51 | Takes a full path to a path you'd like to dispatch to. |
87c672db |
52 | |
53 | If the path is passed as a hash ref then it can include body, action, |
54 | match and path. |
55 | |
56 | An optional second argument as hashref can contain data to put into the |
57 | stash of the subrequest. |
58 | |
59 | An optional third argument as hashref can contain data to pass as |
60 | parameters to the subrequest. |
61 | |
62 | Returns the body of the response. |
63 | |
64 | =item subreq_res [path as string or hash ref], [stash as hash ref], [parameters as hash ref] |
65 | |
51589f61 |
66 | =item subrequest_response |
67 | |
87c672db |
68 | =item sub_request_response |
69 | |
70 | Like C<sub_request()>, but returns a full L<Catalyst::Response> object. |
aae30f91 |
71 | |
a1e0150f |
72 | =back |
aae30f91 |
73 | |
74 | =cut |
75 | |
8d59e5b8 |
76 | *subreq = \&sub_request; |
77 | *subrequest = \&sub_request; |
78 | *subreq_res = \&sub_request_response; |
51589f61 |
79 | *subrequest_response = \&sub_request_response; |
aae30f91 |
80 | |
81 | sub sub_request { |
8d59e5b8 |
82 | return shift->sub_request_response(@_)->body; |
87c672db |
83 | } |
84 | |
85 | sub sub_request_response { |
8d59e5b8 |
86 | my ( $c, $path, $stash, $params ) = @_; |
87 | $stash ||= {}; |
88 | my $env = $c->request->env; |
89 | my $req = Plack::Request->new($env); |
90 | my $uri = $req->uri; |
91 | $uri->query_form( $params || {} ); |
92 | local $env->{QUERY_STRING} = $uri->query || ''; |
93 | local $env->{PATH_INFO} = $path; |
94 | local $env->{REQUEST_URI} = $env->{SCRIPT_NAME} . $path; |
95 | $env->{REQUEST_URI} =~ s|//|/|g; |
96 | my $class = ref($c) || $c; |
97 | |
98 | $c->stats->profile( |
99 | begin => 'subrequest: ' . $path, |
100 | comment => '', |
101 | ) if ( $c->debug ); |
102 | |
103 | # need this so that |
104 | my $writer = Catalyst::Plugin::SubRequest::Writer->new; |
105 | my $response_cb = sub { $writer }; |
106 | my $i_ctx = $class->prepare( env => $env, response_cb => $response_cb ); |
107 | $i_ctx->stash($stash); |
108 | $i_ctx->dispatch; |
109 | $i_ctx->finalize; |
110 | $c->stats->profile( end => 'subrequest: ' . $path ) if $c->debug; |
111 | |
112 | $i_ctx->response->body($writer->body); |
113 | |
114 | return $i_ctx->response; |
aae30f91 |
115 | } |
116 | |
8d59e5b8 |
117 | package Catalyst::Plugin::SubRequest::Writer; |
118 | use Moose; |
119 | has body => ( |
120 | isa => 'Str', |
121 | is => 'ro', |
122 | traits => ['String'], |
123 | default => '', |
124 | handles => { write => 'append' } |
125 | ); |
126 | has _is_closed => ( isa => 'Bool', is => 'rw', default => 0 ); |
127 | sub close { shift->_is_closed(1) } |
128 | |
129 | around write => sub { |
130 | my $super = shift; |
131 | my $self = shift; |
132 | return if $self->_is_closed; |
133 | $self->$super(@_); |
134 | }; |
135 | |
aae30f91 |
136 | =head1 SEE ALSO |
137 | |
138 | L<Catalyst>. |
139 | |
61114b68 |
140 | =head1 AUTHORS |
aae30f91 |
141 | |
142 | Marcus Ramberg, C<mramberg@cpan.org> |
143 | |
61114b68 |
144 | Tomas Doran (t0m) C<< bobtfish@bobtfish.net >> |
145 | |
7b9c5d16 |
146 | =head1 MAINTAINERS |
147 | |
148 | Eden Cardim (edenc) C<eden@insoli.de> |
149 | |
aae30f91 |
150 | =head1 THANK YOU |
151 | |
152 | SRI, for writing the awesome Catalyst framework |
d35825f6 |
153 | |
7b9c5d16 |
154 | MIYAGAWA, for writing the awesome Plack toolkit |
aae30f91 |
155 | |
156 | =head1 COPYRIGHT |
157 | |
d7361335 |
158 | Copyright (c) 2005 - 2011 |
61114b68 |
159 | the Catalyst::Plugin::SubRequest L</AUTHORS> |
85ec975f |
160 | as listed above. |
161 | |
162 | =head1 LICENSE |
163 | |
aae30f91 |
164 | This program is free software, you can redistribute it and/or modify it under |
165 | the same terms as Perl itself. |
166 | |
167 | =cut |
168 | |
169 | 1; |