Catalyst-Plugin-ResponseFrom
view release on metacpan or search on metacpan
lib/Catalyst/Plugin/ResponseFrom.pm view on Meta::CPAN
if ($path =~ s/^(.*?)\@//) {
my $basic = $1;
unshift @rest, 'Authorization:', 'Basic '.MIME::Base64::encode($basic);
}
my $request = HTTP::Request->new($method => $path);
my @params;
while (my ($header, $value) = splice(@rest, 0, 2)) {
unless ($header =~ s/:$//) {
push @params, $header, $value;
}
$header =~ s/_/-/g;
if ($header eq 'Content') {
$request->content($value);
} else {
$request->headers->push_header($header, $value);
}
}
if (($method eq 'POST' or $method eq 'PUT') and @params) {
my $content = do {
my $url = URI->new('http:');
$url->query_form(@params);
$url->query;
};
$request->header('Content-Type' => 'application/x-www-form-urlencoded');
$request->header('Content-Length' => length($content));
$request->content($content);
}
return $request;
};
sub psgi_response_from {
my $self = shift;
my $http_request = $self->$_request_spec_to_http_request(@_);
my $psgi_env = HTTP::Message::PSGI::req_to_psgi($http_request);
return my $psgi_response = $self->psgi_app->($psgi_env);
}
*response_from = \&http_response_from;
sub http_response_from {
my $self = shift;
my $psgi_response = $self->psgi_response_from(@_);
return my $http_response = HTTP::Message::PSGI::res_from_psgi($psgi_response);
}
sub redispatch_to {
my $self = shift;
my $psgi_response = $self->psgi_response_from(@_);
$self->res->from_psgi_response($psgi_response);
$self->detach;
}
1;
=head1 NAME
Catalyst::Plugin::ResponseFrom - Use the response of a public endpoint.
=head1 SYNOPSIS
package MyApp;
use Catalyst 'ResponseFrom';
MyApp->setup;
package MyApp::Controller::Example;
use Moose;
use MooseX::MethodAttributes;
use HTTP::Request::Common;
extends 'Catalyst::Controller';
sub as_http_request :Local {
my ($self, $c) = @_;
$c->redispatch_to(GET $c->uri_for($self->action_for('target')));
# For simple GETs you can just use $c->uri_for style params like:
$c->redispatch_to($self->action_for('target'));
}
sub as_spec :Local {
my ($self, $c) = @_;
$c->redispatch_to('GET' => $c->uri_for($self->action_for('target')));
}
sub collect_response :Local {
my ($self, $c) = @_;
my $http_response = $c->http_response_from(GET => $c->uri_for($self->action_for('target')));
}
sub target :Local {
my ($self, $c) = @_;
$c->response->content_type('text/plain');
$c->response->body("This is the target action");
}
=head1 DESCRIPTION
L<Catalyst> allows you to forward to a private named actions, but there is no
built in method to 'forward' to a public URL. You might want to do this rather
than (for example) issue a redirect.
Additionally there is no 'subrequest' like feature (and L<Catalyst::Plugin::Subrequest>
uses internal hacks to function). There maye be cases, such as in testing, where
it would be great to be able to issue a public URL request and collect the response.
This plugin is an attempt to give you these features in a clean manner that does not
rely on internal L<Catalyst> details that are subject to change. However you must be
using a more modern version of L<Catalyst> (the current requirement is 5.90060).
=head1 METHODS
This plugin adds the following methods to your L<Catalyst> application. All methods
share the same function signature (this approach and following documentation 'borrowed'
from L<Web::Simple>):
my $psgi_response = $app->http_response_from(GET => '/' => %headers);
( run in 0.532 second using v1.01-cache-2.11-cpan-2398b32b56e )