Made callcgi more Apache-compliant.
[ashd.git] / src / callcgi.c
index 70a97dd..10bb87c 100644 (file)
@@ -66,7 +66,7 @@ static char *absolutify(char *file)
 static void forkchild(int inpath, char *prog, char *file, char *method, char *url, char *rest, int *infd, int *outfd)
 {
     int i;
-    char *qp, **env;
+    char *qp, **env, *name;
     int inp[2], outp[2];
     pid_t pid;
 
@@ -85,21 +85,28 @@ static void forkchild(int inpath, char *prog, char *file, char *method, char *ur
            close(i);
        if((qp = strchr(url, '?')) != NULL)
            *(qp++) = 0;
-       /*
-        * XXX: Currently missing:
-        *  SERVER_NAME (Partially)
-        *  SERVER_PORT
-        */
        putenv(sprintf2("SERVER_SOFTWARE=ashd/%s", VERSION));
        putenv("GATEWAY_INTERFACE=CGI/1.1");
        if(getenv("HTTP_VERSION"))
-           putenv(sprintf2("SERVER_PROTOCOL=HTTP/%s", getenv("HTTP_VERSION")));
+           putenv(sprintf2("SERVER_PROTOCOL=%s", getenv("HTTP_VERSION")));
        putenv(sprintf2("REQUEST_METHOD=%s", method));
-       putenv(sprintf2("PATH_INFO=%s", rest));
-       putenv(sprintf2("SCRIPT_NAME=%s", url));
+       putenv(sprintf2("PATH_INFO=/%s", rest));
+       name = url;
+       /* XXX: This is an ugly hack (I think), but though I can think
+        * of several alternatives, none seem to be better. */
+       if(*rest && (strlen(url) > strlen(rest)) &&
+          !strcmp(rest, url + strlen(url) - strlen(rest)) &&
+          (url[strlen(url) - strlen(rest) - 1] == '/')) {
+           name = sprintf2("%.*s", (int)(strlen(url) - strlen(rest) - 1), url);
+       }
+       putenv(sprintf2("SCRIPT_NAME=%s", name));
        putenv(sprintf2("QUERY_STRING=%s", qp?qp:""));
        if(getenv("REQ_HOST"))
            putenv(sprintf2("SERVER_NAME=%s", getenv("REQ_HOST")));
+       if(getenv("REQ_X_ASH_SERVER_PORT"))
+           putenv(sprintf2("SERVER_PORT=%s", getenv("REQ_X_ASH_SERVER_PORT")));
+       if(getenv("REQ_X_ASH_PROTOCOL") && !strcmp(getenv("REQ_X_ASH_PROTOCOL"), "https"))
+           putenv("HTTPS=on");
        if(getenv("REQ_X_ASH_ADDRESS"))
            putenv(sprintf2("REMOTE_ADDR=%s", getenv("REQ_X_ASH_ADDRESS")));
        if(getenv("REQ_CONTENT_TYPE"))
@@ -258,13 +265,13 @@ static void sendstatus(char **headers, FILE *out)
     }
     if(status) {
        if(strchr(status, ' '))
-           fprintf(out, "HTTP/1.1 %s\r\n", status);
+           fprintf(out, "HTTP/1.1 %s\n", status);
        else
-           fprintf(out, "HTTP/1.1 %i %s\r\n", atoi(status), defstatus(atoi(status)));
+           fprintf(out, "HTTP/1.1 %i %s\n", atoi(status), defstatus(atoi(status)));
     } else if(location) {
-       fprintf(out, "HTTP/1.1 303 See Other\r\n");
+       fprintf(out, "HTTP/1.1 303 See Other\n");
     } else {
-       fprintf(out, "HTTP/1.1 200 OK\r\n");
+       fprintf(out, "HTTP/1.1 200 OK\n");
     }
 }
 
@@ -272,7 +279,7 @@ static void sendheaders(char **headers, FILE *out)
 {
     while(*headers) {
        if(**headers)
-           fprintf(out, "%s: %s\r\n", headers[0], headers[1]);
+           fprintf(out, "%s: %s\n", headers[0], headers[1]);
        headers += 2;
     }
 }
@@ -329,7 +336,7 @@ int main(int argc, char **argv, char **envp)
     }
     sendstatus(headers, stdout);
     sendheaders(headers, stdout);
-    printf("\r\n");
+    printf("\n");
     passdata(out, stdout);
     return(0);
 }