I would like to use mechanisms available in AOLserver (nsd/urlspace.c, nsd/op.c) to define different handlers for different parts of URL tree. I am particulary interested in: - directory aliases (see: http://aolserver.com/docs/cdev/c-app2.htm#14874) - TCL registered procs - registered ADP (see my TCL command ns_adp_registeradp in AOLserver 4.0)
I would like to use these mechanisms to allow independent TCL modules to handle parts of URL tree. During request handling I would like to identify which TCL module handles which url (exactly which instance of given module). The problem is well described in documentation for ACS Request Processor, but there they speak about packages and package instances (http://developer.arsdigita.com/doc/request-processor). My solution is to add another field to Ns_Conn structure which will be initialized during request handling to url pattern used to register the handler. That url pattern (combined with [ns_conn server] and [ns_conn method]) identifies the handler so I would make it accessible from TCL by [ns_conn handler]. I suspect that this extention could be usefull for other purposes as well. I would like to get advise for the following: 1) Could my problem be solved without patching AOLserver? 2) Does proposed extention seem usefull for anyone? 3) Is there better proposal for implementing that functionality in C? 4) Would my patch be included in AOLserver core ? Below is my understanding of how AOLserver handles incoming request and what should be changed. --- Details --- AOlserver uses special data structure defined in nsd/urlspace.c to keep information how to handle incoming request. You can access this structure using functions like: void Ns_UrlSpecificSet(char *server, char *method, char *url, int id, void *data, int flags, void (*deletefunc) (void *)) void * Ns_UrlSpecificGet(char *server, char *method, char *url, int id) which allow you to set and retrive data given: - server: eg. server1 - method: eg. GET/HEAD/POST - url pattern: eg. *.adp, /myproc, /mytree/* Their primary usage is to define how aolserver should handle incoming HTTP requests. This is done by reqistering request handlers: - FastGet for static files, - AdpRun for ADP pages - TclDoOp for TCL registered procs (and ADP pages in AOL 4.0). // nsd/fastpath.c Ns_RegisterRequest(server, "GET", "/", FastGet, NULL, NULL, 0); Ns_RegisterRequest(server, "HEAD", "/", FastGet, NULL, NULL, 0); Ns_RegisterRequest(server, "POST", "/", FastGet, NULL, NULL, 0); // nsd/adp.c Ns_RegisterRequest(server, "GET", map, AdpProc, NULL, NULL, 0); Ns_RegisterRequest(server, "HEAD", map, AdpProc, NULL,NULL, 0); Ns_RegisterRequest(server, "POST", map, AdpProc, NULL,NULL, 0); You can register, get and unregister request handler using the following procs defined in nsd/op.c: void Ns_RegisterRequest(char *server, char *method, char *url, Ns_OpProc *procPtr, Ns_Callback *deleteProcPtr, void *arg, int flags) void Ns_UnRegisterRequest(char *server, char *method, char *url, int inherit) void Ns_GetRequest(char *server, char *method, char *url, Ns_OpProc **procPtrPtr, Ns_Callback **deleteProcPtrPtr, void **argPtr, int *flagsPtr) Notice that Ns_GetRequest is never used in AOLserver core! Its interface have to be changed in my proposal. Probably the best soultion is to add Ns_GetRequest2. $ grep Ns_GetRequest aolserver-3.4/nsd/* aolserver-3.4/nsd/op.c: * Ns_GetRequest -- aolserver-3.4/nsd/op.c:Ns_GetRequest(char *server, char *method, char *url, Ns_OpProc **procPtrPtr, Incoming request is handled by function Ns_ConnRunRequest (defined in nsd/op.c) which runs one of registered request handlers. int Ns_ConnRunRequest(Ns_Conn *conn) { Req *reqPtr; int status; char *server = Ns_ConnServer(conn); reqPtr = (Req *) Ns_UrlSpecificGet(server, conn->request->method, conn->request->url, reqId); if (reqPtr == NULL) { status = Ns_ConnReturnNotFound(conn); } else { status = (*reqPtr->procPtr) (reqPtr->arg, conn); } return status; } I propose to add to Req and Ns_Conn definition filed: char* handler; Req.handler should be initialized in Ns_RegisterRequest to parameter url so it could be used in Ns_ConnRunRequest to initialize Ns_Conn.handler in the following way: if (reqPtr == NULL) { status = Ns_ConnReturnNotFound(conn); } else { // I assume that Req structure won't be freed during request handling conn->handler = reqPtr->handler; status = (*reqPtr->procPtr) (reqPtr->arg, conn); } Maybe it's better to ns_strdup(reqPtr->handler) and to free it later in NsConnThread in nsd/serv.c. What do you think? --tkosiak
