Just Uploaded: ModPerl2::Tools

Just Uploaded: ModPerl2::Tools

am 02.03.2010 22:10:54 von torsten.foertsch

Not much, just a few problems solved. Comments are welcome.

NAME
ModPerl2::Tools - a few hopefully useful tools

SYNOPSIS
use ModPerl2::Tools;

ModPerl2::Tools::spawn +{keep_fd=3D>[3,4,7], survive=3D>1}, sub {...};
ModPerl2::Tools::spawn +{keep_fd=3D>[3,4,7], survive=3D>1}, qw/bash -c=
.../;

ModPerl2::Tools::safe_die $status;
$r->safe_die($status);
$f->safe_die($status);

$content=3DModPerl2::Tools::fetch_url $url;
$content=3D$r->fetch_url($url);

INSTALLATION
perl Makefile.PL
make
make test
make install

DESCRIPTION
This module is a collection of functions and methods that I found useful
when working with "mod_perl". I work mostly under Linux. So, I don't
expect all of these functions to work on other operating systems.

Forking off long running processes
Sometimes one needs to spawn off a long running process as the result of
a request. Under modperl this is not as simple as calling "fork" because
that way all open file descriptors would be inherited by the child and,
more subtle, the long running process would be killed when the
administrator shuts down the web server. The former is usually
considered a security issue, the latter a design decision.

There is already $r->spawn_proc_prog that serves a similar purpose as
the "spawn" function. However, "spawn_proc_prog" is not usable for long
running processes because it kills the children after a certain timeout.

Solution
$pid=3DModPerl2::Tools::spawn \%options, $subroutine, @parameters;

or

$pid=3DModPerl2::Tools::spawn \%options, @command_line;

"spawn" expects as the first parameter an options hash reference. The
second parameter may be a code reference or a string.

In case of a code ref no other program is executed but the subroutine is
called instead. The remaining parameters are passed to this function.

Note, the perl environment under modperl differs in certain ways from a
normal perl environment. For example %ENV is not bound to the C-level
"environ". These modifications are not undone by this module. So, it's
generally better to execute another perl interpreter instead of using
the $subroutine feature.

The options parameter accepts these options:

keep_fd =3D> \@fds
here an array of file descriptor numbers (not file handles) is
expected. All other file descriptors except for the listed and file
descriptor 2 (STDERR) are closed before calling $subroutine or
executing @command_line.

survive =3D> $boolean
if passed "false" the created process will be killed when Apache
shuts down. if true it will survive an Apache restart.

The return code on success is the PID of the process. On failure "undef"
or an empty string is returned.

The created process is not related as a child process to the current
apache child.

Serving "ErrorDocument"s
Triggering "ErrorDocument"s from a registry script or even more from an
output filter is not simple. The normal way as a handler is

return Apache2::Const::STATUS;

This does not work for registry scripts. An output filter even if it
returns a status can trigger only a "SERVER_ERROR".

The main interface to enter standard error processing in Apache is
"ap_die()" at C-level. Its Perl interface is hidden in Apache2::HookRun.

There is one case when an error message cannot be sent to the user. This
happens if the HTTP headers are already on the wire. Then it is too
late.

The various flavors of "safe_die()" take this into account.

ModPerl2::Tools::safe_die $status
This function is designed to be called from registry scripts. It
uses Apache2::RequestUtil->request to fetch the current request
object. So,

PerlOption +GlobalRequest

must be enabled.

Usage example:

ModPerl2::Tools::safe_die 401;
exit 0;

$r->safe_die($status)
$f->safe_die($status)
These 2 methods are to be used if a request object or a filter
object are available.

Usage from within a filter:

package My::Filter;
use strict;
use warnings;

use ModPerl2::Tools;
use base 'Apache2::Filter';

sub handler : FilterRequestHandler {
my ($f, $bb)=3D@_;
return $f->safe_die(410);
}

The filter flavor removes the current filter from the request's
output filter chain.

Fetching the content of another document
Sometimes a handler or a filter needs the content of another document in
the web server's realm. Apache provides subrequests for this purpose.

The 2 "fetch_url" variants use a subrequest to fetch the content of
another document. The document can even be fetched via "mod_proxy" from
another server. However, fetching a document directly as with LWP for
example is not (yet) possible.

"ModPerl2::Tools::fetch_url" needs

PerlOption +GlobalRequest

Usage:

$content=3DModPerl2::Tools::fetch_url '/some/where?else=3D42';

$content=3D$r->fetch_url('/some/where?else=3D42');

EXPORTS
None.

SEE ALSO


AUTHOR
Torsten Förtsch,

COPYRIGHT AND LICENSE
Copyright (C) 2010 by Torsten Förtsch

This library is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.


Torsten Förtsch

=2D-=20
Need professional modperl support? Hire me! (http://foertsch.name)

Like fantasy? http://kabatinte.net

Re: Just Uploaded: ModPerl2::Tools

am 02.03.2010 23:55:26 von Fred Moyer

2010/3/2 Torsten Förtsch :
> Not much, just a few problems solved. Comments are welcome.

Looks very cool! I know there are a couple of hooks in APR that
aren't mapped into mod_perl space yet, such as apr_proc_create().
Have you thought about adding those to mod_perl core for a more native
and portable forking solution?

>
> NAME
> =A0 =A0ModPerl2::Tools - a few hopefully useful tools
>
> SYNOPSIS
> =A0 =A0 use ModPerl2::Tools;
>
> =A0 =A0 ModPerl2::Tools::spawn +{keep_fd=3D>[3,4,7], survive=3D>1}, sub {=
....};
> =A0 =A0 ModPerl2::Tools::spawn +{keep_fd=3D>[3,4,7], survive=3D>1}, qw/ba=
sh -c .../;
>
> =A0 =A0 ModPerl2::Tools::safe_die $status;
> =A0 =A0 $r->safe_die($status);
> =A0 =A0 $f->safe_die($status);
>
> =A0 =A0 $content=3DModPerl2::Tools::fetch_url $url;
> =A0 =A0 $content=3D$r->fetch_url($url);
>
> INSTALLATION
> =A0 =A0 perl Makefile.PL
> =A0 =A0 make
> =A0 =A0 make test
> =A0 =A0 make install
>
> DESCRIPTION
> =A0 =A0This module is a collection of functions and methods that I found =
useful
> =A0 =A0when working with "mod_perl". I work mostly under Linux. So, I don=
't
> =A0 =A0expect all of these functions to work on other operating systems.
>
> =A0Forking off long running processes
> =A0 =A0Sometimes one needs to spawn off a long running process as the res=
ult of
> =A0 =A0a request. Under modperl this is not as simple as calling "fork" b=
ecause
> =A0 =A0that way all open file descriptors would be inherited by the child=
and,
> =A0 =A0more subtle, the long running process would be killed when the
> =A0 =A0administrator shuts down the web server. The former is usually
> =A0 =A0considered a security issue, the latter a design decision.
>
> =A0 =A0There is already $r->spawn_proc_prog that serves a similar purpose=
as
> =A0 =A0the "spawn" function. However, "spawn_proc_prog" is not usable for=
long
> =A0 =A0running processes because it kills the children after a certain ti=
meout.
>
> =A0 Solution
> =A0 =A0 $pid=3DModPerl2::Tools::spawn \%options, $subroutine, @parameters=
;
>
> =A0 =A0or
>
> =A0 =A0 $pid=3DModPerl2::Tools::spawn \%options, @command_line;
>
> =A0 =A0"spawn" expects as the first parameter an options hash reference. =
The
> =A0 =A0second parameter may be a code reference or a string.
>
> =A0 =A0In case of a code ref no other program is executed but the subrout=
ine is
> =A0 =A0called instead. The remaining parameters are passed to this functi=
on.
>
> =A0 =A0Note, the perl environment under modperl differs in certain ways f=
rom a
> =A0 =A0normal perl environment. For example %ENV is not bound to the C-le=
vel
> =A0 =A0"environ". These modifications are not undone by this module. So, =
it's
> =A0 =A0generally better to execute another perl interpreter instead of us=
ing
> =A0 =A0the $subroutine feature.
>
> =A0 =A0The options parameter accepts these options:
>
> =A0 =A0keep_fd =3D> \@fds
> =A0 =A0 =A0 =A0here an array of file descriptor numbers (not file handles=
) is
> =A0 =A0 =A0 =A0expected. All other file descriptors except for the listed=
and file
> =A0 =A0 =A0 =A0descriptor 2 (STDERR) are closed before calling $subroutin=
e or
> =A0 =A0 =A0 =A0executing @command_line.
>
> =A0 =A0survive =3D> $boolean
> =A0 =A0 =A0 =A0if passed "false" the created process will be killed when =
Apache
> =A0 =A0 =A0 =A0shuts down. if true it will survive an Apache restart.
>
> =A0 =A0The return code on success is the PID of the process. On failure "=
undef"
> =A0 =A0or an empty string is returned.
>
> =A0 =A0The created process is not related as a child process to the curre=
nt
> =A0 =A0apache child.
>
> =A0Serving "ErrorDocument"s
> =A0 =A0Triggering "ErrorDocument"s from a registry script or even more fr=
om an
> =A0 =A0output filter is not simple. The normal way as a handler is
>
> =A0 =A0 =A0return Apache2::Const::STATUS;
>
> =A0 =A0This does not work for registry scripts. An output filter even if =
it
> =A0 =A0returns a status can trigger only a "SERVER_ERROR".
>
> =A0 =A0The main interface to enter standard error processing in Apache is
> =A0 =A0"ap_die()" at C-level. Its Perl interface is hidden in Apache2::Ho=
okRun.
>
> =A0 =A0There is one case when an error message cannot be sent to the user=
.. This
> =A0 =A0happens if the HTTP headers are already on the wire. Then it is to=
o
> =A0 =A0late.
>
> =A0 =A0The various flavors of "safe_die()" take this into account.
>
> =A0 =A0ModPerl2::Tools::safe_die $status
> =A0 =A0 =A0 =A0This function is designed to be called from registry scrip=
ts. It
> =A0 =A0 =A0 =A0uses Apache2::RequestUtil->request to fetch the current re=
quest
> =A0 =A0 =A0 =A0object. So,
>
> =A0 =A0 =A0 =A0 PerlOption +GlobalRequest
>
> =A0 =A0 =A0 =A0must be enabled.
>
> =A0 =A0 =A0 =A0Usage example:
>
> =A0 =A0 =A0 =A0 ModPerl2::Tools::safe_die 401;
> =A0 =A0 =A0 =A0 exit 0;
>
> =A0 =A0$r->safe_die($status)
> =A0 =A0$f->safe_die($status)
> =A0 =A0 =A0 =A0These 2 methods are to be used if a request object or a fi=
lter
> =A0 =A0 =A0 =A0object are available.
>
> =A0 =A0 =A0 =A0Usage from within a filter:
>
> =A0 =A0 =A0 =A0 package My::Filter;
> =A0 =A0 =A0 =A0 use strict;
> =A0 =A0 =A0 =A0 use warnings;
>
> =A0 =A0 =A0 =A0 use ModPerl2::Tools;
> =A0 =A0 =A0 =A0 use base 'Apache2::Filter';
>
> =A0 =A0 =A0 =A0 sub handler : FilterRequestHandler {
> =A0 =A0 =A0 =A0 =A0 my ($f, $bb)=3D@_;
> =A0 =A0 =A0 =A0 =A0 return $f->safe_die(410);
> =A0 =A0 =A0 =A0 }
>
> =A0 =A0 =A0 =A0The filter flavor removes the current filter from the requ=
est's
> =A0 =A0 =A0 =A0output filter chain.
>
> =A0Fetching the content of another document
> =A0 =A0Sometimes a handler or a filter needs the content of another docum=
ent in
> =A0 =A0the web server's realm. Apache provides subrequests for this purpo=
se.
>
> =A0 =A0The 2 "fetch_url" variants use a subrequest to fetch the content o=
f
> =A0 =A0another document. The document can even be fetched via "mod_proxy"=
from
> =A0 =A0another server. However, fetching a document directly as with LWP =
for
> =A0 =A0example is not (yet) possible.
>
> =A0 =A0"ModPerl2::Tools::fetch_url" needs
>
> =A0 =A0 PerlOption +GlobalRequest
>
> =A0 =A0Usage:
>
> =A0 =A0 $content=3DModPerl2::Tools::fetch_url '/some/where?else=3D42';
>
> =A0 =A0 $content=3D$r->fetch_url('/some/where?else=3D42');
>
> EXPORTS
> =A0 =A0None.
>
> SEE ALSO
> =A0 =A0
>
> AUTHOR
> =A0 =A0Torsten Förtsch,
>
> COPYRIGHT AND LICENSE
> =A0 =A0Copyright (C) 2010 by Torsten Förtsch
>
> =A0 =A0This library is free software; you can redistribute it and/or modi=
fy it
> =A0 =A0under the same terms as Perl itself.
>
>
> Torsten Förtsch
>
> --
> Need professional modperl support? Hire me! (http://foertsch.name)
>
> Like fantasy? http://kabatinte.net
>

Re: Just Uploaded: ModPerl2::Tools

am 03.03.2010 12:23:59 von torsten.foertsch

On Tuesday 02 March 2010 22:10:54 Torsten Förtsch wrote:
> Not much, just a few problems solved. Comments are welcome.
>=20
> NAME
> ModPerl2::Tools - a few hopefully useful tools
>=20
yesterday after uploading, I got a "failed" message from the CPAN indexer:

The following packages (grouped by status) have been found in the distro:

Status: Permission missing
==================== =====3D=
=3D

module: Apache2::Filter
version: 0.01
in file: ModPerl2-Tools-0.01/lib/ModPerl2/Tools.pm
status: Not indexed because permission missing. Current registered
primary maintainer is APML. Hint: you can always find the
legitimate maintainer(s) on PAUSE under "View Permissions".

module: Apache2::RequestRec
version: 0.01
in file: ModPerl2-Tools-0.01/lib/ModPerl2/Tools.pm
status: Not indexed because permission missing. Current registered
primary maintainer is APML. Hint: you can always find the
legitimate maintainer(s) on PAUSE under "View Permissions".

I know what I am doing. How can I get rid of these errors? I seem to rememb=
er=20
there was a trick to get around this by inserting a new line between "packa=
ge"=20
and "Apache2::Filter". Does this still work? Would it be better to do inste=
ad=20
of:

{
package Apache2::Filter;
sub safe_die {}
}

this:

BEGIN {
*Apache2::Filter::safe_die=3Dsub {};
}

or this:

sub Apache2::Filter::safe_die {}

What is best to trick the indexer?

Torsten Förtsch

=2D-=20
Need professional modperl support? Hire me! (http://foertsch.name)

Like fantasy? http://kabatinte.net

Re: Just Uploaded: ModPerl2::Tools

am 03.03.2010 14:26:49 von torsten.foertsch

On Wednesday 03 March 2010 12:23:59 Torsten Förtsch wrote:
> module: Apache2::RequestRec
> version: 0.01
> in file: ModPerl2-Tools-0.01/lib/ModPerl2/Tools.pm
> status: Not indexed because permission missing. Current registered
> primary maintainer is APML. Hint: you can always find the
> legitimate maintainer(s) on PAUSE under "View Permissions".
>=20
> I know what I am doing. How can I get rid of these errors? I seem to
> remember there was a trick to get around this by inserting a new line
> between "package" and "Apache2::Filter".
>=20
That worked. Version 0.02 is indexed without complains.

The new version has got a bit more documentation and

($data, $headers)=3Dfetch_url('http://foertsch.name/');

works via mod_proxy.

Torsten Förtsch

=2D-=20
Need professional modperl support? Hire me! (http://foertsch.name)

Like fantasy? http://kabatinte.net

unsbuscribe

am 03.03.2010 14:36:13 von Roman.Petry

unsubscribe