rewriterule, location, and perlhandler

rewriterule, location, and perlhandler

am 22.07.2009 03:32:20 von Eric Lease Morgan

How do I get Apache's RewriteRule, Location, and PerlHander to work
nicely together?

I have a the following Hello World mod_perl module:

package Apache2::Alex::SemanticWeb;

use Apache2::Const -compile => qw( OK );
use strict;

sub handler {

my $r = shift;
$r->content_type( 'text/html' );
$r->print( 'hello, world!' );
return Apache2::Const::OK;

}

1;

I then touch a file named semantic-web.cgi.

I then add a Location directive to httpd.conf:


SetHandler perl-script
PerlHandler Apache2::Alex::SemanticWeb


I then use my browser to go to the following URL, and it returns
"hello, world!":

http://infomotions.com/sandbox/semantic-web.cgi

Great and wonderful.

I now want to implement a RewriteRule -- a la a "cool" linked data URL
-- to redirect URLs with a specific shape to SemanticWeb.pm, and I use
the following:

RewriteRule ^/etexts/id/(.*) /sandbox/semantic-web.cgi?id=$1

In other words, all request starting with /etexts/id should be
redirected (rewritten) to go to semantic-web.cgi. Unfortunately, all
requests go directly to the touched file and not to my Perl package;
the Location directive seems by-passed. When I remove semantic-web.cgi
from my file system I get a 404 error (file not found).

What am I doing wrong? Does an actual file need to exist in order for
mod_perl to find it? How should I edit httpd.conf so I can: 1) rewrite
GET requests, and 2) execute the result in a mod_perl module?

--
Eric Lease Morgan
Infomotions, Inc.

Re: rewriterule, location, and perlhandler

am 22.07.2009 03:45:21 von wellnhofer

Eric Lease Morgan wrote:
> What am I doing wrong? Does an actual file need to exist in order for
> mod_perl to find it?

No.

> How should I edit httpd.conf so I can: 1) rewrite
> GET requests, and 2) execute the result in a mod_perl module?

Try the mod_rewrite "passthrough" (PT) flag:

RewriteRule ^/etexts/id/(.*) /sandbox/semantic-web.cgi?id=$1 [PT]

More info here:
http://modperlbook.org/html/12-8-mod_rewrite-Examples.html

Nick

Re: rewriterule, location, and perlhandler [resolved]

am 22.07.2009 03:50:04 von Eric Lease Morgan

On Jul 21, 2009, at 9:32 PM, Eric Lease Morgan wrote:

> How do I get Apache's RewriteRule, Location, and PerlHander to work
> nicely together?...
>
> I now want to implement a RewriteRule -- a la a "cool" linked data
> URL -- to redirect URLs with a specific shape to SemanticWeb.pm, and
> I use the following:
>
> RewriteRule ^/etexts/id/(.*) /sandbox/semantic-web.cgi?id=$1
>
> In other words, all request starting with /etexts/id should be
> redirected (rewritten) to go to semantic-web.cgi. Unfortunately, all
> requests go directly to the touched file and not to my Perl package;
> the Location directive seems by-passed....


Resolved. Alas, I needed to add [passthrough] to my RewriteRule
configuration:

RewriteRule ^/etexts/id/(.*) /sandbox/semantic-web.cgi?id=$1
[passthrough]

From the mod_rewrite documentation:

* 'passthrough|PT' (pass through to next handler)

This flag forces the rewrite engine to set the uri field of the
internal request_rec structure to the value of the filename
field. This flag is just a hack to enable post-processing of the
output of RewriteRule directives, using Alias, ScriptAlias,
Redirect, and other directives from various URI-to-filename
translators. For example, to rewrite /abc to /def using
mod_rewrite, and then /def to /ghi using mod_alias:

RewriteRule ^/abc(.*) /def$1 [PT]
Alias /def /ghi

If you omit the PT flag, mod_rewrite will rewrite uri=/abc/... to
filename=/def/... as a full API-compliant URI-to-filename
translator should do. Then mod_alias will try to do a
URI-to-filename transition, which will fail. Note: You must use
this flag if you want to mix directives from different modules
which allow URL-to-filename translators. The typical example is
the use of mod_alias and mod_rewrite.

http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html


I sincerely apologize for wasting people's time and bandwidth.

--
Eric Lease Morgan

Re: rewriterule, location, and perlhandler

am 22.07.2009 03:53:43 von Eric Lease Morgan

On Jul 21, 2009, at 9:45 PM, Nick Wellnhofer wrote:

>> What am I doing wrong? Does an actual file need to exist in order for
>> mod_perl to find it?
>
> No.


I didn't think so, but what sort of configuration do I need to do so
my mod_perl packages get executed without the existence of a file?

--
Eric Morgan

Re: rewriterule, location, and perlhandler

am 22.07.2009 06:05:51 von Adam Prime

Eric Lease Morgan wrote:
>
> On Jul 21, 2009, at 9:45 PM, Nick Wellnhofer wrote:
>
>>> What am I doing wrong? Does an actual file need to exist in order for
>>> mod_perl to find it?
>>
>> No.
>
>
> I didn't think so, but what sort of configuration do I need to do so my
> mod_perl packages get executed without the existence of a file?
>

You need to use Handlers. See this link for a really simple example of
a ResponseHandler, and how to configure it.

http://perl.apache.org/docs/2.0/user/intro/start_fast.html#H andler_Modules

Adam

Re: rewriterule, location, and perlhandler

am 22.07.2009 15:38:57 von Eric Lease Morgan

On Jul 22, 2009, at 12:05 AM, Adam Prime wrote:

>>>>
>>>> SetHandler perl-script
>>>> PerlHandler Apache2::Alex::SemanticWeb
>>>>

>>>>
>>>> What am I doing wrong? Does an actual file need to exist in order
>>>> for
>>>> mod_perl to find it?
>>>
>>> No.
>>
>> I didn't think so, but what sort of configuration do I need to do
>> so my
>> mod_perl packages get executed without the existence of a file?
>
> You need to use Handlers. See this link for a really simple example
> of
> a ResponseHandler, and how to configure it.
>
> http://perl.apache.org/docs/2.0/user/intro/start_fast.html#H andler_Modules


By first changing my Location directive to the following:


SetHandler perl-script
PerlHandler Apache2::Alex::SemanticWeb


And then changing my RewriteRule to this:

RewriteRule ^/etexts/id/(.*) /sandbox/semantic-web/?id=$1
[passthrough]

I eliminate the need to have a file on my file system.

Thank you. oss++ * mailing_lists++

--
Eric Lease Morgan

Re: rewriterule, location, and perlhandler

am 22.07.2009 15:59:23 von Adam Prime

Eric Lease Morgan wrote:
>
> On Jul 22, 2009, at 12:05 AM, Adam Prime wrote:
>
> By first changing my Location directive to the following:
>
>
> SetHandler perl-script
> PerlHandler Apache2::Alex::SemanticWeb
>

>
> And then changing my RewriteRule to this:
>
> RewriteRule ^/etexts/id/(.*) /sandbox/semantic-web/?id=$1 [passthrough]
>
> I eliminate the need to have a file on my file system.
>
> Thank you. oss++ * mailing_lists++
>

If you want, it's actually possible to take this even further and remove
rewrite completely.


SetHandler perl-script
PerlHandler Apache2::Alex::SemanticWeb


Then alter your handler's code to parse $r->uri and extract everything
after $r->location. (or you can use $r->path_info, if the /etexts/id/
actually exists in your document root). That'll give you the same thing
that rewrite is currently stuffing into your id argument.

Adam

Re: rewriterule, location, and perlhandler

am 22.07.2009 16:27:54 von torsten.foertsch

On Wed 22 Jul 2009, Adam Prime wrote:
> Eric Lease Morgan wrote:
> > On Jul 22, 2009, at 12:05 AM, Adam Prime wrote:
> >
> > By first changing my Location directive to the following:
> >
> >
> > SetHandler perl-script
> > PerlHandler Apache2::Alex::SemanticWeb
> >

> >
> > And then changing my RewriteRule to this:
> >
> > RewriteRule ^/etexts/id/(.*) /sandbox/semantic-web/?id=$1
> > [passthrough]
> >
> > I eliminate the need to have a file on my file system.
> >
> > Thank you. oss++ * mailing_lists++
>
> If you want, it's actually possible to take this even further and
> remove rewrite completely.
>
>
> SetHandler perl-script
> PerlHandler Apache2::Alex::SemanticWeb
>

>
> Then alter your handler's code to parse $r->uri and extract
> everything after $r->location. (or you can use $r->path_info, if the
> /etexts/id/ actually exists in your document root). That'll give you
> the same thing that rewrite is currently stuffing into your id
> argument.

Never use path_info unless you are very sure it is what you want.
Path_info is made for CGI scripts where $r->filename points to the file
containing the script.

The usage of path_info leads to action at a distance problems. Assume
you have an empty directory DOCROOT/etexts/id and path_info s what you
want. Later an administrator adds a file or subdirectory to that
directory or removes the id directory. Suddenly path_info has changed
but the handler and all libraries it uses are still the same.

substr($r->uri, length $r->location) is almost always what you need.

Torsten

--
Need professional mod_perl support?
Just hire me: torsten.foertsch@gmx.net

Re: rewriterule, location, and perlhandler

am 22.07.2009 16:39:55 von Eric Lease Morgan

On Jul 22, 2009, at 10:27 AM, Torsten Foertsch wrote:

>> If you want, it's actually possible to take this even further and
>> remove rewrite completely.
>>
>>
>> SetHandler perl-script
>> PerlHandler Apache2::Alex::SemanticWeb
>>

>>
>> Then alter your handler's code to parse $r->uri and extract
>> everything after $r->location. (or you can use $r->path_info, if the
>> /etexts/id/ actually exists in your document root). That'll give you
>> the same thing that rewrite is currently stuffing into your id
>> argument.
>
> Never use path_info unless you are very sure it is what you want.
> Path_info is made for CGI scripts where $r->filename points to the
> file
> containing the script....
>
> substr($r->uri, length $r->location) is almost always what you need.


These two things represent a very elegant solution that I have already
implemented. Cool. Thanks!

--
Eric Lease Morgan