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

I need to create an Apache authorization handler that could change incoming user's parameters to something like "old_parameters&user=$login" because Apache's Basic Authorization's data is not passed to CGI application.
When the request is "GET", task is really easy:

$r->args(new_query_string($r->args()));

But when it comes to "POST" things get worse as the data is held in STDIN:
to get that data I just use

@stdin=<STDIN>;$stdin="@stdin";

so after changing $stdin I need to get it back to standard input, so that CGI could get it.

I do have tried to close STDIN and open the new one, but that new one was different as CGI was seeing not it but the original one already emptied by me.
syswrite gives "Permission denied".
After using fdopen(fileno(STDIN),'w') and trying to print something to STDIN nothing changes in this stream.
open LL,'>&STDIN' same as prevoius.
I've taken a look at "Bidirectional Communication with Yourself" from Perl Cook Book but when a child prints something to a pipe parent's STDIN stays empty.

I'm begging for help or even a tiny hint on how to make this work. I do believe in TIMTOWTDI, so any other ways are welcome.

P.S. All that would have been easier if only I could change the CGI application, but I can't.

Replies are listed 'Best First'.
Re: Altering data in STDIN
by ikegami (Patriarch) on Sep 01, 2008 at 20:00 UTC

    Apache's Basic Authorization's data is not passed to CGI application.

    Isn't it accessible via $r->user()?

Re: Altering data in STDIN
by jethro (Monsignor) on Sep 01, 2008 at 19:45 UTC

    I have no experience with apache handlers, so this might be way off, but in absence of a better suggestion here in this thread: Couldn't you just put the user parameter into r->args() even if it was a POST request ? And then access it in your code. Maybe you could even change the POST request completely into a GET by moving all the parameters from INPUT into $r and hacking the state in $r that says 'POST'

    UPDATE: Found this in the CGI.pm docu which suggests that mixing is possible:

    "It is possible for a script to receive CGI parameters in the URL as well as in the fill-out form by creating a form that POSTs to a URL containing a query string (a "?" mark followed by arguments). The param() method will always return the contents of the POSTed fill-out form, ignoring the URL's query string. To retrieve URL parameters, call the url_param() method. Use it in the same way as param(). The main difference is that it allows you to read the parameters, but not set them."

Re: Altering data in STDIN
by RMGir (Prior) on Sep 01, 2008 at 17:47 UTC
    You can't open a pipe, fork off the CGI app with the pipe as STDIN, and feed it the data yourself?

    "Ungetting" back to STDIN isn't something I know how to do. That doesn't mean it's impossible, but it wouldn't surprise me. Some systems have input streams where you can "unget" a few characters, but the entire contents of the stream might be a bit much to ask...


    Mike
      I have only one misunderstanding:
      if I have forked off CGI app and it gave it's result to the real STDOUT, how can I stop Apache from moving on through the handler's chain and launching this application again?

      return OK; - says to Apache that all is fine and it can move on.
      return AUTH_REQUIRED; - says to stop and return 401 to the user.

      The rest of the returns:
      Apache2::Const::AUTH_REQUIRED Apache2::Const::DECLINED Apache2::Const::DONE Apache2::Const::FORBIDDEN Apache2::Const::NOT_FOUND Apache2::Const::OK Apache2::Const::REDIRECT Apache2::Const::SERVER_ERROR
      just seem useless.
        I was thinking more in terms of replacing x.cgi with an intermediate script, and having the intermediate fork off and call the real x...

        Mike
Re: Altering data in STDIN
by Anonymous Monk on Sep 02, 2008 at 05:46 UTC
      Thank you for reply! I have not noticed that. And it could have been a good way to go if only
      P.S. All that would have been easier if only I could change the CGI application, but I can't.

      And it has a handler on
      $q=new CGI;$q->param('user');

      Still if nothing else is possible, I guess the application should be changed, and that is an other headache and not for me.