userplex: Fixed missing-404 bug, finally.
authorFredrik Tolf <fredrik@dolda2000.com>
Sat, 29 Dec 2012 05:09:33 +0000 (06:09 +0100)
committerFredrik Tolf <fredrik@dolda2000.com>
Sat, 29 Dec 2012 05:09:33 +0000 (06:09 +0100)
doc/userplex.doc
src/userplex.c

index e69cb5d..1269073 100644 (file)
@@ -41,8 +41,8 @@ argument. 'PUBDIR' defaults to `htpub` if no 'PROGRAM' was specified.
 
 If 'PUBDIR' was given (either by being specified explicitly, or
 implicitly if no 'PROGRAM' argument was given), it is checked for
 
 If 'PUBDIR' was given (either by being specified explicitly, or
 implicitly if no 'PROGRAM' argument was given), it is checked for
-existence. If it does not exist, *userplex* should return a 404
-response to the client (but see BUGS below).
+existence. If it does not exist, *userplex* returns a 404 response to
+the client.
 
 If there exists a file named `~/.ashd/error` in the user's home
 directory, it will be opened in append mode and connected to the
 
 If there exists a file named `~/.ashd/error` in the user's home
 directory, it will be opened in append mode and connected to the
@@ -126,12 +126,6 @@ its normal login procedure, and then *exec*(2) the *dirplex*(1)
 handler to serve files normally. Of course, the second line can be
 replaced by whatever other handler one might wish to use.
 
 handler to serve files normally. Of course, the second line can be
 replaced by whatever other handler one might wish to use.
 
-BUGS
-----
-
-Currently, *userplex* does not, in fact, return a 404 response to the
-client if the 'PUBDIR' directory does not exist.
-
 AUTHOR
 ------
 Fredrik Tolf <fredrik@dolda2000.com>
 AUTHOR
 ------
 Fredrik Tolf <fredrik@dolda2000.com>
index 357d791..c50a15c 100644 (file)
@@ -98,18 +98,35 @@ static void login(struct passwd *pwd)
     }
 }
 
     }
 }
 
-static void execchild(struct passwd *pwd)
+static void discardreq(int fromfd)
+{
+    struct hthead *req;
+    int fd;
+    
+    if((fd = recvreq(fromfd, &req)) >= 0) {
+       freehthead(req);
+       close(fd);
+    }
+}
+
+static void execchild(struct passwd *pwd, struct hthead *forreq, int reqfd)
 {
     if(!ignore)
        execl(".ashd/handler", ".ashd/handler", NULL);
     if(dirname != NULL) {
 {
     if(!ignore)
        execl(".ashd/handler", ".ashd/handler", NULL);
     if(dirname != NULL) {
-       if(access(dirname, X_OK | R_OK))
+       if(access(dirname, X_OK | R_OK)) {
+           discardreq(0);
+           simpleerror(reqfd, 404, "Not Found", "No such resource could be found.");
            return;
            return;
+       }
     }
     execvp(childspec[0], childspec);
     }
     execvp(childspec[0], childspec);
+    discardreq(0);
+    flog(LOG_ERR, "could not start request handler for user `%s': %s", pwd->pw_name, strerror(errno));
+    simpleerror(reqfd, 500, "User Error", "Could not start any request handler for that user.");
 }
 
 }
 
-static int forkchild(char *usrnm)
+static int forkchild(char *usrnm, struct hthead *forreq, int reqfd)
 {
     struct passwd *pwd;
     pid_t pid;
 {
     struct passwd *pwd;
     pid_t pid;
@@ -131,7 +148,7 @@ static int forkchild(char *usrnm)
        close(fd[0]);
        close(fd[1]);
        login(pwd);
        close(fd[0]);
        close(fd[1]);
        login(pwd);
-       execchild(pwd);
+       execchild(pwd, forreq, reqfd);
        exit(127);
     }
     close(fd[0]);
        exit(127);
     }
     close(fd[0]);
@@ -142,19 +159,18 @@ static int forkchild(char *usrnm)
 static void serve2(struct user *usr, struct hthead *req, int fd)
 {
     if(usr->fd < 0)
 static void serve2(struct user *usr, struct hthead *req, int fd)
 {
     if(usr->fd < 0)
-       usr->fd = forkchild(usr->name);
+       usr->fd = forkchild(usr->name, req, fd);
     if(sendreq(usr->fd, req, fd)) {
        if((errno == EPIPE) || (errno == ECONNRESET)) {
            /* Assume that the child has crashed and restart it. */
            close(usr->fd);
     if(sendreq(usr->fd, req, fd)) {
        if((errno == EPIPE) || (errno == ECONNRESET)) {
            /* Assume that the child has crashed and restart it. */
            close(usr->fd);
-           usr->fd = forkchild(usr->name);
+           usr->fd = forkchild(usr->name, req, fd);
            if(!sendreq(usr->fd, req, fd))
                return;
        }
        flog(LOG_ERR, "could not pass on request to user `%s': %s", usr->name, strerror(errno));
        close(usr->fd);
        usr->fd = -1;
            if(!sendreq(usr->fd, req, fd))
                return;
        }
        flog(LOG_ERR, "could not pass on request to user `%s': %s", usr->name, strerror(errno));
        close(usr->fd);
        usr->fd = -1;
-       simpleerror(fd, 500, "User Error", "The request handler for that user keeps crashing.");
     }
 }
 
     }
 }