[AOLSERVER-COMMITS] knregistration/src knnewdelete.cpp, NONE, 1.1 knrcommon.cpp, NONE, 1.1 knregistration.cpp, NONE, 1.1 knrfiltermanager.cpp, NONE, 1.1 knrproceduremanager.cpp, NONE, 1.1 knrredirectmanager.cpp, NONE, 1.1 kntclapi.cpp, NONE, 1.1

0 views
Skip to first unread message

cob...@users.sourceforge.net

unread,
May 15, 2008, 8:37:43 PM5/15/08
to AOLSER...@listserv.aol.com
Update of /cvsroot/aolserver/knregistration/src
In directory sc8-pr-cvs11.sourceforge.net:/tmp/cvs-serv11750/src

Added Files:
knnewdelete.cpp knrcommon.cpp knregistration.cpp
knrfiltermanager.cpp knrproceduremanager.cpp
knrredirectmanager.cpp kntclapi.cpp
Log Message:
knregistration adds the ability to register procedures, filters, and indirects based on patterns in URIs. Matched portions of these URIs are added to the ns_conn "form" before delivery to the procedure, filter, or indirect request. Requires the knutil library.

--- NEW FILE: knnewdelete.cpp ---

/**
* (c) Copyright 2008 KnowNow, Inc., Sunnyvale CA
*
* @KNOWNOW_LICENSE_START@
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The name "KnowNow" is a trademark of KnowNow, Inc. and may not
* be used to endorse or promote any product without prior written
* permission from KnowNow, Inc.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL KNOWNOW, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @KNOWNOW_LICENSE_END@
**/
#define KNMODULE knregistration
#include "knutil/knnewdelete.h"

--- NEW FILE: knrcommon.cpp ---

/**
* (c) Copyright 2008 KnowNow, Inc., Sunnyvale CA
*
* @KNOWNOW_LICENSE_START@
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The name "KnowNow" is a trademark of KnowNow, Inc. and may not
* be used to endorse or promote any product without prior written
* permission from KnowNow, Inc.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL KNOWNOW, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @KNOWNOW_LICENSE_END@
**/
#include "knexportlibraryknregistrationmodule.h"
#include "knrcommon.h"

bool addQueryToConn(KnSet& toAdd, Ns_Conn* conn)
{
if(toAdd.size() == 0)
return false;

Ns_Set* query;

query = Ns_ConnGetQuery(conn);
if (query != NULL)
{
for(int i = 0; i < toAdd.size(); i++)
{
Ns_SetUpdate(query, (char*)toAdd[i].m_key.c_str(), (char*)toAdd[i].m_value.c_str());
}

return true;
}

return false;
}

bool removeQueryFromConn(KnSet& toRemove, Ns_Conn* conn)
{
if(toRemove.size() == 0)
return false;

Ns_Set* query;

query = Ns_ConnGetQuery(conn);
if (query != NULL)
{
for(int i = 0; i < toRemove.size(); i++)
{
Ns_SetDeleteKey(query, (char*)toRemove[i].m_key.c_str());
}

return true;
}

return false;
}
--- NEW FILE: knregistration.cpp ---
/**
* (c) Copyright 2008 KnowNow, Inc., Sunnyvale CA
*
* @KNOWNOW_LICENSE_START@
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The name "KnowNow" is a trademark of KnowNow, Inc. and may not
* be used to endorse or promote any product without prior written
* permission from KnowNow, Inc.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL KNOWNOW, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @KNOWNOW_LICENSE_END@
**/
#include <vector>
#include <list>
#include <map>

#include "knutil/knlog.h"
#include "knutil/knset.h"
#include "knutil/kntemplateuri.h"

#include "knexportlibraryknregistrationmodule.h"

#include "knregistration.h"
#include "knrfiltermanager.h"
#include "knrproceduremanager.h"
#include "knrredirectmanager.h"
#include "kntclapi.h"


static KnRFilterManager g_filterManager;
static KnRProcedureManager g_procManager;
static KnRRedirectManager g_redirectManager;

static const char* HttpMethods[] = { "GET", "HEAD", "PUT", "DELETE", "POST", "SUBSCRIBE"};
static const int HttpMethodsCount = 6;

int KnFilterRegistered(void* context, Ns_Conn* conn, int why)
{
// redirect
if(why == NS_FILTER_PRE_AUTH)
{
int result = g_redirectManager.redirect(context, conn);

if(result != NS_OK)
return result;
}

// filters
int result = g_filterManager.runFilters(context, conn, why);

if(result == NS_FILTER_RETURN)
return result;

// procedures
if(why == NS_FILTER_POST_AUTH)
{
return g_procManager.runProcedures(context, conn);
}

return result;
}


void KnRegisterProc(const char* server, const char* method, bool inheritable, const char* urlTemplate, KnRegisteredProc* proc, void* context)
{
if(strcmp(method,"*") != 0)
g_procManager.registerProc(new KnCRProcedureHandler(server,method,urlTemplate,inheritable,proc,context));
else
{
for(int i = 0; i < HttpMethodsCount; i++)
g_procManager.registerProc(new KnCRProcedureHandler(server,HttpMethods[i],urlTemplate,inheritable,proc,context));
}
}

void KnRegisterTclProc(const char* server, const char* method, bool inheritable, const char* urlTemplate, const char* proc ,const char* args)
{
if(strcmp(method,"*") != 0)
g_procManager.registerProc(new KnTclRProcedureHandler(server,method,urlTemplate,inheritable,proc,args));
else
{
for(int i = 0; i < HttpMethodsCount; i++)
g_procManager.registerProc(new KnTclRProcedureHandler(server,HttpMethods[i],urlTemplate,inheritable,proc,args));
}
}

void KnRegisterFilter(const char* server, const char* method, int why, const char* urlTemplate, KnRegisteredFilter* proc, void* context)
{
if(strcmp(method,"*") != 0)
g_filterManager.registerFilter(new KnCRFilterHandler(server,method,why,urlTemplate,proc,context));
else
{
for(int i = 0; i < HttpMethodsCount; i++)
g_filterManager.registerFilter(new KnCRFilterHandler(server,HttpMethods[i],why,urlTemplate,proc,context));
}
}

void KnRegisterTclFilter(const char* server, const char* method, int why, const char* urlTemplate, const char* proc, const char* args)
{
if(strcmp(method,"*") != 0)
g_filterManager.registerFilter(new KnTclRFilterHandler(server,method,why,urlTemplate,proc,args));
else
{
for(int i = 0; i < HttpMethodsCount; i++)
g_filterManager.registerFilter(new KnTclRFilterHandler(server,HttpMethods[i],why,urlTemplate,proc,args));
}
}

void KnRegisterRedirect(bool internal, const char* method, const char* urlTemplateFrom, const char* urlTemplateTo)
{
if(strcmp(method,"*") != 0)
g_redirectManager.addRedirect(new KnRRedirectInfo(internal, method, urlTemplateFrom, urlTemplateTo));
else
{
for(int i = 0; i < HttpMethodsCount; i++)
g_redirectManager.addRedirect(new KnRRedirectInfo(internal, HttpMethods[i], urlTemplateFrom, urlTemplateTo));
}
}

bool KnUnregisterProc(const char* server, const char* method, bool inheritable, const char* urlTemplate)
{
if(strcmp(method,"*") != 0)
return g_procManager.removeProcedure(server,method,inheritable,urlTemplate);

for(int i = 0; i < HttpMethodsCount; i++)
g_procManager.removeProcedure(server,HttpMethods[i],inheritable,urlTemplate);

return true;
}

bool KnUnregisterFilter(const char* server, const char* method, int why, const char* urlTemplate)
{
if(strcmp(method,"*") != 0)
return g_filterManager.removeFilter(server,method,why,urlTemplate);

for(int i = 0; i < HttpMethodsCount; i++)
return g_filterManager.removeFilter(server,HttpMethods[i],why,urlTemplate);

return true;
}

bool KnUnregisterRedirect(const char* method, const char* urlTemplateFrom)
{
if(strcmp(method,"*") != 0)
return g_redirectManager.removeRedirect(method, urlTemplateFrom);

for(int i = 0; i < HttpMethodsCount; i++)
return g_redirectManager.removeRedirect(HttpMethods[i], urlTemplateFrom);

return true;
}

extern "C"
{

EXPORT_LIBRARY_KNREGISTRATION int NsRegistration_ModuleInit(char *hServer, char *hModule)
{
KnLog(KnLogNotice, "knregistration: starting");
KnLog(KnLogNotice, "knregistration: build date: %s %s", __DATE__, __TIME__);

char filter_path[1024];

Ns_Set* config = NULL;
const char* nsp;

if ((nsp = Ns_ConfigGetPath(hServer, hModule, NULL)) == 0
|| (config = Ns_ConfigGetSection(const_cast<CONST char*>(nsp))) == 0)
{
KnLog(KnLogError, "knregistration: could not parse configuration");
return NS_ERROR;
}

KnString urlfilter;
urlfilter += "/*";
Ns_RegisterFilter(
hServer,
"*",
const_cast<char*>(urlfilter.c_str()),
KnFilterRegistered,
NS_FILTER_POST_AUTH | NS_FILTER_PRE_AUTH | NS_FILTER_TRACE
,NULL
);

// Export TCL commands
if (NS_OK != Ns_TclInitInterps(hServer, KnRegister_TclCommands::AddCmds, NULL))
{
KnLog( KnLogError, "knregistration: Couldn't add kn_ TCL commands to server '%s'", hServer);
return NS_ERROR;
}

KnLog(KnLogNotice, "knregistration: ready");

return NS_OK;
}
}

--- NEW FILE: knrfiltermanager.cpp ---
/**
* (c) Copyright 2008 KnowNow, Inc., Sunnyvale CA
*
* @KNOWNOW_LICENSE_START@
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The name "KnowNow" is a trademark of KnowNow, Inc. and may not
* be used to endorse or promote any product without prior written
* permission from KnowNow, Inc.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL KNOWNOW, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @KNOWNOW_LICENSE_END@
**/
#include "knexportlibraryknregistrationmodule.h"
#include "knrcommon.h"
#include "knrfiltermanager.h"

/* ------------------------------------------------------------------------- */
/* IKnRFilterHandler */
/* ------------------------------------------------------------------------- */

IKnRFilterHandler::IKnRFilterHandler(const char* server, const char* method, int why, const char* urlTemplate)
: m_server(server),m_method(method),m_why(why),m_urlTemplate(urlTemplate)
{
}

IKnRFilterHandler::~IKnRFilterHandler()
{
}

std::string IKnRFilterHandler::getID()
{
return m_server+':'+m_method+':'+(char)('a'+m_why);
}

std::string IKnRFilterHandler::getID(const char* server, const char* method, int why)
{
std::string result = server;
result += ":";
result += method;
result += ":";
result += (char)('a'+why);
return result;
}

/* ------------------------------------------------------------------------- */
/* KnCRFilterHandler */
/* ------------------------------------------------------------------------- */

KnCRFilterHandler::KnCRFilterHandler(const char* server, const char* method, int why, const char* urlTemplate, KnRegisteredFilter* proc, void* context)
: IKnRFilterHandler(server,method,why,urlTemplate),m_proc(proc),m_context(context)
{
}

int KnCRFilterHandler::handle(void *context, Ns_Conn *conn, int why)
{
return (*m_proc)(context,conn,why);
}

/* ------------------------------------------------------------------------- */
/* KnTclRFilterHandler */
/* ------------------------------------------------------------------------- */

KnTclRFilterHandler::KnTclRFilterHandler(const char* server, const char* method, int why, const char* urlTemplate, const char* proc, const char* args)
: IKnRFilterHandler(server,method,why,urlTemplate),m_proc(proc),m_args(args)
{
}

int KnTclRFilterHandler::handle(void *context, Ns_Conn *conn, int why)
{
std::string& command = m_proc;
command += " ";
command += m_args;
Tcl_Interp* interp = Ns_GetConnInterp(conn);

int status = Tcl_EvalEx(interp, const_cast<char*>(command.c_str()),command.length(),TCL_EVAL_DIRECT);
if (status != TCL_OK)
{
KnLog(KnLogError,"knregistration: Couldn't evaluate '%s': %s",command.c_str(), Tcl_GetStringResult(interp));
Ns_TclLogError(interp);
return NS_ERROR;
}

Tcl_Obj* result = Tcl_GetObjResult(interp);
if(result == TCL_OK)
{
int filterresult = NS_OK;
Tcl_GetIntFromObj(interp,result,&filterresult);

return filterresult;
}

return NS_ERROR;
}


/* ------------------------------------------------------------------------- */
/* KnRFilterManager */
/* ------------------------------------------------------------------------- */

void KnRFilterManager::registerFilter(IKnRFilterHandler* fh)
{
FinderType::ScopedWriteable sw(m_filterFinder);

KnString name(fh->m_urlTemplate.c_str());

m_filterFinder.put(
fh->getID(),
new KnTemplateURI(name, KnString(fh->m_urlTemplate.c_str())),
fh);
}

bool KnRFilterManager::removeFilter(const char* server, const char* method, int why, const char* urlTemplate)
{
FinderType::ScopedWriteable sw(m_filterFinder);

std::string id = IKnRFilterHandler::getID(server,method,why);

KnString name(urlTemplate);

return m_filterFinder.removeByName(id, name);
}

int KnRFilterManager::runFilters(void *context, Ns_Conn *conn, int why)
{
if(!m_filterFinder.size())
return NS_OK;

int ret = NS_OK;
std::string method = conn->request->method;
std::string url = conn->request->url;
std::string server = Ns_ConnServer(conn);
std::string id = IKnRFilterHandler::getID(server.c_str(),method.c_str(),why);

KNREGDBG(KnLog(KnLogDev,"ReC: knregistration: Looking for filter for url '%s' in set '%s'", url.c_str(), id.c_str()));
ResultType result;
{
FinderType::ScopedReadable sr(m_filterFinder);
if(! m_filterFinder.findAllMatchesSubs(id, url.c_str(), result))
return NS_OK;
}
KNREGDBG(KnLog(KnLogDev,"ReC: knregistration: Found %d filters that matched '%s'",
result.size(), url.c_str()));

bool added;
KnSet* matched;
int i;
for(i = 0; i < result.size(); i++)
{
matched = result[i].first;

if (KNREGDBG(KnLog(KnLogDev,"ReC: knregistration: Calling filter with set:")))
{
matched->dump(KnString("ReC: knregistration: "));
}

added = addQueryToConn(*matched, conn);

int filterresult = result[i].second->handle(context, conn, why);

if(added)
removeQueryFromConn(*matched, conn);

if((filterresult == NS_FILTER_BREAK)||(filterresult == NS_FILTER_RETURN))
{
ret = filterresult;
break;
}
}

for(i = 0 ; i < result.size() ; i++)
{
matched = result[i].first;
SAFE_DELETE(matched);
}

return ret;
}

--- NEW FILE: knrproceduremanager.cpp ---
/**
* (c) Copyright 2008 KnowNow, Inc., Sunnyvale CA
*
* @KNOWNOW_LICENSE_START@
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The name "KnowNow" is a trademark of KnowNow, Inc. and may not
* be used to endorse or promote any product without prior written
* permission from KnowNow, Inc.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL KNOWNOW, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @KNOWNOW_LICENSE_END@
**/
#include "knexportlibraryknregistrationmodule.h"
#include "knrcommon.h"
#include "knrproceduremanager.h"

/* ------------------------------------------------------------------------- */
/* IKnRProcedureHandler */
/* ------------------------------------------------------------------------- */

IKnRProcedureHandler::IKnRProcedureHandler(const char* server, const char* method, const char* urlTemplate, bool inheritable)
: m_server(server),m_method(method),m_urlTemplate(urlTemplate),m_inheritable(inheritable)
{
}

IKnRProcedureHandler::~IKnRProcedureHandler()
{
}

bool IKnRProcedureHandler::isInheritable()
{
return m_inheritable;
}

std::string IKnRProcedureHandler::getID()
{
return m_server+':'+m_method;
}

std::string IKnRProcedureHandler::getID(const char* server, const char* method)
{
std::string result = server;
result += ":";
result += method;

return result;
}

/* ------------------------------------------------------------------------- */
/* KnRProcedureInfo */
/* ------------------------------------------------------------------------- */


KnRProcedureInfo::KnRProcedureInfo()
{
m_inheritable = NULL;
m_exact = NULL;
}

KnRProcedureInfo::KnRProcedureInfo(IKnRProcedureHandler* ph)
{
m_inheritable = NULL;
m_exact = NULL;
set(ph);
}

KnRProcedureInfo::~KnRProcedureInfo()
{
SAFE_DELETE(m_inheritable);
SAFE_DELETE(m_exact);
}

bool KnRProcedureInfo::hasInheritable()
{
return m_inheritable != NULL;
}

bool KnRProcedureInfo::hasExact()
{
return m_exact != NULL;
}

bool KnRProcedureInfo::removeHandler(bool inheritable)
{
if(inheritable && hasInheritable())
{
SAFE_DELETE(m_inheritable);
return true;
}

if(!inheritable && hasExact())
{
SAFE_DELETE(m_exact);
return true;
}

return false;
}

int KnRProcedureInfo::handle(void* context, Ns_Conn* conn)
{
return m_exact->handle(context,conn);
}

int KnRProcedureInfo::handleInheritable(void* context, Ns_Conn* conn)
{
return m_inheritable->handle(context,conn);
}

void KnRProcedureInfo::set(IKnRProcedureHandler* ph)
{
if(ph->isInheritable())
{
SAFE_DELETE(m_inheritable);
m_inheritable = ph;
}else
{
SAFE_DELETE(m_exact);
m_exact = ph;
}
}


/* ------------------------------------------------------------------------- */
/* KnCRProcedureHandler */
/* ------------------------------------------------------------------------- */

KnCRProcedureHandler::KnCRProcedureHandler(const char* server, const char* method, const char* urlTemplate, bool inheritable, KnRegisteredProc* proc, void* context)
: IKnRProcedureHandler( server, method, urlTemplate,inheritable)
{
m_proc = proc;
m_context = context;
}

int KnCRProcedureHandler::handle(void* context, Ns_Conn* conn)
{
return (*m_proc)(context,conn);
}

/* ------------------------------------------------------------------------- */
/* KnTclRProcedureHandler */
/* ------------------------------------------------------------------------- */


KnTclRProcedureHandler::KnTclRProcedureHandler(const char* server, const char* method, const char* urlTemplate, bool inheritable, const char* proc, const char* args)
: IKnRProcedureHandler(server,method,urlTemplate,inheritable)
{
m_proc = proc;
m_args = args;
}

int KnTclRProcedureHandler::handle(void* context, Ns_Conn* conn)
{
Tcl_Interp *interp = Ns_GetConnInterp(conn);
int result;

std::string command;

command += m_proc;

int id = Ns_ConnId(conn);

char buffer[30];
sprintf(buffer,"cns%d",id);

command += ' ';
command += buffer;
command += m_args;

result = Tcl_EvalEx(interp, (char*)command.c_str(), command.size(), 0);

if (result != TCL_OK)
{
Ns_TclLogError(interp);
if (Ns_ConnResetReturn(conn) == NS_OK)
return Ns_ConnReturnInternalError(conn);

return NS_OK;
}

return NS_OK;
}

/* ------------------------------------------------------------------------- */
/* KnRProcedureManager */
/* ------------------------------------------------------------------------- */

void KnRProcedureManager::registerProc(IKnRProcedureHandler* ph)
{
FinderType::ScopedWriteable sw(m_procFinder);

std::string id = ph->getID();
KnString name(ph->m_urlTemplate.c_str());

KnSmartRef<KnTemplateURI> temp;
KnSmartRef<KnRProcedureInfo> info;

if(m_procFinder.findByName(id, name, temp, info))
info->set(ph);
else
{
m_procFinder.put(
id,
new KnTemplateURI(name, KnString(ph->m_urlTemplate.c_str())),
new KnRProcedureInfo(ph)
);
}
}

bool KnRProcedureManager::removeProcedure(const char* server, const char* method, bool inheritable, const char* urlTemplate)
{
FinderType::ScopedWriteable sw(m_procFinder);

std::string id = IKnRProcedureHandler::getID(server,method);
KnString name(urlTemplate);

KnSmartRef<KnTemplateURI> temp;
KnSmartRef<KnRProcedureInfo> info;

if(m_procFinder.findByName(id, name, temp, info))
{
if(info->removeHandler(inheritable))
{
if(!(info->hasExact() || info->hasInheritable()))
return m_procFinder.removeByName(id, name);

return true;
}
}

return false;
}

int KnRProcedureManager::runProcedures(void* context, Ns_Conn* conn)
{
if(!m_procFinder.size())
return NS_OK;

int ret = NS_OK; // respond as a filter
std::string method = conn->request->method;
std::string url = conn->request->url;
std::string server = Ns_ConnServer(conn);
std::string id = IKnRProcedureHandler::getID(server.c_str(),method.c_str());

KNREGDBG(KnLog(KnLogDev,"ReC: knregistration: Looking for procedure for url '%s' in set '%s'", url.c_str(), id.c_str()));
ResultType result;
{
FinderType::ScopedReadable sr(m_procFinder);
if(! m_procFinder.findAllMatchesSubs(id, url.c_str(), result))
return ret;
}
KNREGDBG(KnLog(KnLogDev,"ReC: knregistration: %d candidates for url '%s'", result.size(), url.c_str()));

KnSet* matched;

int exactPos;
bool hasExact = false;
for(exactPos = 0; exactPos < result.size(); exactPos++)
{
if(result[exactPos].second->hasExact())
{
hasExact = true;
break;
}
}

bool added;

int i;
if(hasExact)
{
for(i = result.size()-1 ; i > exactPos; i--)
{
if(!result[i].second->hasInheritable())
continue;

matched = result[i].first;

if (KNREGDBG(KnLog(KnLogDev,"ReC: knregistration: calling inherited procedure using set:")))
{
matched->dump(KnString("ReC: knregistration: "));
}

added = addQueryToConn(*matched, conn);

result[i].second->handleInheritable(context, conn);

if(added)
removeQueryFromConn(*matched, conn);
}

matched = result[exactPos].first;

if (KNREGDBG(KnLog(KnLogDev,"ReC: knregistration: calling exact-match procedure using set:")))
{
matched->dump(KnString("ReC: knregistration: "));
}

added = addQueryToConn(*matched, conn);

result[exactPos].second->handle(context, conn);
ret = NS_FILTER_RETURN;

if(added)
removeQueryFromConn(*matched, conn);
}else
{
for(i = result.size()-1 ; i >= 0; i--)
{
if(!result[i].second->hasInheritable())
continue;

matched = result[i].first;

if (KNREGDBG(KnLog(KnLogDev,"ReC: knregistration: calling inherited procedure using set:")))
{
matched->dump(KnString("ReC: knregistration: "));
}

added = addQueryToConn(*matched, conn);

result[i].second->handleInheritable(context, conn);

if(added)
removeQueryFromConn(*matched, conn);
}
}


for(i = 0 ; i < result.size() ; i++)
{
matched = result[i].first;
SAFE_DELETE(matched);
}

return ret;
}

--- NEW FILE: knrredirectmanager.cpp ---

/**
* (c) Copyright 2008 KnowNow, Inc., Sunnyvale CA
*
* @KNOWNOW_LICENSE_START@
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The name "KnowNow" is a trademark of KnowNow, Inc. and may not
* be used to endorse or promote any product without prior written
* permission from KnowNow, Inc.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL KNOWNOW, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @KNOWNOW_LICENSE_END@
**/
#include "knexportlibraryknregistrationmodule.h"
#include "knrcommon.h"
#include "knrredirectmanager.h"

/* ------------------------------------------------------------------------- */
/* Utility */
/* ------------------------------------------------------------------------- */

void createExternalRedirectUrl(Ns_Conn* conn, const std::string& toUrl, std::string& url)
{
url = "";

if(toUrl[0] == '/')
{
Ns_DString ds;
Ns_DStringInit(&ds);
char* location = Ns_ConnLocation(conn, &ds);
if(location)
url += location;
Ns_DStringFree(&ds);
}

url += toUrl;
}

/* ------------------------------------------------------------------------- */
/* KnRRedirectInfo */
/* ------------------------------------------------------------------------- */


KnRRedirectInfo::KnRRedirectInfo(bool internal, const char* method, const char* urlTemplateFrom, const char* urlTemplateTo)
:m_internal(internal),m_method(method),m_urlTemplateFrom(urlTemplateFrom),m_urlTemplateTo(urlTemplateTo)
{
}

/* ------------------------------------------------------------------------- */
/* KnRRedirectManager */
/* ------------------------------------------------------------------------- */


KnRRedirectManager::KnRRedirectManager()
{
}

KnRRedirectManager::~KnRRedirectManager()
{
}

void KnRRedirectManager::addRedirect(KnRRedirectInfo* ri)
{
FinderType::ScopedWriteable sw(m_redirectFinder);

KnString name;
name.printf("%s%s",ri->m_method.c_str(), ri->m_urlTemplateFrom.c_str());
KnTemplateURI* tempuri = new KnTemplateURI(name, KnString(ri->m_urlTemplateFrom.c_str()));

m_redirectFinder.put(ri->m_method, tempuri, ri);
}

bool KnRRedirectManager::removeRedirect(const char* method, const char* urlTemplateFrom)
{
FinderType::ScopedWriteable sw(m_redirectFinder);

KnString name;
std::string m = method;
name.printf("%s%s",method, urlTemplateFrom);

return m_redirectFinder.removeByName(m, name);
}

int KnRRedirectManager::redirect(void* context, Ns_Conn* conn)
{
if(!m_redirectFinder.size())
return NS_OK;

KnSet matched;
std::string url = (conn->request->url? conn->request->url : "");
std::string method = conn->request->method;

KnSmartRef<KnTemplateURI> pattern;
KnSmartRef<KnRRedirectInfo> ri;

std::string newUrl;

{
FinderType::ScopedReadable sr(m_redirectFinder);

bool found = m_redirectFinder.findBestMatchSubs(method, url.c_str(), matched, pattern, ri);

if(!found)
return NS_OK;
}

//KnLog(KnLogDebug,"Chose pattern [%s] for redirecting url [%s] from pattern list:",ri->m_urlTemplateFrom.c_str(), url.c_str());
//m_redirectFinder.dump(method, KnLogDebug);

std::string redirectTo;
bool valid = KnTemplateURI::replaceInto(matched, ri->m_urlTemplateTo.c_str(), redirectTo, true);

if(!valid)
{
KnLog(KnLogNotice, "Invalid redirect translation from [%s] to [%s]", ri->m_urlTemplateFrom.c_str(), ri->m_urlTemplateTo.c_str());
return NS_OK;
}

newUrl = redirectTo;

if(ri->m_internal)
{
addQueryToConn(matched, conn);
// Url rewrite
Ns_ConnRedirect(conn, (char*)newUrl.c_str());
}else
{
createExternalRedirectUrl(conn, redirectTo, newUrl);

addQueryToConn(matched, conn);
// External redirect
Ns_ConnReturnRedirect(conn, (char*)newUrl.c_str());
}

return NS_FILTER_RETURN;
}


--- NEW FILE: kntclapi.cpp ---
/**
* (c) Copyright 2008 KnowNow, Inc., Sunnyvale CA
*
* @KNOWNOW_LICENSE_START@
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The name "KnowNow" is a trademark of KnowNow, Inc. and may not
* be used to endorse or promote any product without prior written
* permission from KnowNow, Inc.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL KNOWNOW, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @KNOWNOW_LICENSE_END@
**/
#include "knutil/knstring.h"
#include "knutil/knset.h"
#include "knutil/knstringtokenizer.h"
#include "knutil/kntclinterp.h"
#include "knutil/kntclerrors.h"

#include "knexportlibraryknregistrationmodule.h"
#include "knregistration.h"

namespace KnRegister_TclCommands
{

extern "C"
{

int
kn_registerproc (
void * context,
Tcl_Interp* interp,
int objc,
Tcl_Obj * objv[])
{
if (objc < 4)
{
KnTcl_WrongNumArgs(interp,3,objv,"string");
return TCL_ERROR;
}

bool inheritable = false;
int index = 1;
char* elem = (Tcl_GetString(objv[index]));

if(strcasecmp(elem,"-noinherit") == 0)
{
index++;
inheritable = false;
}else
if(strcasecmp(elem,"-inherit") == 0)
{
index++;
inheritable = true;
}

char* method(Tcl_GetString(objv[index++]));
char* url(Tcl_GetString(objv[index++]));
char* proc(Tcl_GetString(objv[index++]));

std::string args;

for(int i = index; i < objc; i++)
{
args += " {";
args += Tcl_GetString(objv[i]);
args += "}";
}

KnRegisterTclProc(Ns_TclInterpServer(interp), method, inheritable, url, proc, args.c_str());

return TCL_OK;
}

int
kn_registerfilter (
void * context,
Tcl_Interp* interp,
int objc,
Tcl_Obj * objv[])
{
if (objc < 5)
{
KnTcl_WrongNumArgs(interp,4,objv,"string");
return TCL_ERROR;
}

int index = 1;
char* server = Ns_TclInterpServer(interp);
char* type(Tcl_GetString(objv[index++]));
char* method(Tcl_GetString(objv[index++]));
char* url(Tcl_GetString(objv[index++]));
char* proc(Tcl_GetString(objv[index++]));

std::string args;

for(int i = 5; i < objc; i++)
{
args += " {";
args += Tcl_GetString(objv[i]);
args += "}";
}

int filterType;

if(strcasecmp(type,"-preauth") == 0)
filterType = NS_FILTER_PRE_AUTH;
else
if(strcasecmp(type,"-postauth") == 0)
filterType = NS_FILTER_POST_AUTH;
else
if(strcasecmp(type,"-trace") == 0)
filterType = NS_FILTER_TRACE;
else
{
Tcl_AppendResult(interp,"500 Unknown type for filter: '",type,"'",0);
return TCL_ERROR;
}

KnRegisterTclFilter(server, method, filterType, url, proc, args.c_str());

return TCL_OK;
}


int
kn_registerredirect (
void * context,
Tcl_Interp* interp,
int objc,
Tcl_Obj * objv[])
{
if (objc < 5)
{
KnTcl_WrongNumArgs(interp,4,objv,"string");
return TCL_ERROR;
}

int index = 1;
char* type(Tcl_GetString(objv[index++]));
char* method(Tcl_GetString(objv[index++]));
char* template1(Tcl_GetString(objv[index++]));
char* template2(Tcl_GetString(objv[index++]));

if(strcasecmp(type,"-internal") == 0)
KnRegisterRedirect(true, method, template1, template2);
else
if(strcasecmp(type,"-external") == 0)
KnRegisterRedirect(false, method, template1, template2);
else
{
Tcl_AppendResult(interp,"500 Unknown type of redirect: '",type,"'",0);
return TCL_ERROR;
}

return TCL_OK;
}

int
kn_unregister (
void * context,
Tcl_Interp* interp,
int objc,
Tcl_Obj * objv[])
{
if (objc < 4)
{
KnTcl_WrongNumArgs(interp,1,objv,"string");
return TCL_ERROR;
}

char* type(Tcl_GetString(objv[1]));

bool success;
if(strcasecmp(type,"-redirect") == 0)
{
char* method(Tcl_GetString(objv[2]));
char* from(Tcl_GetString(objv[3]));
success = KnUnregisterRedirect(method,from);
}
else
if(strcasecmp(type,"-filter") == 0)
{
char* why(Tcl_GetString(objv[4]));
char* method(Tcl_GetString(objv[2]));
char* temp(Tcl_GetString(objv[3]));
success = KnUnregisterFilter(Ns_TclInterpServer(interp),method,atoi(why),temp);
}
else
if(strcasecmp(type,"-proc") == 0)
{
char* what(Tcl_GetString(objv[4]));
char* method(Tcl_GetString(objv[2]));
char* temp(Tcl_GetString(objv[3]));

bool inheritable = true;
if(strcasecmp(what,"-noinherit"))
inheritable = false;
success = KnUnregisterProc(Ns_TclInterpServer(interp),method,inheritable,temp);
}
else
{
Tcl_AppendResult(interp,"500 Unknown type of unregister: '",type,"'",0);
return TCL_ERROR;
}

Tcl_Obj *result = Tcl_NewBooleanObj(success);
Tcl_SetObjResult(interp,result);
return TCL_OK ;
}

} // extern "C"


int AddCmds(Tcl_Interp *nsInterp, void *context)
{
Tcl_CreateObjCommand(nsInterp,
"kn_registerproc", kn_registerproc, context, NULL);

Tcl_CreateObjCommand(nsInterp,
"kn_registerfilter", kn_registerfilter, context, NULL);

Tcl_CreateObjCommand(nsInterp,
"kn_registerredirect", kn_registerredirect, context, NULL);

Tcl_CreateObjCommand(nsInterp,
"kn_unregister", kn_unregister, context, NULL);

return 0;
}
}


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
aolserver-commits mailing list
aolserve...@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/aolserver-commits

Reply all
Reply to author
Forward
0 new messages