Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

So, this seems like it should be simple, but apparently I am moreso as I cannot figure it out.

I want to read the GET URI or the POST body of a request coming into a server AS IS (no multipart for now). I'm doing a header-based, signature validation of the requests so I need it to be char-for-char what the client has POSTed.

Ideally I'd like to have my CGI turn the request it gets into an HTTP::Request since that is what the client is using to form requests via POE::Component::Client::HTTP. Then I'd do the signature verification against $request->uri . $request->content. I've played around with straight CGI.pm and without it, trying to read the incoming stuff via STDIN and GET URI checks are fine but I can't get the POST stuff to even pretend to work.

Thank you!

Replies are listed 'Best First'.
Re: Read a raw POST request, as is
by pileofrogs (Priest) on Oct 16, 2007 at 18:07 UTC

    I think we're going to need to see your code to know what your problem is.

    You might want to write a simplified script with just enough code to reproduce the error. That will make it easier for us and making that script often leads to a solution in itself.

    Are you saying you get absolutely nothing on STDIN when processing the POST request? Or are you saying you can't verify the sig? Is this header-based signature validation a standard thing or is it something you're making from scratch? If it's standard, I'd be surprised if there isn't a CPAN module...

      Whoops. I was being simple-minded. I did not name my "input" field in my test script so the value was being omitted. Reading from STDIN works fine once the fields are named. Doi.

      Thanks! I need a Teddy bear at this desk.

Re: Read a raw POST request, as is
by Anonymous Monk on Oct 16, 2007 at 19:16 UTC

    Actually, this is the time to ask for best (better?) practices. I have some test code, below, that does what I want (under limited/broken circumstances; not mod_perl, etc). Reconstitutes an HTTP::Request. Anyone want to look at the functionality and tell me how I should really be doing it and with which modules?

    use strict; use HTTP::Request; use IO::Handle; use HTML::Entities; print "Content-type: text/html\n\n"; print <<""; <form method="post" action="/http-request.pl" enctype="multipart/form-data"> <input name="form_field" /> <input type="submit" name="Submit!" /> </form><hr /> print "<pre>"; my $request = HTTP::Request->parse( request_line() . "\n" . headers() . "\n\n" . request_body() ); print encode_entities($request->as_string()); print "</pre>"; sub request_line { return sprintf("%s %s %s", $ENV{REQUEST_METHOD}, $ENV{REQUEST_URI}, $ENV{SERVER_PROTOCOL} ); } sub headers { my @header_pair; for my $key ( grep /^HTTP_/, keys %ENV ) { my $field = lc($key); $field =~ s/^http_//; $field =~ tr/_/-/; $field =~ s/\b(\w)/\U\1/g; push @header_pair, join(": ", $field, $ENV{$key}); } return join "\n", @header_pair; } sub request_body { my $body = ""; my $io = IO::Handle->new(); if ($io->fdopen(fileno(STDIN),"r")) { while ( my $line = $io->getline ) { $body .= $line; } $io->close; } return $body; }