[QUESTION mp2]creating own handler for mod_perl

[QUESTION mp2]creating own handler for mod_perl

am 03.10.2011 20:43:07 von Carla von Reitzenstein

Hi,

for my diploma thesis I need to implement some of the WebDAV requests
into my apache, to make a TWiki installation (an open-source wiki)
WebDAV compatible.
I know that there is a WebDAV module for the apache but when looking
at the needed connection between the Apache and TWiki, writing a
custom module/handler for mod_perl (a bit like the CPAN module
Apache::WebDAV) than to change the mod_dav code seems to be easier
(and better to maintain).

I am quite experienced programming with perl but I have never done
anything with mod_perl before. After reading in your documentation and
testing some example handlers I still don't really know how to start
and there are also some open questions:

=A0- I do not understand the link between API and APR functions/methods
(I am working on a Debian Server and really don't care for Windows)

=A0- in Apache::RequestIO there is the read function but it says that's
for reading from client side. Does that mean reading an input stream
given by the client?

=A0- when can I use normal perl code and when do I have to use one of
the provided functions/methods? Is it normal perl code for everything
happening on the server (like reading from a file on the server) and
mod_perl functions for everything that happens between server and
client?

Would it be useful to get the mod_perl2 book from Stas Bekman (or
other books), or does it handle more of the general "install and setup
mod_perl" - themes than writing own handlers?

Thanks a lot for help and tips!
Carla

Re: [QUESTION mp2]creating own handler for mod_perl

am 03.10.2011 22:54:04 von aw

Carla von Reitzenstein wrote:
> Hi,
>
> for my diploma thesis I need to implement some of the WebDAV requests
> into my apache, to make a TWiki installation (an open-source wiki)
> WebDAV compatible.
> I know that there is a WebDAV module for the apache but when looking
> at the needed connection between the Apache and TWiki, writing a
> custom module/handler for mod_perl (a bit like the CPAN module
> Apache::WebDAV) than to change the mod_dav code seems to be easier
> (and better to maintain).

There is a 3rd option : use the Apache mod_dav module as it is, but "wrap" it with
mod_perl handlers. See below.

>
> I am quite experienced programming with perl but I have never done
> anything with mod_perl before.

If you like perl and like Apache httpd, then you will love mod_perl.

After reading in your documentation and
> testing some example handlers I still don't really know how to start
> and there are also some open questions:
>
> - I do not understand the link between API and APR functions/methods
> (I am working on a Debian Server and really don't care for Windows)

Can you clarify that question ? (an example, maybe)
To me
- the mod_perl API is the ensemble of all the mod_perl functions that you can call, and
their interface
- APR is the Apache Portable Runtime. That is a special part of Apache httpd, which offers
some basic functions to access the Apache core.
Some of the mod_perl functions interact with the APR, some with other parts of Apache.
That's the link I can see.

>
> - in Apache::RequestIO there is the read function but it says that's
> for reading from client side. Does that mean reading an input stream
> given by the client?

Yes. For example, if the client is sending a HTTP request containing a body, you could
read this body using that read() call. But this is unusual. Usually, you will use other
functions, which will read this for you and parse it, and deliver it to your mod_perl
module already pre-digested.
(But you would probably need this, if you wanted to write your own PUT handler).

>
> - when can I use normal perl code and when do I have to use one of
> the provided functions/methods? Is it normal perl code for everything
> happening on the server (like reading from a file on the server) and
> mod_perl functions for everything that happens between server and
> client?

It is all normal perl code, see below.

>
> Would it be useful to get the mod_perl2 book from Stas Bekman (or
> other books), or does it handle more of the general "install and setup
> mod_perl" - themes than writing own handlers?
>

It would probably be useful, and please Stas, if you bought the book (which is always one
way to support an author who volunteers his time to donate code).
The on-line documentation for mod_perl is also quite good, once you get the basic "feel"
for mod_perl.

Let me try to give you an overall starter, which is maybe missing in the on-line mod_perl
documentation.

About Apache httpd :

Apache httpd is a beautiful piece of software, composed of many parts (core and optional),
and together all these parts constitute the best and most powerful and most flexible and
most used webserver on the whole WWW.

Apache httpd is designed to receive HTTP requests, process them, and respond to them.
A very important aspect of this work, is that it happens in a series of consecutive
"steps", which take place for every HTTP request in more or less the same sequence.
In text, there is some information about this here :
http://httpd.apache.org/docs/2.2/developer/request.html
A more graphic example exists here : http://www.apachetutor.org/dev/request
And this one is even clearer :
http://www.modsecurity.org/documentation/modsecurity-apache/ 2.1.0/html-multipage/04-processing-phases.html
(just forget the mod_security part for now).
Another useful diagram appears on chapter 3, page 378 of the MOD_PERL DEVELOPER’S
COOKBOOK, which happens to be available (in part) on line at : http://www.modperlcookbook.org/
(this one already integrates mod_perl handlers and where they fit)

As you can see, a HTTP request goes through a whole series of consecutive and distinct
steps inside of Apache httpd, before the response is being created and sent back to the
browser.

About mod_perl :

The beauty of mod_perl, is that

1) it embeds a perl interpreter inside of Apache itself. So now you have an Apache which
"speaks perl", and you can now thus ask Apache to run perl scripts and modules very fast.

But that's not the best part. The best part is

2) that you can now "insert" pieces of Perl code almost anywhere within Apache, and have
Apache run them as an integral piece of the Apache webserver.

If you refer to one of the diagrams above, it means that at any "step" of the processing
of a HTTP request by Apache, you can insert your own perl code, and you can modify what
Apache does to the request at that point, or even substitute your own perl code to be run
instead of the standard Apache code for that phase.

For example, you can write your own Apache authentication module, and then you can plug it
into Apache, and Apache will call /your/ authentication module instead of (or in addition
to) the standard Apache ones. And it is your module which will at the end tell Apache if
this user has a valid user-id or not, or if Apache should return a "403 Forbidden"
response to the browser.

Or you can write your own "URI translation" module, which will intercept certain HTTP
requests, and direct them somewhere else than Apache would have normally done.

Now in order to do that, you have to write these perl modules according to certain rules,
so that Apache can call them and pass to them information about the current HTTP request
being processed. Conversely, your modules, when they are done processing the request,
have to return information to Apache in a certain form, so that Apache can take into
account what they have done before continuing with the processing of the request.

And that is what the mod_perl documentation explains how to do (and it gives you examples
too).

The code inside such "mod_perl handlers" (that is the name used for these additional
pieces of code) is normal perl. But this code is running inside of an Apache webserver,
and usually it is put there to handle some aspect of the processing of a HTTP request.
That is why it may look a bit different than a usual stand-alone perl script.

For example, most mod_perl handlers, when they are called by Apache, receive access to the
"Apache request object" (the table in memory which represents the current request), as the
first argument. That's why they usually start with :

sub handler {
my $r = shift; # $r is now a reference to the Apache "request object"

Then the handler can "play around" with that request (inspect it, modify it, do something
else on the side with the information contained in the request). Then when the handler has
finished playing around, it returns some standard value to Apache, to let Apache know what
to do next.

It is not evident at first, but once you get the hang of it, you will be amazed at the
things that you can do with Apache and mod_perl.
(That is also because mod_perl is very tightly "coupled" to Apache, and allows your
mod_perl modules to intervene very deeply into the core functionality of Apache.)

Another secondary aspect is that by learning how to do things with mod_perl, you will
automatically become an expert at understanding how Apache works, inside (and also how all
webservers work in general).


So now, to get back to your original doubts about how to go about this :

You will have to provide a bit more details about what exactly you want to do, but I
mentioned a "3rd way" above, between

a) modifying Apache's DAV module directly (delicate, dangerous, because it is a complex
module)(and you'd have to do that in C)

b) starting from the existing Apache::WebDAV and modify it

You could instead see if you cannot just install and configure the Apache mod_dav module
normally, but insert your own mod_perl handlers before mod_dav and after mod_dav, to
modify what mod_dav does, in the way that you need.

For example (and I am wildy guessing here), suppose that you want most of the
functionalities of mod_dav, but
- you do not want the user to actually be able to see where the files are being written
when they are uploaded to the server
- and, when the upload (via DAV) is finished, you want Apache to immediately run something
that will take the file just uploaded, do something with it, and write something in some
kind of database

well then, you could do this with mod_perl handlers, without having to modify the mod_dav
code at all. You would just arrange to insert a mod_perl handler to be called just before
mod_dav is called, and another one to run just when mod_dav is done.
And those handlers could do just what is necessary to make Apache and Twiki happy, without
interfering with mod_dav, whose function is to allow users to safely and reliably
upload/download files to/from a webserver through HTTP.

Re: [QUESTION mp2]creating own handler for mod_perl

am 04.10.2011 12:53:11 von Carla von Reitzenstein

--0015174c430cc6fab404ae76e514
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

Andr=E9, thanks a lot for that great and detailed answer!
It's like everyone says the support from this mailing list is perfect.


>> - I do not understand the link between API and APR functions/methods
>> (I am working on a Debian Server and really don't care for Windows)
>
> Can you clarify that question ? (an example, maybe)
> To me
> - the mod_perl API is the ensemble of all the mod_perl functions that you
> can call, and their interface
> - APR is the Apache Portable Runtime. That is a special part of Apache
> httpd, which offers some basic functions to access the Apache core.
> Some of the mod_perl functions interact with the APR, some with other
parts
> of Apache.
> That's the link I can see.

This answered my question, it was just some general understanding issue
about the APR, but now I think I get the idea behind it.

> There is a 3rd option : use the Apache mod_dav module as it is, but "wrap=
"
> it with mod_perl handlers. (...)

> So now, to get back to your original doubts about how to go about this :
>
> You will have to provide a bit more details about what exactly you want t=
o
do


My goal is to extend the TWiki software (written in perl) with some WebDAV
functionality, to make the attachments in the TWiki "directly editable".
I will only need GET, LOCK, PROPFIND and PUT. Other requests like COPY or
DELETE shouldn't be enabled for the TWiki files.
When someone tries to open an attachment as WebDAV file from an office tool
I need to run the TWiki function that checks if the user has the rights to
edit the attachment - for every page in the TWiki one can restrict view and
edit access to certain users/groups.
After uploading files (via DAV) I also need to run some functions from the
TWiki, to run the version management, check if the file name needs to be
protected and so on.

So I think for that, your idea about wrapping mod_dav with some mod_perl
handlers sound really interesting and could be the best way to combine
existing functionality with the TWiki without changing someone else=92s cod=
e
and with the support for mod_dav.


I will need some more time to go to all the links and ideas you gave me, bu=
t
by now I'm not feeling that confused about mod_perl any more and you helped
my see the problem and a possible solution in a much clearer way.

Thanks again for the help,
Carla

--0015174c430cc6fab404ae76e514
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

Andr=E9, thanks a lot for that great and detailed answer!
It's like =
everyone says the support from this mailing list is perfect.


>=
;> =A0- I do not understand the link between API and APR functions/metho=
ds

>> (I am working on a Debian Server and really don't care for Win=
dows)
>
> Can you clarify that question ? (an example, maybe) r>> To me
> - the mod_perl API is the ensemble of all the mod_perl=
functions that you

> can call, and their interface
> - APR is the Apache Portable Run=
time. That is a special part of Apache
> httpd, which offers some bas=
ic functions to access the Apache core.
> Some of the mod_perl functi=
ons interact with the APR, some with other parts

> of Apache.
> That's the link I can see.

This answered=
my question, it was just some general understanding issue about the APR, b=
ut now I think I get the idea behind it.

> There is a 3rd option =
: use the Apache mod_dav module as it is, but "wrap"

> it with mod_perl handlers.=A0 (...)

> So now, to get back to=
your original doubts about how to go about this :
>
> You will=
have to provide a bit more details about what exactly you want to do



My goal is to extend the TWiki software (written in perl) with some=
WebDAV functionality, to make the attachments in the TWiki "directly =
editable".
I will only need GET, LOCK, PROPFIND and PUT. Other req=
uests like COPY or DELETE shouldn't be enabled for the TWiki files. >
When someone tries to open an attachment as WebDAV file from an office tool=
I need to run the TWiki function that checks if the user has the rights to=
edit the attachment - for every page in the TWiki one can restrict view an=
d edit access to certain users/groups.

After uploading files (via DAV) I also need to run some functions from the =
TWiki, to run the version management, check if the file name needs to be pr=
otected and so on.

So I think for that, your idea about wrapping mod=
_dav with some mod_perl handlers sound really interesting and could be the =
best way to combine existing functionality with the TWiki without changing =
someone else=92s code and with the support for mod_dav.




I will need some more time to go to all the links and ideas you gav=
e me, but by now I'm not feeling that confused about mod_perl any more =
and you helped my see the problem and a possible solution in a much clearer=
way.


Thanks again for the help,
Carla



--0015174c430cc6fab404ae76e514--