view release on metacpan or search on metacpan
lib/Apache2/Controller.pm view on Meta::CPAN
The controller handler returns your set HTTP status code
or OK (0) to Apache. In general you return the status code
that you want to set, or return OK. Or you can set it with
C<< $r->status() >> and return OK.
You can't return DONE or DECLINED. (If you find you need
to do that for some reason please contact me.)
See L<Apache2::Const/:http>
and L<Apache2::Controller::Refcard>. You can also set
C<< status_line() >> or throw L<Apache2::Controller::X>
exceptions to be processed by an error template,
if you're using some form of template rendering - see
the section on errors below.
Add handlers in your config file with your own modules which
C<use base> to inherit from these classes as you need them:
=head2 PerlHeaderParserHandler Apache2::Controller::Session
C<< $r->pnotes->{a2c}{session} >> automatically loaded from and
lib/Apache2/Controller.pm view on Meta::CPAN
access those methods via C<< $self->{r} >>.
=head1 RETURN VALUES
Your controller methods should use C<< eval { } >> if necessary and
act accordingly, set the right things for C<Apache2::RequestRec>
and return the right HTTP constant. See L<Apache2::Const/:http>
and L<Apache2::Controller::Refcard>.
In the event of an error, if you wish, use L<Apache2::Controller::X>
and throw one with field 'status' set to a valid HTTP return code.
This lets you implement nice error templates if your controller uses
L<Apache2::Controller::Render::Template> as a base.
See L<ERRORS> below.
Success in the controller method normally should just return the
appropriate HTTP status code. You can return HTTP_OK (200) if that
is what you mean, or it is the default status if you return OK (0).
Or, if you do C<< $self->status( Apache2::Const::HTTP_SOMETHING ) >>
and then just C<< return() >>
lib/Apache2/Controller.pm view on Meta::CPAN
to the error log at the WARN level of L<Log::Log4perl> from
this module's namespace. If errors crop up from
other A2C request phase handlers, try setting
WARN log level for L<Apache2::Controller::NonResponseBase>
or L<Apache2::Controller::NonResponseRequest>.
Also see L<Apache2::Controller::Render::Template>.
You can use or subclass L<Apache2::Controller::X>,
to use C<< a2cx() >>,
or you can throw your own exception objects,
or just C<< die() >>, or C<< croak() >>,
or set C<< $self->status >>, headers etc., possibly printing content,
or return the appropriate status from your controller method.
See L<Apache2::Controller::X> for help on throwing exceptions
with HTTP status, data dumps, etc.
If your code does break, die or throw an exception, this is
caught by Apache2::Controller. If your controller module implements
an C<<error() >> method,
then C<< $handler->error() >> will be called passing the C<< $EVAL_ERROR >>
or exception object as the first argument.
package MyApp::C::Foo;
use YAML::Syck;
# ...
sub error {
my ($self, $X) = @_;
lib/Apache2/Controller.pm view on Meta::CPAN
if (exists $supports_error_method{$class}) {
$error_method_status = $handler->error($X);
}
elsif ($class->can('error')) {
$supports_error_method{$class} = 1;
$error_method_status = $handler->error($X);
}
$used_error_method_successfully = 1;
};
# trap unknown errors that might have been thrown
# by the error() subroutine
$X = Exception::Class->caught('Apache2::Controller::X')
|| $EVAL_ERROR
|| $X;
}
my $x_status = $ref && $blessed && $X->can('status')
? $X->status : undef;
$status
lib/Apache2/Controller/Auth/OpenID.pm view on Meta::CPAN
use Net::OpenID::Consumer;
use URI;
use List::MoreUtils qw(any);
use Apache2::Const -compile => qw( OK SERVER_ERROR REDIRECT );
use Apache2::Controller::X;
=head2 new
Overloaded constructor will always throw an L<Apache2::Controller::X>
because this module does not work.
=cut
sub new {
a2cx __PACKAGE__." is disabled, does not work, do not use.";
}
# hopefully we get the same default consumer secret as in top level
use Apache2::Controller::Const qw( $DEFAULT_CONSUMER_SECRET );
lib/Apache2/Controller/DBI/Connector.pm view on Meta::CPAN
=head1 METHODS
=head2 process
Gets DBI connect arguments by calling C<< $self->dbi_connect_args() >>,
then connects C<< $dbh >> and stashes it in C<< $r->pnotes->{a2c}{dbh} >>
or the name you select.
The $dbh has a reference in package space, so controllers using it
should always call commit or rollback. It's good practice to use
C<< eval >> anyway and throw an L<Apache2::Controller::X> or
your subclass of it (using C<< a2cx() >>,
so you can see the function path trace in the logs when the error occurs.
The package-space $dbh for the child persists across requests, so
it is never destroyed. However, it is assigned with C<< DBI->connect() >>
on every request, so that L<Apache::DBI> will cache the database handle and
actually connect it only if it cannot be pinged.
=cut
lib/Apache2/Controller/Dispatch.pm view on Meta::CPAN
Subclasses of this module implement C<< find_controller() >>
in different ways, usually interpreting the URI from a
hash reference returned by C<< dispatch_map() >> in your subclass.
Or, if you provide the directive C<< A2C_Dispatch_Map >> to specify
a map file, this module will load it with L<YAML::Syck/LoadFile>.
See L<Apache2::Controller::Dispatch::Simple> and
L<Apache2::Controller::Dispatch::HashTree> for other
dispatch possibilities.
Any implementation of find_controller() should throw an
L<Apache2::Controller::X> with status C<< Apache2::Const::NOT_FOUND >>
in the
event that the detected method selected does not appear in the list of
C<< allowed_methods() >> in the controller module. ex:
a2cx status => Apache2::Const::NOT_FOUND;
See L<Apache2::Controller::Funk/check_allowed_method>. This is
internal stuff mostly, you don't have to implement your own
type of dispatch mechanism unless you are a nut like me.
lib/Apache2/Controller/Dispatch.pm view on Meta::CPAN
$self->find_controller();
my $controller = $self->{controller} = $pnotes->{a2c}{controller};
DEBUG "found controller '$controller'";
# save the dispatch class name in notes in case we have to
# re-dispatch somewhere along the line if the uri changes
# (this is done by Apache2::Controller::Auth::OpenID, for instance)
$pnotes->{a2c}{dispatch_class} = $class;
# set the handler for that class
# - this has to be the last thing it does in case an exception is thrown
DEBUG "setting PerlResponseHandler '$controller'";
$r->set_handlers(PerlResponseHandler => [ "$controller" ]);
# "" == lame but true, must stringify lib name because
# the value is some kind of blessed scalar reference or something
DEBUG sub { "Done with process() for uri ".$r->uri };
return Apache2::Const::OK;
}
lib/Apache2/Controller/Funk.pm view on Meta::CPAN
=cut
use version;
our $VERSION = version->new('1.001.001');
=head1 SYNOPSIS
$bool = controller_allows_method($class, $method);
check_allowed_method($class, $method); # throws NOT_FOUND exception
=head1 DESCRPTION
Useful routines for both Apache2::Controller and Apache2::Controller::Dispatch
objects to run. Results and whether to 'require' are cached in this package's
namespace across requests, optimizing efficiency per mod_perl2 child, and are
queried futher using 'exists', which is very fast.
=cut
lib/Apache2/Controller/Log/SessionSave.pm view on Meta::CPAN
use Apache2::Controller::X;
use Apache2::Controller::Const qw( $DEFAULT_SESSION_SECRET );
=head2 process
If aborted connection, don't save, and return.
If status >- 300 and not set C<< $r->pnotes->{a2c}{session_force_save} >>,
don't save, and return.
If session object is not tied, throw an error. This may not do
anything noticible to the user since the request response is
finished, but you'll see it in the log.
Update the top-level timestamp in the session if the directive
C<A2C_Session_Always_Save> is set.
Untie the session so Apache::Session saves it or not.
=cut
lib/Apache2/Controller/Methods.pm view on Meta::CPAN
of C<Apache2::Cookie>, and input headers could possibly change
via filters, and it would create a circular reference to C<< $r >>
if you stuck it in pnotes. It always creates a new Jar object,
which acts as a utility object to parse the source information
that remains in C<< $r >>, if I understand this correctly.
If the directive << A2C_Skip_Bogus_Cookies >> is set, fetches
jar in eval and returns C<< $EVAL_ERROR->jar >> if the error
is an L<APR::Request::Error> and the code is C<< APR::Request::Error::NOTOKEN >>,
indicating a cookie with a value like '1' sent by a defective client.
Any other L<APR::Error> will be re-thrown as per that doc,
otherwise A2C will throw an L<Apache2::Controller::X> with the error.
(See L<http://comments.gmane.org/gmane.comp.apache.apreq/4477> -
closes RT #61744, thanks Arkadius Litwinczuk.) Skipping these
errors is optional since they might be important for debugging
clients that send invalid headers.
See L<Apache2::Cookie>, L<Apache2::Controller::Directives>.
=cut
sub get_cookie_jar {
lib/Apache2/Controller/Methods.pm view on Meta::CPAN
}
sub _get_cookie_jar_normal {
my ($self) = @_;
my $r = $self->{r};
my $jar;
eval { $jar = Apache2::Cookie::Jar->new($r) };
if (my $err = $EVAL_ERROR) {
my $ref = ref $err;
DEBUG "error creating cookie jar (reftype '$ref'): '$err'";
die $err if $ref; # rethrow blessed APR::Error errors
a2cx "unknown error creating cookie jar: '$err'";
}
DEBUG sub {
my $cookie = $r->headers_in->{Cookie};
$cookie = $cookie ? qq{$cookie} : '[no raw cookie string]';
eval { my @cookies = $jar->cookies() };
a2cx "error getting cookie from jar that worked: '$EVAL_ERROR'"
if $EVAL_ERROR;
return
"raw cookie header: $cookie\n"
lib/Apache2/Controller/Methods.pm view on Meta::CPAN
my $errstr = APR::Error::strerror($code);
DEBUG sub {
my $ip = $r->connection->remote_ip
|| '[ could not detect remote ip?? ]';
return "bad cookies from ip $ip, skipping error: '$err'"
." ($code/$errstr)";
};
$jar = $err->jar;
}
else {
DEBUG "rethrowing other APR::Error: '$err'";
die $err;
}
}
else {
a2cx "unknown error (reftype '$ref') getting cookie jar: '$err'";
}
}
DEBUG sub {
my $cookie = $r->headers_in->{Cookie};
$cookie = $cookie ? qq{$cookie} : '[no raw cookie string]';
lib/Apache2/Controller/Refcard.pm view on Meta::CPAN
=head2 status
If you're like me, you get confused as to which status codes are http
status codes and which ones are used internally by Apache2 to signal the
&handler subroutine exit status and return or deny further control to
the server.
$r->status is set with the right value, usually HTTP_OK or
HTTP_(which might be overridden by an error in case an
exception is thrown somewhere with ), and then handler() returns
Apache2::Const::OK in any case. So far. This might change if
someone gets me wise to what's actually going on.
RC Apache2::Const::* HTTP::Status::status_message($RC)
-----------------------------------------------------------------------
-02 DONE -
-01 DECLINED -
000 OK -
100 HTTP_CONTINUE Continue
101 HTTP_SWITCHING_PROTOCOLS Switching Protocols
lib/Apache2/Controller/Render/Template.pm view on Meta::CPAN
my $tt = $self->get_tt_obj();
# pass Apache2::Request object to print directly.
$tt->process($template, $self->{stash}, $self->{r}) || a2cx $tt->error();
return;
}
=head2 error
If your template directory contains a subdirectory named 'error',
then when the controller throws an exception, the exception object will
be passed to a selected error template as 'X' in the stash. It also
sets status (number) and status_line
(from HTTP::Status::status_message() or from the values
set in the L<Apache2::Controller::X> exception).
If you have a template $template_dir/error/$status.html,
where $status is the numeric http status code,
then it will use that template.
For example:
lib/Apache2/Controller/Render/Template.pm view on Meta::CPAN
my $template_dir = $self->get_directive('A2C_Render_Template_Path')
|| a2cx 'A2C_Render_Template_Path not defined.';
DEBUG sub { "A2C_Render_Template_Path:\n".Dump($template_dir) };
if (exists $error_templates{$template_dir}{$status_file}) {
my $template = $error_templates{$template_dir}{$status_file};
# if exists but undefined, it means it failed totally.
# forget about using an error template and just rethrow the error
if (!defined $template) {
if (ref($X) && $X->isa('Apache2::Controller::X')) {
$X->rethrow();
}
else {
a2cx "Cannot process any template for unknown-type error: $X";
}
}
$self->{template} = $template;
$self->render();
}
else {
lib/Apache2/Controller/Render/Template.pm view on Meta::CPAN
my %try_errors = ( );
$self->{template} = "errors/$status_file.html";
eval { $self->render() };
# if got an error using that file name, try the default error file:
if ($EVAL_ERROR) {
$try_errors{$self->{template}} = "$EVAL_ERROR";
$self->{template} = "errors/default.html";
eval { $self->render() };
# and if error template doesn't work, throw back original error
if ($EVAL_ERROR) {
DEBUG "Error rendering error file: $EVAL_ERROR";
$try_errors{$self->{template}} = "$EVAL_ERROR";
$error_templates{$template_dir}{$status_file} = undef;
if (ref $X && $X->isa('Apache2::Controller::X')) {
$X->rethrow();
}
else {
my $dump = { tries => \%try_errors, reftype => ref $X };
a2cx message => "$X",
status => $status,
status_line => $status_line,
'dump' => $dump;
}
}
}
lib/Apache2/Controller/Session.pm view on Meta::CPAN
to save stuff, and then if something goes wrong, it is as if this
rolls back.
A C<PerlLogHandler> subroutine is 'unshifted' to the request stack
which decides whether to save changes to the session. By default,
it saves changes only if A) the connection is not aborted,
and B) your controller set HTTP status < 300,
i.e. it returned C<OK> (0), one of the C<HTTP_CONTINUE> family (100+)
or one of the C<HTTP_OK> family (200+).
So for an C<HTTP_SERVER_ERROR>, or throwing an exception, redirecting,
forbidding access, etc (>= 300), it normally would not save changes.
If your L<Apache2::Controller> controller module returns one of these
non-OK statuses, but you want to force the saving of the session contents,
set C<< $self->pnotes->{a2c}{session_force_save} = 1 >> before
your response phase controller returns a status to L<Apache2::Controller>.
If the connection is aborted mid-way (i.e. the pipe was broken
due to a network failure or the user clicked 'stop'
in the browser), then the session will not be saved,
whether you set the force save flag or not.
lib/Apache2/Controller/Session.pm view on Meta::CPAN
query params, and C<set_session_id()> would push a C<PerlOutputFilterHandler>
to post-process all other handler output and append the session id param
onto any url links that refer to our site. That would be cool...
release your own plug-in.
If you wanted to do it with combined cookies and url params in
this way you could
overload C<get_session_id()> and C<set_session_id()>, etc. etc.
=head1 ERRORS
C<<Apache2::Controller::Session>> will throw an error exception if the
session setup encounters an error.
=head1 METHODS
=cut
use strict;
use warnings FATAL => 'all';
use English '-no_match_vars';
lib/Apache2/Controller/X.pm view on Meta::CPAN
Hierarchy of L<Exception::Class> objects for L<Apache2::Controller>.
All are subclasses of Apache2::Controller::X.
=head1 FIELDS
All Apache2::Controller::X exceptions implement three fields:
=head2 message
Required.
The standard L<Exception::Class> message field. If you call C<throw()>
or the alias C<a2cx()>
with only one argument, a string, then this gets set as the message
field, which is displayed when the object is referred to in string context.
eval { a2cx "booyeah" };
if (my $X = Exception::Class->caught('Apache2::Controller::X')) {
warn "my exception 'message' was '$X'\n";
warn $X->trace;
}
t/unit_exception_object.t view on Meta::CPAN
use blib;
use English '-no_match_vars';
use Log::Log4perl qw(:easy);
use Test::More qw( no_plan );
use Apache2::Controller::X;
eval { Apache2::Controller::X->throw('horta') };
is("$EVAL_ERROR" => 'horta', 'stringify exception throw works');
eval { Apache2::Controller::X->throw('spock') };
my $X = Exception::Class->caught('Apache2::Controller::X');
ok(defined $X, 'X object is defined after class throw');
SKIP: {
skip 'X object not defined', 2 unless defined $X;
isa_ok($X, 'Apache2::Controller::X', 'X isa Apache2::Controller::X');
can_ok($X, qw( trace message dump status status_line ));
};
eval { a2cx 'mccoy' };
$X = Exception::Class->caught('Apache2::Controller::X');
ok(defined $X, 'X object is defined after alias a2cx');