X-Git-Url: http://www.dolda2000.com/gitweb/?a=blobdiff_plain;f=src%2Fcallcgi.c;h=fb2596bff6c6b4825afa5c08f42f5563e3a3719e;hb=33f29d6778ddc733a054e07d0d255f63a77797ac;hp=dcd681948acccc7641d0dc83fa6e66079990028b;hpb=f812ea037b5c693977e83ace9ed7ac2515a4a6d0;p=ashd.git diff --git a/src/callcgi.c b/src/callcgi.c index dcd6819..fb2596b 100644 --- a/src/callcgi.c +++ b/src/callcgi.c @@ -52,10 +52,21 @@ static void passdata(FILE *in, FILE *out) free(buf); } +static char *absolutify(char *file) +{ + char cwd[1024]; + + if(*file != '/') { + getcwd(cwd, sizeof(cwd)); + return(sprintf2("%s/%s", cwd, file)); + } + return(sstrdup(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; @@ -74,21 +85,31 @@ 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)); + if(*rest) + putenv(sprintf2("PATH_INFO=/%s", rest)); + else + putenv("PATH_INFO="); + 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")) @@ -103,7 +124,7 @@ static void forkchild(int inpath, char *prog, char *file, char *method, char *ur * This is (understandably) missing from the CGI * specification, but PHP seems to require it. */ - putenv(sprintf2("SCRIPT_FILENAME=%s", file)); + putenv(sprintf2("SCRIPT_FILENAME=%s", absolutify(file))); if(inpath) execlp(prog, prog, file, NULL); else @@ -247,13 +268,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"); } } @@ -261,7 +282,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; } } @@ -318,7 +339,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); }