Patch

Kuba Winnicki <[email protected]> Thu, 26 Feb 2004 11:48:35 +0100
Newsgroups gmane.comp.web.fnord
Organization http://www.yn.pl/
Message-ID <[email protected]>
Hi,

This patch makes fnord:

- chdir() to cgi's base dir before execve()'ing,
- set HTTP_ACCEPT_ENCODING environment variable,
- avoid calling badrequest() headers on signal if HTTP headers are
  already sent.

First conforms to the standard. From the spec (8.2)
<http://cgi-spec.golux.com/draft-coar-cgi-v11-03.txt>:

|   Where applicable, servers SHOULD set the current working
|   directory to the directory in which the script is located
|   before invoking it.

Second is handy when you want to send compressed content if your client
accepts it. I guess code should be rewritten though, so all request
headers are available to cgi through environment variables, as specified
in 6.1.5 of the spec.

Third one works for me, i.e. doesn't paste HTTP header at the end of
output on signal catch anymore (SIGSEGV in my case ;)). I'm not that
familiar with code to be sure, but i guess this fix may not handle all
such situations...

-- 
Regards,
Kuba Winnicki <[email protected]>
fnord.diff (text/plain, 2 KB)
--- ../httpd/httpd.c	Fri Aug 22 14:16:04 2003
+++ httpd.c	Thu Feb 26 10:31:36 2004
@@ -130,6 +130,7 @@
 char *url;			/* string between GET and HTTP/1.0, demangled */
 char *ua="?";			/* user-agent */
 char *refer;			/* Referrer: header */
+char *accept_enc;		/* Accept-Encoding */
 int httpversion;		/* 0 == 1.0, 1 == 1.1 */
 #ifdef KEEPALIVE
 int keepalive=0;		/* should we keep the connection alive? */
@@ -277,6 +278,7 @@
   "HTTP_USER_AGENT=",
   "HTTP_COOKIE=",
   "HTTP_REFERER=",
+  "HTTP_ACCEPT_ENCODING=",
   "AUTH_TYPE=",
   "CONTENT_TYPE=",
   "CONTENT_LENGTH=",
@@ -379,6 +381,13 @@
     *tmp=0; ++tmp;
   }
 
+  if (accept_enc) {
+    cgi_env[++i]=tmp;
+    tmp+=str_copy(tmp,"HTTP_ACCEPT_ENCODING=");
+    tmp+=str_copy(tmp,accept_enc);
+    *tmp=0; ++tmp;
+  }
+
   if (auth_type) {
     cgi_env[++i]=tmp;
     tmp+=str_copy(tmp,"AUTH_TYPE=");
@@ -441,10 +450,15 @@
     cgi_arg[1]=0;
   }
 
+  i=strrchr(url,'/')-url;
+  strncpy(tmp,url+1,i);
+  tmp[i]=0;
+  chdir(tmp);
+
   /* program name */
   cgi_arg[0]=tmp;
   tmp[0]='.';
-  tmp[str_copy(tmp+1,url)+1]=0;
+  tmp[str_copy(tmp+1,url+i)+1]=0;
 
   /* start cgi */
   execve(cgi_arg[0],cgi_arg,cgi_env);
@@ -533,6 +547,7 @@
 	      if (byte_diff(ibuf,10,"Location: ")==0) {
 		retcode=302;
 		buffer_puts(buffer_1,"HTTP/1.0 302 CGI-Redirect\r\nConnection: close\r\n");
+		signal(SIGCHLD,SIG_IGN);
 		cgi_send_correct_http(ibuf,n);
 		buffer_flush(buffer_1);
 		dolog(0);
@@ -541,6 +556,7 @@
 	      else {
 		retcode=200;
 		buffer_puts(buffer_1,"HTTP/1.0 200 OK\r\nServer: "FNORD"\r\nPragma: no-cache\r\nConnection: close\r\n");
+		signal(SIGCHLD,SIG_IGN);
 		cgi_send_correct_http(ibuf,n);
 	      }
 	    }
@@ -1336,6 +1352,7 @@
     char *tmp;
     if ((tmp=header(buf,len,"User-Agent"))) ua=tmp;
     if ((tmp=header(buf,len,"Referer"))) refer=tmp;
+    if ((tmp=header(buf,len,"Accept-Encoding"))) accept_enc=tmp;
 #ifdef KEEPALIVE
     if ((tmp=header(buf,len,"Connection"))) {	/* see if it's "keep-alive" or "close" */
       if (!strcasecmp(tmp,"keep-alive"))