1

How to modify post request content using mod_perl's filter/handler?

I can read request content in PerlResponseHandler but how do I "attach" modified content back into request?

Also, I don't want to do this in PerlResponseHandler as I want requested resource to handle response generation part.

Any help will be appreciated.

Thanks.

keeping_it_simple
  • 439
  • 1
  • 11
  • 31
  • http://stackoverflow.com/questions/3083367/modify-post-request-in-mod-perl2 – daxim Nov 27 '10 at 20:36
  • Thanks Daxim. To access Request script, I'll need to download CPAN's libapreq2-2.12 library. I'll give it a try. – keeping_it_simple Nov 29 '10 at 04:53
  • However I think there must be some way in standard library to read POST data. Thanks. – keeping_it_simple Nov 29 '10 at 04:55
  • I am not able to install libapreq2-2.12 library in mod_perl/perl (I am using indigoampp all in one Apache HTTP Server). If I copy individual pm files at respective locations, it gives following error: – keeping_it_simple Nov 29 '10 at 07:12
  • [Mon Nov 29 12:24:58 2010] [error] APR/Request/Param.pm did not return a true value at d:/indigoampp/perl-5.12.1/site/lib/Apache2/Request.pm line 2.\nBEGIN failed--compilation aborted at d:/indigoampp/perl-5.12.1/site/lib/Apache2/Request.pm line 2.\nCompilation failed in require at d:/indigoampp/perl-5.12.1/site/lib/MyApache2/Test4.pm line 6.\nBEGIN failed--compilation aborted at d:/indigoampp/perl-5.12.1/site/lib/MyApache2/Test4.pm line 6.\nCompilation failed in require at (eval 2) line 2. – keeping_it_simple Nov 29 '10 at 07:12
  • Is there any other way to install it (without manually copying pm files) so I can make use of Request script? Thanks. – keeping_it_simple Nov 29 '10 at 07:12

2 Answers2

1

if you add use Apache2::RequestIO and from my ($r) = @_; you can do a $r->print();

a PerlResponseHandler can not modify request data, but even if it could what would be the point. Only a PerlInputFilterHandler can do that as it filters input before it gets to a response.

The only thing after a response handler is the Output Filters, Log Handler, and the Cleanup Handler.

package MyFilter;

use strict;

use base qw(Apache::Filter);
use Apache2::Const qw(OK);

sub handler: FilterRequestHandler {
  my ($f) = @_;
  while($f->read(my $buf, 1024)) {
    # do something with $buf
    $f->print($buf);
  }
  return OK;
}

1;

Important to know, that you will get data in chunks. When you read you may or may not get the whole posted in a single call.

Rahly
  • 1,462
  • 13
  • 16
  • Thanks Jeremy. However the print() function in RequestIO script is used to send data to the client. I am not clear what it means but how can I read POST data using RequestIO? Also, how can I update it? Thanks! – keeping_it_simple Nov 29 '10 at 04:49
  • The problem is, that a PerlResponseHandler is the end of the line for POST data. – Rahly Nov 30 '10 at 07:57
  • Thanks Jeremy for response. I got that the request can be modifed in PerlInputFilterHandler but can I do that without Apache2::Request module? As I am facing some issues in installing that module. – keeping_it_simple Nov 30 '10 at 08:27
  • What is Apache2::Request? Never used it before. I use Apache2::RequestRec and Apache2::RequestIO. – Rahly Dec 01 '10 at 07:25
  • Apache2::Request is CPAN's module which makes getting post request data real easy. – keeping_it_simple Dec 02 '10 at 06:12
  • That might be your problem then, in a filter you do not have access to the entire post. – Rahly Dec 02 '10 at 07:25
  • Thanks very much Jeremy. The above code works great in PerlInputFilterHandler. – keeping_it_simple Dec 02 '10 at 08:18
0

This code also works -

  package MyApache2::Test7;

  use strict;
  use warnings;

  use base qw(Apache2::Filter);

  use Apache2::Connection ();
  use APR::Brigade ();
  use APR::Bucket ();

  use Apache2::Const -compile => 'OK';
  use APR::Const     -compile => ':common';

use Apache2::Log ();

  sub handler : FilterRequestHandler {

Apache2::ServerRec->log_error("f*** starts");


      my ($f, $bb, $mode, $block, $readbytes) = @_; 
      my $c = $f->c;
      my $bb_ctx = APR::Brigade->new($c->pool, $c->bucket_alloc);
      my $rv = $f->next->get_brigade($bb_ctx, $mode, $block, $readbytes);
      return $rv unless $rv == APR::Const::SUCCESS;

      while (!$bb_ctx->is_empty) {
          my $b = $bb_ctx->first;

          if ($b->is_eos) {
              $bb->insert_tail($b);
              last;
          }

          my $len = $b->read(my $data);

Apache2::ServerRec->log_error($len);

          #$b = APR::Bucket->new($bb->bucket_alloc, lc $data) if $len;

          #$b->remove;
          #$bb->insert_tail($b);

Apache2::ServerRec->log_error($data);

Apache2::ServerRec->log_error("f*** ends");

$bb_ctx->cleanup;

      }

      return Apache2::Const::OK;
  }

  1;
keeping_it_simple
  • 439
  • 1
  • 11
  • 31