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); } /*