Update of /cvsroot/aolserver/aolserver/nsd
In directory vz-cvs-4.sog:/tmp/cvs-serv9402/nsd
Modified Files:
conn.c connio.c driver.c filter.c nsd.h op.c queue.c server.c
tclrequest.c
Log Message:
add various functions, mostly from SF RFEs -
pre-write filter, response content modification,
insert/append filter, priority filters, ns_conn gzip flag,
re-run filters on redirect with new config option "filterredirect",
add new constants, fix STREQ macro
Index: nsd.h
===================================================================
RCS file: /cvsroot/aolserver/aolserver/nsd/nsd.h,v
retrieving revision 1.124
retrieving revision 1.125
diff -C2 -d -r1.124 -r1.125
*** nsd.h 7 Oct 2011 17:06:30 -0000 1.124
--- nsd.h 11 Oct 2011 08:03:27 -0000 1.125
***************
*** 513,516 ****
--- 513,522 ----
/*
+ * output buffers, used if needed
+ */
+ char *sbuf; /* pointer to content requested to be sent */
+ Tcl_DString *rbuf; /* buffer for response content. */
+
+ /*
* The following offsets are used to manage the
* buffer read-ahead process.
***************
*** 585,588 ****
--- 591,595 ----
#define SERV_NOTICEDETAIL 0x0008 /* Add detail to notice messages. */
#define SERV_GZIP 0x0010 /* Enable GZIP compression. */
+ #define SERV_FILTERREDIRECT 0x0020 /* re-run filters on redirects */
/*
***************
*** 1099,1102 ****
--- 1106,1110 ----
extern int NsConnRunProxyRequest(Ns_Conn *conn);
+ extern int NsConnRunDirectRequest(Ns_Conn *conn);
#endif
Index: conn.c
===================================================================
RCS file: /cvsroot/aolserver/aolserver/nsd/conn.c,v
retrieving revision 1.51
retrieving revision 1.52
diff -C2 -d -r1.51 -r1.52
*** conn.c 5 Aug 2011 11:49:45 -0000 1.51
--- conn.c 11 Oct 2011 08:03:27 -0000 1.52
***************
*** 1006,1009 ****
--- 1006,1065 ----
*----------------------------------------------------------------------
*
+ * Ns_ConnGetResponseContent
+ * Ns_ConnSetResponseContent
+ * Ns_ConnAppendResponseContent
+ *
+ * get, set, or append to the response content
+ *
+ * Results:
+ * the current content buffer
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+ char *Ns_ConnGetResponseContent(Ns_Conn *conn)
+ {
+ Conn *connPtr = (Conn *) conn;
+
+ if (connPtr->rbuf!= NULL) {
+ return Tcl_DStringValue(connPtr->rbuf);
+ } else {
+ return connPtr->sbuf;
+ }
+ }
+
+ char *Ns_ConnSetResponseContent(Ns_Conn *conn, char *content)
+ {
+ Conn *connPtr = (Conn *) conn;
+
+ if (connPtr->rbuf == NULL) {
+ connPtr->rbuf=ns_malloc(sizeof(Tcl_DString));
+ Tcl_DStringInit(connPtr->rbuf);
+ }
+ Tcl_DStringSetLength(connPtr->rbuf,0);
+ Tcl_DStringAppend(connPtr->rbuf, content, -1);
+ return Tcl_DStringValue(connPtr->rbuf);
+ }
+
+ char *Ns_ConnAppendResponseContent(Ns_Conn *conn, char *content)
+ {
+ Conn *connPtr = (Conn *) conn;
+
+ if (connPtr->rbuf == NULL) {
+ connPtr->rbuf=ns_malloc(sizeof(Tcl_DString));
+ Tcl_DStringInit(connPtr->rbuf);
+ Tcl_DStringAppend(connPtr->rbuf, connPtr->sbuf, -1);
+ }
+ Tcl_DStringAppend(connPtr->rbuf, content, -1);
+ return Tcl_DStringValue(connPtr->rbuf);
+ }
+
+
+
+ /*
+ *----------------------------------------------------------------------
+ *
* NsTclConnObjCmd --
*
***************
*** 1044,1048 ****
"query", "request", "server", "sock", "start", "status",
"url", "urlc", "urlencoding", "urlv", "version",
! "write_encoded", "interp", NULL
};
enum {
--- 1100,1104 ----
"query", "request", "server", "sock", "start", "status",
"url", "urlc", "urlencoding", "urlv", "version",
! "write_encoded", "interp","gzip","responsecontent", NULL
};
enum {
***************
*** 1055,1059 ****
CProtocolIdx, CQueryIdx, CRequestIdx, CServerIdx, CSockIdx,
CStartIdx, CStatusIdx, CUrlIdx, CUrlcIdx, CUrlEncodingIdx,
! CUrlvIdx, CVersionIdx, CWriteEncodedIdx, CInterpIdx
} opt;
--- 1111,1116 ----
CProtocolIdx, CQueryIdx, CRequestIdx, CServerIdx, CSockIdx,
CStartIdx, CStatusIdx, CUrlIdx, CUrlcIdx, CUrlEncodingIdx,
! CUrlvIdx, CVersionIdx, CWriteEncodedIdx, CInterpIdx,
! CGzipIdx, CRespContentIdx
} opt;
***************
*** 1394,1397 ****
--- 1451,1475 ----
Tcl_SetLongObj(result, (long) interp);
break;
+
+ case CGzipIdx:
+ if (objc > 2) {
+ int flag;
+ if (Tcl_GetBooleanFromObj(interp, objv[2], &flag) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ Ns_ConnSetGzipFlag(conn, flag);
+ }
+ Tcl_SetIntObj(result, Ns_ConnGetGzipFlag(conn));
+ break;
+
+ case CRespContentIdx:
+ if (objc == 2) {
+ Tcl_SetResult(interp, Ns_ConnGetResponseContent(connPtr), TCL_STATIC);
+ } else if (objc == 3) {
+ Tcl_SetResult(interp, Ns_ConnSetResponseContent(connPtr, Tcl_GetString(objv[2])), TCL_STATIC);
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, "?value?");
+ return TCL_ERROR;
+ }
}
***************
*** 1640,1643 ****
--- 1718,1724 ----
connPtr->sockPtr->sock = sock;
}
+ if (chan != NULL) {
+ Tcl_Ungets(chan,connPtr->content, connPtr->avail, 0);
+ }
return chan;
Index: connio.c
===================================================================
RCS file: /cvsroot/aolserver/aolserver/nsd/connio.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -C2 -d -r1.28 -r1.29
*** connio.c 8 Dec 2009 04:12:19 -0000 1.28
--- connio.c 11 Oct 2011 08:03:27 -0000 1.29
***************
*** 136,139 ****
--- 136,149 ----
int status;
+ connPtr->sbuf=buf;
+ if (NsRunFilters((Ns_Conn *) connPtr, NS_FILTER_PRE_WRITE) != NS_OK) {
+ return NS_ERROR;
+ }
+ if (connPtr->rbuf != NULL) {
+ /* the content was set by pre-write filters */
+ buf=Tcl_DStringValue(connPtr->rbuf);
+ len=Tcl_DStringLength(connPtr->rbuf);
+ }
+
Tcl_DStringInit(&enc);
Tcl_DStringInit(&gzip);
Index: op.c
===================================================================
RCS file: /cvsroot/aolserver/aolserver/nsd/op.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -C2 -d -r1.17 -r1.18
*** op.c 16 Jul 2011 09:25:29 -0000 1.17
--- op.c 11 Oct 2011 08:03:27 -0000 1.18
***************
*** 291,295 ****
{
Conn *connPtr = (Conn *) conn;
- int status;
++connPtr->recursionCount;
--- 291,294 ----
***************
*** 305,328 ****
*/
! status = Ns_AuthorizeRequest(Ns_ConnServer(conn), conn->request->method,
! conn->request->url, conn->authUser,
! conn->authPasswd, Ns_ConnPeer(conn));
! switch (status) {
! case NS_OK:
! status = Ns_ConnRunRequest(conn);
! break;
! case NS_FORBIDDEN:
! status = Ns_ConnReturnForbidden(conn);
! break;
! case NS_UNAUTHORIZED:
! status = Ns_ConnReturnUnauthorized(conn);
! break;
! case NS_ERROR:
! default:
! status = Ns_ConnReturnInternalError(conn);
! break;
! }
!
! return status;
}
--- 304,308 ----
*/
! return NsConnRunDirectRequest(conn);
}
***************
*** 472,475 ****
--- 452,527 ----
*----------------------------------------------------------------------
*
+ * NsConnRunDirectRequest --
+ *
+ * runs pre/post-auth filters and main connection
+ *
+ * Results:
+ * Standard request procedure result, normally NS_OK.
+ *
+ * Side effects:
+ * Depends on request procedure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ int NsConnRunDirectRequest(Ns_Conn *conn)
+ {
+ int status;
+ Conn *connPtr = (Conn *) conn;
+
+ /*
+ * always run pre/post-auth filters on initial request;
+ * if this is an internal redirect then only run them
+ * if the "filterredirect" option is set
+ */
+ int runFilters = (connPtr->recursionCount == 0 ||
+ connPtr->servPtr->opts.flags & SERV_FILTERREDIRECT);
+
+ status = runFilters ?
+ NsRunFilters(conn, NS_FILTER_PRE_AUTH) :
+ NS_OK;
+ if (status == NS_OK) {
+ status = Ns_AuthorizeRequest(Ns_ConnServer(conn),
+ conn->request->method, conn->request->url,
+ conn->authUser, conn->authPasswd, Ns_ConnPeer(conn));
+ switch (status) {
+ case NS_OK:
+ status = runFilters ?
+ NsRunFilters(conn, NS_FILTER_POST_AUTH) :
+ NS_OK;
+ 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 */
+ }
+ return status;
+ }
+
+
+ /*
+ *----------------------------------------------------------------------
+ *
* FreeReq --
*
Index: filter.c
===================================================================
RCS file: /cvsroot/aolserver/aolserver/nsd/filter.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -C2 -d -r1.10 -r1.11
*** filter.c 28 Sep 2002 19:23:39 -0000 1.10
--- filter.c 11 Oct 2011 08:03:27 -0000 1.11
***************
*** 58,61 ****
--- 58,63 ----
} Trace;
+ #define FILTER_GETPRIO(when) ((signed char)((when & 0xFF000000) >> 24))
+
static Trace *NewTrace(Ns_TraceProc *proc, void *arg);
static void RunTraces(Ns_Conn *conn, Trace *firstPtr);
***************
*** 96,104 ****
fPtr->when = when;
fPtr->arg = arg;
- fPtr->nextPtr = NULL;
fPtrPtr = &servPtr->filter.firstFilterPtr;
! while (*fPtrPtr != NULL) {
fPtrPtr = &((*fPtrPtr)->nextPtr);
}
*fPtrPtr = fPtr;
return (void *) fPtr;
--- 98,115 ----
fPtr->when = when;
fPtr->arg = arg;
fPtrPtr = &servPtr->filter.firstFilterPtr;
! /* locate the first filter at this priority */
! while (*fPtrPtr != NULL
! && FILTER_GETPRIO(fPtr->when) > FILTER_GETPRIO((*fPtrPtr)->when)) {
fPtrPtr = &((*fPtrPtr)->nextPtr);
}
+ /* if appending, locate last filter in the same priority group */
+ if (!(when & NS_FILTER_INSERT)) {
+ while (*fPtrPtr != NULL
+ && FILTER_GETPRIO(fPtr->when) == FILTER_GETPRIO((*fPtrPtr)->when)) {
+ fPtrPtr = &((*fPtrPtr)->nextPtr);
+ }
+ }
+ fPtr->nextPtr = *fPtrPtr;
*fPtrPtr = fPtr;
return (void *) fPtr;
Index: server.c
===================================================================
RCS file: /cvsroot/aolserver/aolserver/nsd/server.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -C2 -d -r1.50 -r1.51
*** server.c 7 Oct 2011 17:06:31 -0000 1.50
--- server.c 11 Oct 2011 08:03:27 -0000 1.51
***************
*** 271,274 ****
--- 271,277 ----
servPtr->opts.flags |= SERV_NOTICEDETAIL;
}
+ if (!Ns_ConfigGetBool(path, "filterredirect", &i) || i) {
+ servPtr->opts.flags |= SERV_FILTERREDIRECT;
+ }
p = Ns_ConfigGetValue(path, "headercase");
if (p != NULL && STRIEQ(p, "tolower")) {
Index: queue.c
===================================================================
RCS file: /cvsroot/aolserver/aolserver/nsd/queue.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -C2 -d -r1.50 -r1.51
*** queue.c 5 Aug 2011 11:49:45 -0000 1.50
--- queue.c 11 Oct 2011 08:03:27 -0000 1.51
***************
*** 597,635 ****
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 */
! }
}
Ns_ConnClose(conn);
--- 597,601 ----
status = NsConnRunProxyRequest((Ns_Conn *) connPtr);
} else {
! status = NsConnRunDirectRequest((Ns_Conn *) connPtr);
}
Ns_ConnClose(conn);
Index: tclrequest.c
===================================================================
RCS file: /cvsroot/aolserver/aolserver/nsd/tclrequest.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** tclrequest.c 8 Dec 2009 04:12:19 -0000 1.14
--- tclrequest.c 11 Oct 2011 08:03:27 -0000 1.15
***************
*** 258,279 ****
int when, i;
static CONST char *wopt[] = {
! "read", "write", "prequeue", "preauth", "postauth", "trace", NULL
};
enum {
! ReadIdx, WriteIdx, PreQueueIdx, PreAuthIdx, PostAuthIdx, TraceIdx,
} widx;
if (objc < 2) {
! Tcl_WrongNumArgs(interp, 1, objv, "option ?args?");
return TCL_ERROR;
}
! if (objc != 5 && objc != 6) {
! Tcl_WrongNumArgs(interp, 1, objv, "when method url script ?arg?");
! return TCL_ERROR;
}
if (Tcl_ListObjGetElements(interp, objv[1], &lobjc, &lobjv) != TCL_OK) {
return TCL_ERROR;
}
- when = 0;
for (i = 0; i < lobjc; ++i) {
if (Tcl_GetIndexFromObj(interp, lobjv[i], wopt, "when", 0,
--- 258,305 ----
int when, i;
static CONST char *wopt[] = {
! "read", "prewrite", "write", "prequeue", "preauth", "postauth", "trace", NULL
};
enum {
! ReadIdx, PreWriteIdx, WriteIdx, PreQueueIdx, PreAuthIdx, PostAuthIdx, TraceIdx,
} widx;
if (objc < 2) {
! error:
! Tcl_SetResult(interp, "wrong arguments: should be ns_register_filter "
! "?-insert? ?-priority num? when method url script ?arg?",
! TCL_STATIC);
return TCL_ERROR;
}
! when = 0;
! for (i = 1; i < objc; i++) {
! char *arg = Tcl_GetString(objv[i]);
! if (*arg != '-') break;
! if (STRIEQ(arg, "-insert")) {
! when |= NS_FILTER_INSERT;
! } else if (STRIEQ(arg, "-priority")) {
! if (++i >= objc) goto error;
! int prio;
! if (Tcl_GetIntFromObj(interp,objv[i],&prio) != TCL_OK) {
! return TCL_ERROR;
! }
! if (prio < -128 || prio > 127) {
! Tcl_SetResult(interp, "priority must be in range -128 .. 127",
! TCL_STATIC);
! return TCL_ERROR;
! }
! when |= NS_FILTER_PRIORITY(prio);
! } else {
! goto error;
! }
! }
! objc-=(i-1);
! objv+=(i-1);
!
! if (objc < 5 || objc > 6) {
! goto error;
}
if (Tcl_ListObjGetElements(interp, objv[1], &lobjc, &lobjv) != TCL_OK) {
return TCL_ERROR;
}
for (i = 0; i < lobjc; ++i) {
if (Tcl_GetIndexFromObj(interp, lobjv[i], wopt, "when", 0,
***************
*** 285,288 ****
--- 311,317 ----
when |= NS_FILTER_READ;
break;
+ case PreWriteIdx:
+ when |= NS_FILTER_PRE_WRITE;
+ break;
case WriteIdx:
when |= NS_FILTER_WRITE;
***************
*** 514,517 ****
--- 543,549 ----
Tcl_DStringAppendElement(&script, "read");
break;
+ case NS_FILTER_PRE_WRITE:
+ Tcl_DStringAppendElement(&script, "prewrite");
+ break;
case NS_FILTER_WRITE:
Tcl_DStringAppendElement(&script, "write");
Index: driver.c
===================================================================
RCS file: /cvsroot/aolserver/aolserver/nsd/driver.c,v
retrieving revision 1.62
retrieving revision 1.63
diff -C2 -d -r1.62 -r1.63
*** driver.c 9 Jul 2011 10:06:46 -0000 1.62
--- driver.c 11 Oct 2011 08:03:27 -0000 1.63
***************
*** 2326,2329 ****
--- 2326,2334 ----
Ns_SetFree(connPtr->outputheaders);
+ if (connPtr->rbuf != NULL) {
+ Tcl_DStringFree(connPtr->rbuf);
+ ns_free(connPtr->rbuf);
+ }
+
/*
* Truncate the I/O buffers, zero remaining elements of the Conn,
|