How to process only first path element in the URL as the CGI executable

I am using a FreePascal web module designed for apache cgi-bin with
nginx.

The CGI itself is called spidersample.cgi and contains modules such as
hello, bye etc.

With Apache when spidersample.cgi/hello is called, spidersample.cgi gets
executed, and passes control to the hello subroutine it contains.

With nginx instead of executing spidersample.cgi it treats
spidersample.cgi/hello as meaning a hello file in a spidersample.cgi
directory, and returns with a 404 error as there is no such directory.

I suspect it is an easily fixed problem with some rewrite rules in the
configuration file and it is posted below.

=============================================

server {
listen 8118;
server_name localhost;
access_log /var/log/nginx/sysman_access.log;
index index.html;
root /home/rchurch/Data/Lazarus/CgiApps;

    location ~ \.cgi$ {
            include /etc/nginx/fastcgi_params;
            fastcgi_pass unix:/tmp/sysman_cgi.sock;
            fastcgi_param  SCRIPT_FILENAME

$document_root$fastcgi_script_n$
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
}
}

==================================================================


Frank C.

=======================
http://devblog.brahmancreations.com

On Fri, Oct 08, 2010 at 04:02:48PM +0100, Frank C. wrote:

Hi there,

With Apache when spidersample.cgi/hello is called, spidersample.cgi gets
executed, and passes control to the hello subroutine it contains.

That’ll be due to the way Apache is configured.

With nginx instead of executing spidersample.cgi

nginx doesn’t execute cgi programs. It usually is configured either to
proxy_pass the request to a http server that will, or to fastcgi_pass
with params to a fastcgi-processing server.

It might just be a terminology difference, or it might be important to
your image of what happens.

it treats
spidersample.cgi/hello as meaning a hello file in a spidersample.cgi
directory, and returns with a 404 error as there is no such directory.

That’s probably down to the (default) configuration.

    location ~ \.cgi$ {

That says “for any request that ends in the four characters ‘.cgi’,
use this config”.

Your request for “/spidersample.cgi/hello” doesn’t match, and so doesn’t
use this config.

For initial testing, if you remove the “$”, then the config will be
used for any request that includes the 4-char string “.cgi”. That should
allow you to confirm the rest of the configuration.

Then you can change the location definition to include all and only the
requests you want handled this way.

Good luck with it,

f

Francis D. [email protected]

On 8 Out 2010 16h02 WEST, [email protected] wrote:

server {
listen 8118;
server_name localhost;
access_log /var/log/nginx/sysman_access.log;
index index.html;
root /home/rchurch/Data/Lazarus/CgiApps;

location ~ .cgi$ {
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/tmp/sysman_cgi.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_n$

Try: fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

— appa

On 8 October 2010 16:59, António P. P. Almeida [email protected] wrote:

gets executed, and passes control to the hello subroutine it

fastcgi_pass unix:/tmp/sysman_cgi.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_n$

Try: fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

That is due to a cut and paste issue from a narrow terminal screen, the
real
line is just as yours.

— appa


nginx mailing list
[email protected]
nginx Info Page


Frank C.

=======================
http://devblog.brahmancreations.com

On 8 October 2010 16:55, Francis D. [email protected] wrote:

For initial testing, if you remove the “$”, then the config will be
used for any request that includes the 4-char string “.cgi”. That should
allow you to confirm the rest of the configuration.

I removed the “$” and now this is the error message I get:

2010/10/08 21:06:46 [error] 14628#0: *22 FastCGI sent in stderr: “Cannot
chdir to script directory
(/home/rchurch/Data/Lazarus/CgiApps/spidersample.cgi)” while reading
response header from upstream, client: 127.0.0.1, server: localhost,
request: “GET /spidersample.cgi/hello HTTP/1.1”, upstream:
“fastcgi://unix:/tmp/rchurch_cgi.sock:”, host: “localhost:8118”,
referrer: "
http://localhost:8118/spidersample.cgi"

nginx mailing list
[email protected]
nginx Info Page


Frank C.

=======================
http://devblog.brahmancreations.com

On 8 Out 2010 16h02 WEST, [email protected] wrote:

[1 <multipart/alternative (7bit)>] [1.1 <text/plain; ISO-8859-1
(7bit)>] I am using a FreePascal web module designed for apache
cgi-bin with nginx.

The CGI itself is called spidersample.cgi and contains modules such
as hello, bye etc.

With Apache when spidersample.cgi/hello is called, spidersample.cgi
gets executed, and passes control to the hello subroutine it
contains.

Isn’t there something missing here? I would expect for a query string
separator somewhere that signals the application data portion of the
URI. It should be a ‘?’, according to

Something like spidersample.cgi?q=hello or similar.

I’m guessing that there’s some rewrite rule in the Apache config that
didn’t get converted to nginx. Hence the script is failing. And it
makes sense according to the config. After all any request not ending
in .cgi is handled “as usual” by nginx, therefore it tries to get the
file in /home/rchurch/Data/Lazarus/CgiApps/spidersample.cgi/hello. If
it doesn’t exist it returns a 404.

With nginx instead of executing spidersample.cgi it treats
spidersample.cgi/hello as meaning a hello file in a spidersample.cgi
directory, and returns with a 404 error as there is no such
directory.

Yes.

I suspect it is an easily fixed problem with some rewrite rules in
the configuration file and it is posted below.

The rewrite rule must be in the Apache config, find it and port it to
nginx.

HTH,
— appa

I tried your suggestion and it worked.

I have yet to learn more about “changing the location definition to
include
all and only the
requests you want handled this way.”

Thanks

On 9 October 2010 11:12, Francis D. [email protected] wrote:

(/home/rchurch/Data/Lazarus/CgiApps/spidersample.cgi)" while reading
which is untrue. SCRIPT_FILENAME is
if they are already in the included /etc/nginx/fastcgi_params. You can
fastcgi_param REQUEST_METHOD $request_method;


Frank C.

=======================
http://devblog.brahmancreations.com

On Fri, Oct 08, 2010 at 09:10:27PM +0100, Frank C. wrote:

On 8 October 2010 16:55, Francis D. [email protected] wrote:

On Fri, Oct 08, 2010 at 04:02:48PM +0100, Frank C. wrote:

Hi there,

With nginx instead of executing spidersample.cgi it treats
spidersample.cgi/hello as meaning a hello file in a spidersample.cgi
directory, and returns with a 404 error as there is no such directory.

    location ~ \.cgi$ {

Your request for “/spidersample.cgi/hello” doesn’t match, and so doesn’t
use this config.

I removed the “$” and now this is the error message I get:

2010/10/08 21:06:46 [error] 14628#0: *22 FastCGI sent in stderr: “Cannot
chdir to script directory
(/home/rchurch/Data/Lazarus/CgiApps/spidersample.cgi)” while reading
response header from upstream, client: 127.0.0.1, server: localhost,
request: “GET /spidersample.cgi/hello HTTP/1.1”, upstream:
“fastcgi://unix:/tmp/rchurch_cgi.sock:”, host: “localhost:8118”, referrer: "
http://localhost:8118/spidersample.cgi"

That suggests that this location block is now being used
for this request, which is good. The error is because the
fastcgi processor was told that the SCRIPT_FILENAME was
/home/rchurch/Data/Lazarus/CgiApps/spidersample.cgi/hello,
which is untrue. SCRIPT_FILENAME is
“/home/rchurch/Data/Lazarus/CgiApps/spidersample.cgi”.

Also, the script itself almost certainly uses PATH_INFO to determine
which module of its own to use – “hello”, “echo”, or some other –
so you’ll want to set that too.

The easiest way to do both is probably to use fastcgi_split_path_info.
See
the two new lines below that include the string “path_info”.

Note – it is possible that all of the fastcgi_param lines are
unnecessary
if they are already in the included /etc/nginx/fastcgi_params. You can
experiment with removing them at leisure.

location ~ \.cgi {
        fastcgi_split_path_info (.*\.cgi)(/.*);
        include /etc/nginx/fastcgi_params;
        fastcgi_pass unix:/tmp/sysman_cgi.sock;
        fastcgi_param  SCRIPT_FILENAME 

$document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param PATH_INFO $fastcgi_path_info;
}

Then you can change the location definition to include all and only the
requests you want handled this way.

That bit should still be done.

All the best,

f

Francis D. [email protected]

On Sat, Oct 09, 2010 at 08:31:27PM +0100, Frank C. wrote:

Hi there,

I tried your suggestion and it worked.

Good stuff.

I have yet to learn more about “changing the location definition to include
all and only the
requests you want handled this way.”

It’s the usual security/convenience trade-off. If you know that you’re
the only person who can add accessible urls to the server, then you
can make sure that nothing with “.cgi” in the name that might lead to
a security breach will be added.

I prefer to have a less generic configuration – so, for example, only
files in the /cgi-bin/ namespace should be processed by the fastcgi
server; or perhaps even only spidersample.cgi should be processed
that way.

You have to decide what urls should go to the fastcgi service, and find
one or more location patterns that match all of those urls, and match no
other urls.

So maybe something like

location ~ spidersample.cgi

or

location ~^ /spidersample.cgi

or

location ~ /cgi-bin/*.cgi

or even

location ~ /spidersample.cgi($|/)

will suit your requirements.

All the best,

f

Francis D. [email protected]