tags:

views:

38

answers:

2

I have a script which, given an ID, kicks off some complex processes and puts an RTF file onto stdout. For example, you might call it with something like foo.exe 27 to point it at ID 27.

Now I'd like to write a short PHP page which:

  • accepts a GET id parameter
  • checks that the parameter is an integer number
  • calls shell_exec(...) on the script (we'll assume it's on the $PATH)
  • responds with the output of the script, popping up the usual browser-specific download prompt, just as if they'd clicked on the file in a link

Can this be done easily?

A: 

Just make sure you leave (or set) ample time for the script to run - it could possibly take a long time and cause your request to time out.

Also, make sure you sanitize the input you put into exec().

But yeah, it can all be done.

Mr-sk
Increasing time is not always necessary. Any time spent doing system(), exec() or functions like this is not counted into the default 30 default seconds time limit (or user defined). See http://php.net/set_time_limit .
OcuS
Cool, good to know, thanks.
Mr-sk
A: 

This should be pretty simple. Just what you need is to make sure you're not inserting weird data to the script, to avoid any breaks, and to redirect STDERR to STDOUT to avoid to have errors and not to be able to see them.

<?php

// configuration
$scriptName = 'foo.exe';

// sets the header to send raw data to the browser
header('Content-Type: text/plain');    

// disables the timeout for your script
set_time_limit(0);

// if the input is not an integer
if (! is_integer($_GET['id']))
{
        // throw to forbidden page
        header("HTTP/1.0 403 Forbidden");
        die();
}

// parameter to use as parameter of 
// the command to call
$parameterId = (int) $_GET['id'];

// preparing the command and redirecting STDERR to STDOUT (the browser)
$command = "$scriptName $parameterId 2>&1";

// executing command and outputing it
print(shell_exec($command));

Hope it helps!

Pablo López Torres
Hmm -- don't we want to avoid redirecting stderr to stdout, since then it'd show up in the file stream? I think he wants to actually be able to have a file get downloaded.
John Feminella
Yes... of course if you want to pass thru a file you could log the STDERR to the file system with something like: $command = "$scriptName $parameterId 2>> /var/log/web-script.log"; instead of "echoing" it.
Pablo López Torres