Hi all,

the questions that I have, as you can see from the title, are related to mod_perl2 and the Perl API for Apache2 filters. I am trying to install a connection filter which blocks flooding attempts by allowing only one initial request per second and blocking all others (which are not subrequests) from the same IP. Obviously, I first thought, this should be accomplished by a PerlPreConnectionHandler. Its code is:

package Foo::FloodBlocker; use strict; use warnings; use Apache2::Connection; use Apache2::Const -compile => qw/FORBIDDEN OK/; use IPC::Shareable ':all'; use constant { FILTERGLUE => 'PIFt', FILTERSHMEM => 1048576 }; sub handler { my $c = shift; return Apache2::Const::OK if $c->keepalives; my $ip = $c->remote_ip; my $time = time; no warnings 'untie'; my ($shmem, %hash); $shmem = tie %hash, 'IPC::Shareable', FILTERGLUE, { create => 0, mode => 0666, size => FILTERSHMEM, exclusive => 0, destroy => 0 }; $ip =~ s/\./_/g; my $block; $shmem->shlock(LOCK_EX); if (exists $hash{$ip}) { if ($hash{$ip} < $time) { delete $hash{$ip}; } else { $block = 1; } } else { $hash{$ip} = $time; } $shmem->shunlock; untie %hash; undef $shmem; return Apache2::Const::FORBIDDEN if $block; Apache2::Const::OK; }
Rather simple, quick and clean. ;)
The funny thing, from which all my troubles arise, lies in $c->keepalives. Because when I try a request after having cleaned the browser cache, I get the HTML-document, maybe one or the other image, and accidentally a javascript document or a CSS-file.

So my first question is: does anyone know, whether Apache2 opens new connections for dealing with subrequests? And if it does so, how can I distinguish them from the initial request?

My first attempt to overcome these problems failed as well: I configured the package to serve as PerlProcessConnectionHandler, which then has the advantage of already defined filters. The code I inserted is as follows:

use APR::Const -compile => qw/SUCCESS/; use APR::Brigade; use APR::Bucket; use APR::Status; use APR::Error; [...] sub handler { [...] my $bb_in = APR::Brigade->new($c->pool, $c->bucket_alloc); my $bb_out = APR::Brigade->new($c->pool, $c->bucket_alloc); while (1) { my $rc = $c->input_filters->get_brigade($bb_in, Apache2::Const::MODE_GETLINE); last if APR::Status::is_EOF($rc); die APR::Error::strerror($rc) unless $rc == APR::Const::SUCCESS; my $last = 0; while (!$bb_in->is_empty) { my $b = $bb_in->first; $b->remove; if ($b->is_eos) { $bb_out->insert_tail($b); $last++; last; } if ($b->read(my $data)) { warn $data; # testing line } $bb_out->insert_tail($b); } if ($last) { $bb_out->insert_tail(APR::Bucket::flush_create($c->bucket_all +oc)); $c->output_filters->pass_brigade($bb_out); last; } } [...]
In fact this is a copy from the tutorial on protocol handlers, which is either buggy, or I misunderstood it. Because the condition if ($b->is_eos) is never fulfilled, and the handler hangs. The loop will only be left after the client has closed the connection.

The idea behind this bucket-sniffing attempt is, that I want to know whether there is a referrer to the request and what it looks like. Since at this stage of the request process the RequestRec object doesn't exist, this seems to be the only method.

Has anybody got a clue? What am I doing wrong?
Thx in advance
TOD (aka DEATH, for en Pratchett fans ;)

Edit: g0n - readmore tags


In reply to Apache2 Perl(Pre|Process)ConnectionHandler by TOD

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.