Apply patch to be able to get the entire request, from RT#39486
[catagits/Catalyst-Plugin-SubRequest.git] / lib / Catalyst / Plugin / SubRequest.pm
CommitLineData
aae30f91 1package Catalyst::Plugin::SubRequest;
2
3use strict;
61114b68 4use warnings;
588fd7ac 5use Time::HiRes qw/tv_interval/;
aae30f91 6
87c672db 7our $VERSION = '0.16';
aae30f91 8
aae30f91 9=head1 NAME
10
11Catalyst::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 36Make subrequests to actions in Catalyst. Uses the catalyst
37dispatcher, so it will work like an external url call.
87c672db 38Methods are provided both to get the body of the response and the full
39response (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
47=item sub_request
48
4f38f6a7 49Takes a full path to a path you'd like to dispatch to.
87c672db 50
51If the path is passed as a hash ref then it can include body, action,
52match and path.
53
54An optional second argument as hashref can contain data to put into the
55stash of the subrequest.
56
57An optional third argument as hashref can contain data to pass as
58parameters to the subrequest.
59
60Returns the body of the response.
61
62=item subreq_res [path as string or hash ref], [stash as hash ref], [parameters as hash ref]
63
64=item sub_request_response
65
66Like C<sub_request()>, but returns a full L<Catalyst::Response> object.
aae30f91 67
a1e0150f 68=back
aae30f91 69
70=cut
71
72*subreq = \&sub_request;
87c672db 73*subreq_res = \&sub_request_response;
aae30f91 74
75sub sub_request {
87c672db 76 return shift->sub_request_response( @_ )->body ;
77}
78
79sub sub_request_response {
885f6da0 80 my ( $c, $path, $stash, $params ) = @_;
8c464987 81
5bd316a5 82 $path =~ s#^/##;
29ec3000 83
84 $params ||= {};
85
86 my %request_mods = (
87 body => undef,
88 action => undef,
89 match => undef,
90 parameters => $params,
91 );
92
93 if (ref $path eq 'HASH') {
94 @request_mods{keys %$path} = values %$path;
95 } else {
96 $request_mods{path} = $path;
97 }
61114b68 98 $request_mods{_body} = delete $request_mods{body};
29ec3000 99
100 my $fake_engine = bless(
101 {
102 orig_request => $c->req,
103 request_mods => \%request_mods,
104 },
105 'Catalyst::Plugin::SubRequest::Internal::FakeEngine'
106 );
107
108 my $class = ref($c);
109
110 no strict 'refs';
111 no warnings 'redefine';
112
113 local *{"${class}::engine"} = sub { $fake_engine };
114
115 my $inner_ctx = $class->prepare;
116
117 $inner_ctx->stash($stash || {});
a1e0150f 118
119
6162c29a 120 $c->stats->profile(
121 begin => 'subrequest: /' . $path,
122 comment => '',
a1e0150f 123 ) if ($c->debug);
124
6162c29a 125 $inner_ctx->dispatch;
126
127 $c->stats->profile( end => 'subrequest: /' . $path ) if ($c->debug);
a1e0150f 128
87c672db 129 return $inner_ctx->response;
aae30f91 130}
131
132=head1 SEE ALSO
133
134L<Catalyst>.
135
61114b68 136=head1 AUTHORS
aae30f91 137
138Marcus Ramberg, C<mramberg@cpan.org>
139
61114b68 140Tomas Doran (t0m) C<< bobtfish@bobtfish.net >>
141
aae30f91 142=head1 THANK YOU
143
144SRI, for writing the awesome Catalyst framework
145
146=head1 COPYRIGHT
147
85ec975f 148Copyright (c) 2005 - 2008
61114b68 149the Catalyst::Plugin::SubRequest L</AUTHORS>
85ec975f 150as listed above.
151
152=head1 LICENSE
153
aae30f91 154This program is free software, you can redistribute it and/or modify it under
155the same terms as Perl itself.
156
157=cut
158
29ec3000 159package # hide from PAUSE
160 Catalyst::Plugin::SubRequest::Internal::FakeEngine;
161
162sub AUTOLOAD { return 1; } # yeah yeah yeah
163
164sub prepare {
165 my ($self, $c) = @_;
166 my $req = $c->request;
a1e0150f 167
cc9f9d31 168 @{$req}{keys %{$self->{orig_request}}} = values %{$self->{orig_request}};
169 while (my ($key,$value) = each %{$self->{request_mods}}) {
597f0a02 170 if (my $mut = $req->can($key)) {
171 $req->$mut($value);
172 } else {
173 $req->{$key} = $value;
174 }
175 }
29ec3000 176}
177
aae30f91 1781;