in reply to Running a CGI script from a command line?
All other postings assume that the old script uses the CGI module, which has some debugging features. But there also is a generic way to fake CGI context from a shell, that works for all CGIs, written in any language. The trick is to know how CGI works, this is documented in RFC 3875.
Short summary: CGI programs are invoked with STDIN connected to a file or pipe delivering POSTed content, STDOUT connected to a file or pipe collecting output for the browser, STDERR connected to a file or pipe for logging. This is nearly the same setup you would expect from any unix command line utility. The big difference are arguments, they are passed via the environment, not as program parameters.
For a GET or HEAD request, you can ignore STDIN. If you are paranoid, redirect from /dev/null. For a POST request, you need to write the POSTed data into STDIN of the CGI program in the same format that the browser would send it to the webserver. You also have to set the environment variable "CONTENT_LENGTH" to the number of bytes in the POSTed data.
In any case, you should set the enviroment variable "GATEWAY_INTERFACE" to "CGI/1.1", as several CGIs use this to tell the difference between running in CGI mode (variable set) and running from command line for debugging (variable not set). The request method ("GET" / "HEAD" / "POST") is stored in "REQUEST_METHOD". CGI parameters that would be encoded in the URL have to be stored in the environment variable "QUERY_STRING", excluding the "?". Extra path elements in the URL, following the script URL, have to be placed in the environment variable "PATH_INFO".
Some rare CGIs need to know more, e.g. the host name from the URL ("HTTP_HOST"), the document root directory ("DOCUMENT_ROOT").
To fake a GET request for http://www.example.com/cgi-bin/some.cgi/extra/path/elements?name1=value1&name2=value2, minimally do this:
/usr/bin/env GATEWAY_INTERFACE='CGI/1.1' REQUEST_METHOD='GET' PATH_INF +O='/extra/path/elements' QUERY_STRING='name1=value1&name2=value2' /sr +v/www/cgi-bin/some.cgi
Note that you need to quote the ampersand (&), as it has a special meaning for most shells. To avoid shell traps, simply put every value in single quotes. Also note that all data from the URL stays URL-encoded (i.e. with %), decoding the values is done by the CGI.
Of course, you can put that in a shell script, that makes it easier to call the CGI program:
#!/bin/bash export GATEWAY_INTERFACE='CGI/1.1' export REQUEST_METHOD='GET' export PATH_INFO='/extra/path/elements' export QUERY_STRING='name1=value1&name2=value2' exec /srv/www/cgi-bin/some.cgi
You could also use a Perl script instead of bash, e.g. to set the encoded QUERY_STRING environment variable from unencoded command line arguments instead of hard-coding it:
#!/usr/bin/perl # called as wrapper.pl name1 arg1 name2 arg2 ... use strict; use warnings; sub encode { my $value=shift; $value=~s/([^A-Za-z0-9._-])/sprintf('%%%02X',ord $1)/ge; return $value; } $ENV{'GATEWAY_INTERFACE'}='CGI/1.1'; $ENV{'REQUEST_METHOD'}='GET'; $ENV{'PATH_INFO'}='/extra/path/elements'; my @pairs; while (@ARGV) { my $name=encode(shift @ARGV); my $value=encode(shift @ARGV); push @pairs,"$name=$value"; } $ENV{'QUERY_STRING'}=join('&',@pairs); exec('/srv/www/cgi-bin/some.cgi') or die "exec failed: $!";
I'm sure there is a way to do that in bash, too. But this is perlmonks, not bashmonks. ;-)
Alexander
|
---|
Replies are listed 'Best First'. | |
---|---|
Re^2: Running a CGI script from a command line?
by Anonymous Monk on Jun 16, 2015 at 08:13 UTC | |
Re^2: Running a CGI script from a command line?
by shanen (Initiate) on Jun 16, 2015 at 08:14 UTC | |
Re^2: Running a CGI script from a command line?
by shanen (Initiate) on Jun 17, 2015 at 08:23 UTC | |
by hippo (Archbishop) on Jun 17, 2015 at 09:03 UTC | |
by Anonymous Monk on Jun 17, 2015 at 09:26 UTC | |
by shanen (Initiate) on Jun 18, 2015 at 05:40 UTC | |
by afoken (Chancellor) on Jun 25, 2015 at 09:02 UTC | |
by shanen (Initiate) on Jun 25, 2015 at 06:09 UTC |