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

Here is my problem:

I have a CGI script that generates data. From this script, I want to call a second script, and pass it the data. That second script uses CGI.pm to access the posted data.

This works well, using LWP::UserAgent, building a request that includes a file and getting back the result:

sub upload { my( $data)= @_; my $ua = LWP::UserAgent->new; my $req= POST $SCRIPT_URL, Content_Type => 'form-data', Content => [ status => 'ok', uploaded_file => [ undef, # conte +nt provided below $basename, Content_Type = +> 'text/html', Content = +> $data ], ], ; # this might be wrong, the real code uses a callback to output the + results # as they come back from $SCRIPT my $result= $ua->request($req)->content; }

Now my problem is that both scripts are in protected areas, and are used by users whose passwords I do not know. So even if the above code works well on my test machine, I can't actually use it on the live server, because I cannot pass the credentials to the second script. And I cannot modify that script to bypass the authentication process.

The solution I have found, as both scripts are on the same machine, is to call directly the script, without going through the server. So I thought I would just set $ENV{REMOTE_USER}, build the same HTTP::Request as previously and pass the request content to the script. But none of this seems to work. The second script does not pick up the parameters, and the REMOTE_USER is not set.

Here is the code I have so far:

sub exe_script { my( $data)= @_; my $req= POST $SCRIPT, Content_Type => 'form-data', Content => [ status => 'ok', uploaded_file => [ undef, # cont +ent provided below 'whatever', Content_Type +=> 'text/html', Content +=> $data, ], ], ; open( my $script, "| $SCRIPT") or exit_status( Error => "cannot ca +ll script: $!"); my $user= remote_user(); $ENV{REMOTE_USER}= $user; my $content= $req->content; print {$script} $content; exit; }

Am I missing something obvious? Should I forget about HTTP::Request in this case, just RTFR (Read The Fine RFC) and build the request myself? And how can I get the REMOTE_USER variable set in $SCRIPT? Save the query in a file, set the environment variable and exec the script? That's my next experiment anyway.

Any help would be greatly appreciated

Replies are listed 'Best First'.
Re: HTTP::Request to local script
by BUU (Prior) on Jan 16, 2005 at 00:35 UTC
    Emulating a CGI environment is rather trivial. You basically just need to set the following ENV variables and optionally pipe something to it via stdin. Also note you need to modify the ENV before you fork.
    sub run_local { local %ENV; %ENV = qw/foo bar baz etc/; open my $script, "perl foo.pl |" or die $!; print $script $CONTENT; my @return = <$script>; close $script; return @return; }
    The full list of CGI vars follows:

      Thanks, I figured that much, whith some help from the code for CGI::Lite and I have been busy-busy setting environment variables. I am not sure which ones I have to set and which ones I can ommit. I think I have most of them right now, but I still can't get the parameters to be passed.

      I think passing the content of the HTTP::Request object is not what I should be doing. Back to the doc...

Re: HTTP::Request to local script
by mirod (Canon) on Jan 15, 2005 at 18:17 UTC

    Indeed saving the query in a file and doing a system that sets the REMOTE_USER environment variable and run the script using the query as input gives me the right remote_user() in the script... but still doesn't get the parameters right.

    my( $new_fh, $new)= mkstemp( '/var/tmp/generate_new.XXXXX' ); print {$new_fh} $req->content; close $new_fh; my $user= remote_user(); system( "export REMOTE_USER=$user; cat $new | $SCRIPT") # probably + qualyfies as useless use of cat ;--) && exit_status( "problem running $SCRIPT: $!"); unlink( $new) or exit_status( "Warning: could not unlink temp file + $new $!");