The attached diff uses SCRIPT_FILENAME instead of SCRIPT_NAME to
determine the path of CGI scripts in slowcgi. It also updates the
example in nginx.conf.
According to CGI/1.1:
"The SCRIPT_NAME variable MUST be set to a URL path (not URL-encoded)
which could identify the CGI script (rather than the script's
output). The syntax is the same as for PATH_INFO (section 4.1.5)"
If you decided to run a CGI script outside of /cgi-bin/ SCRIPT_NAME no
longer matches the path of the CGI script as it is now local to the
document root.
You would need to set something like the following in nginx.conf to make
slowcgi be able to find the CGI script:
fastcgi_param SCRIPT_NAME $document_root$fastcgi_script_name;
However this now violates the CGI/1.1 spec as SCRIPT_NAME is now an
absolute path to the file on disk.
By introducing SCRIPT_FILENAME much like PHP does we can then use:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
when using CGI scripts outside of cgi-bin and SCRIPT_NAME still
functions as normal.
The /cgi-bin/ example doesn't need $document_root so your pretty much
setting SCRIPT_FILENAME = SCRIPT_NAME which seems redundant but once you
move outside of cgi-bin I believe this is the correct way to go.
--
James Turner
Index: usr.sbin/slowcgi/slowcgi.c
===================================================================
RCS file: /cvs/src/usr.sbin/slowcgi/slowcgi.c,v
retrieving revision 1.27
diff -u -p -u -p -r1.27 slowcgi.c
--- usr.sbin/slowcgi/slowcgi.c 19 Jan 2014 00:01:05 -0000 1.27
+++ usr.sbin/slowcgi/slowcgi.c 1 Mar 2014 21:32:03 -0000
@@ -118,7 +118,7 @@ struct request {
struct fcgi_response_head response_head;
struct fcgi_stdin_head stdin_head;
uint16_t id;
- char script_name[MAXPATHLEN];
+ char script_filename[MAXPATHLEN];
struct env_head env;
int env_count;
pid_t script_pid;
@@ -524,7 +524,7 @@ slowcgi_sig_handler(int sig, short event
create_end_record(c);
c->script_flags |= SCRIPT_DONE;
- ldebug("wait: %s", c->script_name);
+ ldebug("wait: %s", c->script_filename);
}
if (pid == -1 && errno != ECHILD)
lwarn("waitpid");
@@ -741,9 +741,9 @@ parse_params(uint8_t *buf, uint16_t n, s
env_entry->val[name_len] = '\0';
if (val_len < MAXPATHLEN && strcmp(env_entry->val,
- "SCRIPT_NAME") == 0) {
- bcopy(buf, c->script_name, val_len);
- c->script_name[val_len] = '\0';
+ "SCRIPT_FILENAME") == 0) {
+ bcopy(buf, c->script_filename, val_len);
+ c->script_filename[val_len] = '\0';
}
env_entry->val[name_len] = '=';
@@ -848,7 +848,7 @@ exec_cgi(struct request *c)
lerr(1, "socketpair");
cgi_inflight--;
c->inflight_fds_accounted = 1;
- ldebug("fork: %s", c->script_name);
+ ldebug("fork: %s", c->script_filename);
switch (pid = fork()) {
case -1:
@@ -887,15 +887,15 @@ exec_cgi(struct request *c)
close(s_out[1]);
close(s_err[1]);
- argv[0] = c->script_name;
+ argv[0] = c->script_filename;
argv[1] = NULL;
if ((env = calloc(c->env_count + 1, sizeof(char*))) == NULL)
_exit(1);
SLIST_FOREACH(env_entry, &c->env, entry)
env[i++] = env_entry->val;
env[i++] = NULL;
- execve(c->script_name, argv, env);
- lwarn("execve %s", c->script_name);
+ execve(c->script_filename, argv, env);
+ lwarn("execve %s", c->script_filename);
_exit(1);
}
Index: usr.sbin/nginx/conf/nginx.conf
===================================================================
RCS file: /cvs/src/usr.sbin/nginx/conf/nginx.conf,v
retrieving revision 1.16
diff -u -p -u -p -r1.16 nginx.conf
--- usr.sbin/nginx/conf/nginx.conf 28 Jan 2014 14:48:53 -0000 1.16
+++ usr.sbin/nginx/conf/nginx.conf 1 Mar 2014 21:32:03 -0000
@@ -64,6 +64,7 @@ http {
# fastcgi_pass unix:run/slowcgi.sock;
# fastcgi_split_path_info ^(/cgi-bin/[^/]+)(.*);
# fastcgi_param PATH_INFO $fastcgi_path_info;
+ # fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
# include fastcgi_params;
#}