Forum Moderators: phranque

Message Too Old, No Replies

RewriteMap <perl> script

no errors not working

         

BlueBlizz

9:59 am on Sep 14, 2009 (gmt 0)

10+ Year Member



I want to have a perl script working in httpd.conf of htaccess , but non of them works.

in httpd.conf:
RewriteMap testje prg:/home/epages5/eproot/Apache/conf/testje.pl
RewriteCond %{REQUEST_URI} /TEST
RewriteRule ^(.*)$ ${testje:$1} [R=301,L]

The file is present and fully accessable (777), containing:

#!/perl
$¦ = 1;
while (<STDIN>) {
# ...put here any transformations or lookups...

print "/A10024/;
}

the perl program:
# which perl
/home/epages5/eproot/Perl/bin/perl

Thus when the url is: http://www.example.com/TEST it should redirect to http://www.example.com/A10024/

in the log files:
83.87.74.162 - - [14/Sep/2009:10:38:50 +0200] [www.xx.com/sid#80a1f48][rid#8198f68/initial] (2) init rewrite engine with requested uri /TEST
83.87.74.162 - - [14/Sep/2009:10:38:50 +0200] [www.xx.com/sid#80a1f48][rid#8198f68/initial] (2) rewrite '/TEST' -> ''

If I replace RewriteRule into :
RewriteRule ^ [google.com...] it works

[edited by: jdMorgan at 2:44 pm (utc) on Sep. 14, 2009]
[edit reason] example.com [/edit]

jdMorgan

3:01 pm on Sep 14, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



That RewriteLog appears incomplete. Consider increasing the log level (!temporarily!)

A few things to look at (in addition to rewritelog, error log, and trace log):

Problems:
1) No RewriteLock file defined.
2) Missing line-ender ("\n") on PERL print string.
3) Missing end-quote on PERL print string.

Rule optimization:


RewriteRule ^(/TEST.*)$ http://www.example.com{testje:$1} [R=301,L]

No RewriteCond is required, since RewriteRule can verify that the "/TEST" path is being requested.

Jim

BlueBlizz

8:32 am on Sep 15, 2009 (gmt 0)

10+ Year Member



and the answer is 2.

new problems.
We use a software package called ePages to build the website.
The use another perl.
Normaly I can run a perl program from linux command prompt.
The program uses epages API's.
like:

#!/home/epages5/eproot/Perl/bin/perl
use DE_EPAGES::Object::API::Factory qw(LoadObject ExistsObjectByPath);

my $post = $ARGV[0];
if(index($post, 'T11256') != -1) { $post = 'A11256'; }
elsif(index($post, 'T11257') != -1) { $post = 'A11257'; }

print "/$post\n";

}

This runnes fine from command prompt.

For apache I've got to make some changings:
#!/home/epages5/eproot/Perl/bin/perl
$¦=1;
use DE_EPAGES::Object::API::Factory qw(LoadObject ExistsObjectByPath);

while (my $post = <STDIN>) {

if(index($post, 'T11256') != -1) { $post = 'A11256'; }
elsif(index($post, 'T11257') != -1) { $post = 'A11257'; }

print "/$post\n";

}

without including the API it works a planed.
including the API is will not.
error HTTP-400.
"Your browser sent a request that this server could not understand.
Apache/2.2.3 (Unix) mod_ssl/2.2.3 OpenSSL/0.9.7j Server at www.#*$!.com Port 80"

I assume that the API inclusing is wrong. Perhaps the path is not found when running inside apache?

jdMorgan

4:12 pm on Sep 15, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



It might be useful to examine the output from the RewriteMap when trying to use the E_pages API script. An easy way to do this is to change your RewriteRule (for testing only) to put the map result into the URL in your address bar. Also, use a RewriteCond to prevent a redirection loop in this test code:

RewriteCond $1 !^/TEST/testing-only\.html$
RewriteRule ^(/TEST.*)$ http://www.example.com/TEST/testing-only.html?testje-map_ouput={testje:$1} [R=301,L]

This will redirect /TEST requests to /TEST/testing-only.html with the testje map output shown as a query string, so you can see it.

Be very careful that your E_pages API code does not output anything to STDOUT -- If it does, it will be trying to do Apache-content-handler-API-phase output while the server is still in the URL-to-filename translation phase. Your E_pages API code must pass information using only script and/or server variables, and must not use STDOUT.

Always keep in mind that there will be one and only one instance of your RewriteMap script, which will be started when the server is restarted, and must run forever. For this reason, this script must also never be allowed to 'die' under any circumstances -- It must always return a URL or a NULL, no matter what may happen.

Simlarly, the E_pages API must not be allowed to output to STDOUT if it 'dies' when being called from your RewriteMap script.

Also, any read/write resources (e.g. files) used by these scripts must be 'locked' so that only one instance of any script can use them at one time. Since these instances will be invoked asynchronously by incoming HTTP requests, then can occur at any time. So where strict sequential execution is required to ensure data integrity, set up all of the variables ahead of time, lock the file, do the read-modify-write, and immediately unlock the file. The time that the shared resource remains locked must be kept to an absolute minimum, and again, the script cannot be allowed to 'die.'

If the E_pages API script is complex and you cannot control it or modify it to suit execution in the URL-to-filename translation phase as described above, then perhaps you should consider 'extracting' only the exact function(s) you need from that script, and including them directly in your RewriteMap script.

Basically, you need to keep the RewriteMap-invoked script(s) very, very simple and absolutely fail-safe. If you have more than 50 lines of code total being invoked by RewriteMap, then that's too many, and you should consider using a different approach.

Jim