Mod_include
Ein Design-Ziel unseres Moduls war Zusammenarbeit mit mod_include. Um das zu testen basteln wir uns also flink 2 Test-Seiten, wobei die Basis-Seite die andere perl virtual include einschließt.
<html>
<body>
<!--#include virtual="include.html" -->
</body>
</html>
<a href="/pfad/nach/irgendwo.shtml">.</a>
> curl http://localhost:8080/basis.shtml
<html>
<body>
<a href="/-U2UmjcCoAAQAACmQAiAAAAAA/pfad/nach/irgendwo.shtml">.</a>
</body>
</html>
> curl http://localhost:8080/-TESTSESSION/basis.shtml
<html>
<body>
<a href="/-TESTSESSION/pfad/nach/irgendwo.shtml">.</a>
</body>
</html>
1 $re1=qr,( # $1 start
2 <\s*a(?:rea)?\s+ # <a> oder <area> start
3 .*? # evtl. target=...
4 \bhref\s*=\s* # href=
5 (["']) # " oder ' in $2 bzw. \2
6 (?:https?://\Q$host\E)? # evtl. Host
7 ) # Das alles ist in $1
8 (?:/+\Q$tag\E[^/]+)?
9 ( # $3 start
10 (?!(?:\w+:|\043)).*? # ein beliebiger nicht mit http:
11 # o.ä. beginnender String
12 \2 # das schließende Quote: $2
13 ) # $3 ende
14 ,xi;
Des Rätsels Lösung
PerlModule Apache2::ClickPath
PerlModule Apache2::ReqChain
PerlTransHandler Apache2::ReqChain Apache2::ClickPath
PerlOutputFilterHandler Apache2::ClickPath::OutputFilter
...
# jetzt wird der Datenstrom bearbeitet
while( $f->read(my $buffer, 1024) ) {
warn "Filter (req ".$f->r->pnotes('req#').") >>>\n".
$buffer."\n<<<\n";
# Beim letzten Aufruf koennte ein halbes HTML Tag im Buffer
# uebrig geblieben sein. Das wird hier vor den neuen Datenblock
# gehaengt.
$buffer=$context->{extra}.$buffer if( length $context->{extra} );
...
>>>> 1
r uri: /-TESTSESSION/basis.shtml
<<<< 1
Filter (req 1) >>>
<html>
<body>
<<<
>>>> 2
r uri: /include.html
sub-request von
main uri: /basis.shtml
main initial: 1
main #: 1
<<<< 2
Filter (req 2) >>>
<a href="/pfad/nach/irgendwo.shtml">.</a>
<<<
Filter (req 1) >>>
<a href="/-TESTSESSION/pfad/nach/irgendwo.shtml">.</a>
<<<
Filter (req 1) >>>
</body>
</html>
<<<
Doppeltes Filtern vermeiden
...
unless ($f->ctx) { # Initialisierung
my $r=$f->r; # hier finden wir das Anfrage-Objekt wieder
if( $r->main ) {
$f->remove;
return Apache2::Const::DECLINED;
}
$sess='/'.$tag.$r->subprocess_env('SESSION');
$host=$r->headers_in->{Host};
...
> curl http://localhost:8080/-TESTSESSION/basis.shtml
<html>
<body>
<a href="/-TESTSESSION/pfad/nach/irgendwo.shtml">.</a>
</body>
</html>
>>>> 1
r uri: /-TESTSESSION/basis.shtml
<<<< 1
Filter (req 1) >>>
<html>
<body>
<<<
>>>> 2
r uri: /include.html
sub-request von
main uri: /basis.shtml
main initial: 1
main #: 1
<<<< 2
Filter (req 1) >>>
<a href="/pfad/nach/irgendwo.shtml">.</a>
<<<
Filter (req 1) >>>
</body>
</html>
<<<


