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
<[email protected]> 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);
}
/*