Gustaf,

Yep, you are right. Looking at this again, I noticed a few additional
things which might help get this working as expected.

For one, the log trace is registered with Ns_RegisterServerTrace. The
documentation with this function says:

 *      Register a connection trace procedure.  Traces registered
 *      with this procedure are only called in FIFO order if the
 *      connection request procedure successfully responds to the
 *      clients request.

I read this to include successfully sending a forbidden, unauthorized or
internal server error response (Otherwise the access log would contain
only 200 response codes).

So I have rearranged the code so that the status code reflects the
actual status of sending a response to the client. 

Attached is a patch based upon the original code, not my last attempt,
and more info at:

http://www.junom.com/gitweb/gitweb.perl?p=aolserver.git;a=commit;h=7ab44


tom jackson



--
AOLserver - http://www.aolserver.com/

To Remove yourself from this list, simply send an email to 
<lists...@listserv.aol.com> with the
body of "SIGNOFF AOLSERVER" in the email message. You can leave the Subject: 
field of your email blank.
diff --git a/aolserver/nsd/queue.c b/aolserver/nsd/queue.c
index c620393..051abdc 100644
--- a/aolserver/nsd/queue.c
+++ b/aolserver/nsd/queue.c
@@ -56,6 +56,7 @@ typedef struct ConnData {
  */
 
 static void ConnRun(Conn *connPtr);	/* Connection run routine. */
+static int ConnAuthorize(Conn *connPtr);   /* Connection Authorize routine. */
 static void AppendConnList(Tcl_DString *dsPtr, Conn *firstPtr, char *state);
 
 /*
@@ -533,6 +534,59 @@ NsConnThread(void *arg)
 /*
  *----------------------------------------------------------------------
  *
+ * ConnAuthorize --
+ *
+ *      Try to authorize a connection.
+ *
+ * Results:
+ *      NS_OK on successful authorization,
+ *      NS_FILTER_RETURN on failure, or
+ *      NS_ERROR on error.
+ *
+ * Side effects:
+ *      Connection request is authorized. On failure an alternative
+ *      response may be sent to the client.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ConnAuthorize(Conn *connPtr)
+{
+    Ns_Conn 	  *conn = (Ns_Conn *) connPtr;
+    NsServer	  *servPtr = connPtr->servPtr;
+    int            status;
+
+    status = Ns_AuthorizeRequest(servPtr->server,
+		connPtr->request->method, connPtr->request->url, 
+		connPtr->authUser, connPtr->authPasswd, connPtr->peer);
+
+    switch (status) {
+    case NS_OK:
+        break;
+    case NS_FORBIDDEN:
+        if ((status = Ns_ConnReturnForbidden(conn)) == NS_OK) {
+	    status = NS_FILTER_RETURN;
+        }
+        break;
+    case NS_UNAUTHORIZED:
+        if ((status = Ns_ConnReturnUnauthorized(conn)) == NS_OK) {
+            status = NS_FILTER_RETURN;
+        }
+        break;
+    case NS_ERROR:
+    default:
+        status = NS_ERROR;
+        break;
+    }
+
+    return status;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
  * ConnRun --
  *
  *	Run a valid connection.
@@ -582,52 +636,49 @@ ConnRun(Conn *connPtr)
      * Run the request.
      */
 
-    if (connPtr->request->protocol != NULL && connPtr->request->host != NULL) {
-	status = NsConnRunProxyRequest((Ns_Conn *) connPtr);
-    } else {
-	status = NsRunFilters(conn, NS_FILTER_PRE_AUTH);
-	if (status == NS_OK) {
-	    status = Ns_AuthorizeRequest(servPtr->server,
-			connPtr->request->method, connPtr->request->url, 
-			connPtr->authUser, connPtr->authPasswd, connPtr->peer);
-	    switch (status) {
-	    case NS_OK:
-		status = NsRunFilters(conn, NS_FILTER_POST_AUTH);
-		if (status == NS_OK) {
-		    status = Ns_ConnRunRequest(conn);
-		}
-		break;
-
-	    case NS_FORBIDDEN:
-		Ns_ConnReturnForbidden(conn);
-		break;
-
-	    case NS_UNAUTHORIZED:
-		Ns_ConnReturnUnauthorized(conn);
-		break;
-
-	    case NS_ERROR:
-	    default:
-		Ns_ConnReturnInternalError(conn);
-		break;
-	    }
-        } else if (status != NS_FILTER_RETURN) {
-            /* if not ok or filter_return, then the pre-auth filter coughed
-             * an error.  We are not going to proceed, but also we
-             * can't count on the filter to have sent a response
-             * back to the client.  So, send an error response.
-             */
-            Ns_ConnReturnInternalError(conn);
-            status = NS_FILTER_RETURN; /* to allow tracing to happen */
+    while (1) {
+
+        if (connPtr->request->protocol != NULL
+            && connPtr->request->host != NULL) {
+
+            status = NsConnRunProxyRequest((Ns_Conn *) connPtr);
+            break;
+        }
+
+        status = NsRunFilters(conn, NS_FILTER_PRE_AUTH);
+        if (status != NS_OK) {
+            break;
+        }
+
+        status = ConnAuthorize(connPtr);
+        if (status != NS_OK) {
+            break;
         }
+
+        status = NsRunFilters(conn, NS_FILTER_POST_AUTH);
+        if (status != NS_OK) {
+            break;
+        }
+
+        status = Ns_ConnRunRequest(conn);
+        break;
+    }
+
+    if (status == NS_ERROR) {
+        status = Ns_ConnReturnInternalError(conn);
     }
+ 
     Ns_ConnClose(conn);
+
+    /* Trace filters run if successful response to client 
+     * Note that a successful response includes sending
+     * an internal server error response.
+     */
+
     if (status == NS_OK || status == NS_FILTER_RETURN) {
-	status = NsRunFilters(conn, NS_FILTER_TRACE);
-	if (status == NS_OK) {
-	    (void) NsRunFilters(conn, NS_FILTER_VOID_TRACE);
-	    NsRunTraces(conn);
-	}
+        NsRunFilters(conn, NS_FILTER_TRACE);
+        (void) NsRunFilters(conn, NS_FILTER_VOID_TRACE);
+        NsRunTraces(conn);
     }
 
     /*

Reply via email to