Skip to content

Commit

Permalink
Some fixes. Explicitely prevent loading a plugin more than once
Browse files Browse the repository at this point in the history
Changed the cfg file directive
  • Loading branch information
ffurano committed Oct 17, 2017
1 parent 12b18e0 commit 6b5c065
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 22 deletions.
90 changes: 70 additions & 20 deletions src/XrdHttp/XrdHttpProtocol.cc
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ SSL_CTX *XrdHttpProtocol::sslctx = 0;
BIO *XrdHttpProtocol::sslbio_err = 0;
XrdCryptoFactory *XrdHttpProtocol::myCryptoFactory = 0;
XrdHttpSecXtractor *XrdHttpProtocol::secxtractor = 0;
std::vector<XrdHttpExtHandler *> XrdHttpProtocol::exthandler;
struct XrdHttpProtocol::XrdHttpExtHandlerInfo XrdHttpProtocol::exthandler[MAX_XRDHTTPEXTHANDLERS];
int XrdHttpProtocol::exthandlercnt = 0;
std::map< std::string, std::string > XrdHttpProtocol::hdr2cgimap;

static const unsigned char *s_server_session_id_context = (const unsigned char *) "XrdHTTPSessionCtx";
Expand Down Expand Up @@ -2191,35 +2192,55 @@ int XrdHttpProtocol::xsecxtractor(XrdOucStream & Config) {

/* Function: xexthandler
*
* Purpose: To parse the directive: exthandler <path> <initparm>
* Purpose: To parse the directive: exthandler <name> <path> <initparm>
*
* <name> a unique name (max 16chars) to be given to this
* instance, e.g 'myhandler1'
* <path> the path of the plugin to be loaded
* <initparm> a string parameter (e.g. a config file) that is
* passed to the initialization of the plugin
*
* Output: 0 upon success or !0 upon failure.
*/

int XrdHttpProtocol::xexthandler(XrdOucStream & Config, const char *ConfigFN, XrdOucEnv *myEnv) {
char *val, valbuf[1024];
int XrdHttpProtocol::xexthandler(XrdOucStream & Config, const char *ConfigFN,
XrdOucEnv *myEnv) {
char *val, path[1024], namebuf[1024];
char *parm;

// Get the name
//
val = Config.GetWord();
if (!val || !val[0]) {
eDest.Emsg("Config", "No instance name specified for an http external handler plugin .");
return 1;
}
if (strlen(val) >= 16) {
eDest.Emsg("Config", "Instance name too long for an http external handler plugin .");
return 1;
}
strncpy(namebuf, val, sizeof(namebuf));
namebuf[ sizeof(namebuf)-1 ] = '\0';

// Get the path
//
val = Config.GetWord();
if (!val || !val[0]) {
eDest.Emsg("Config", "No http external handler plugin specified.");
return 1;
} else {
strcpy(valbuf, val);
parm = Config.GetWord();
}
strcpy(path, val);

// Everything else is a free string
//
parm = Config.GetWord();

// Try to load the plugin (if available) that extracts info from the user cert/proxy
//
if (LoadExtHandler(&eDest, valbuf, ConfigFN, parm, myEnv))
return 1;
}

// Try to load the plugin implementing ext behaviour
//
if (LoadExtHandler(&eDest, path, ConfigFN, parm, myEnv, namebuf))
return 1;


return 0;
}
Expand Down Expand Up @@ -2435,7 +2456,18 @@ int XrdHttpProtocol::LoadSecXtractor(XrdSysError *myeDest, const char *libName,
// Loads the external handler plugin, if available
int XrdHttpProtocol::LoadExtHandler(XrdSysError *myeDest, const char *libName,
const char *configFN, const char *libParms,
XrdOucEnv *myEnv) {
XrdOucEnv *myEnv, const char *instName) {


// This function will avoid loading doubles. No idea why this happens
if (ExtHandlerLoaded(instName)) {
eDest.Emsg("Config", "Instance name already present for an http external handler plugin.");
return 1;
}
if (exthandlercnt >= MAX_XRDHTTPEXTHANDLERS) {
eDest.Emsg("Config", "Cannot load one more exthandler. Max is 4");
return 1;
}

XrdVersionInfo *myVer = &XrdVERSIONINFOVAR(XrdgetProtocol);
XrdOucPinLoader myLib(myeDest, myVer, "exthandlerlib", libName);
Expand All @@ -2447,7 +2479,12 @@ int XrdHttpProtocol::LoadExtHandler(XrdSysError *myeDest, const char *libName,

XrdHttpExtHandler *newhandler;
if (ep && (newhandler = ep(myeDest, configFN, libParms, myEnv))) {
exthandler.push_back(newhandler);

// Handler has been loaded, it's the last one in the list
strncpy( exthandler[exthandlercnt].name, instName, 16 );
exthandler[exthandlercnt].name[15] = '\0';
exthandler[exthandlercnt++].ptr = newhandler;

return 0;
}

Expand All @@ -2456,13 +2493,26 @@ int XrdHttpProtocol::LoadExtHandler(XrdSysError *myeDest, const char *libName,
}


// Locates a matching external handler for a given request, if available

// Tells if we have already loaded a certain exthandler. Try to
// privilege speed, as this func may be invoked pretty often
bool XrdHttpProtocol::ExtHandlerLoaded(const char *handlername) {
for (int i = 0; i < exthandlercnt; i++) {
if ( !strncmp(exthandler[i].name, handlername, 15) ) {
return true;
}
}
return false;
}

// Locates a matching external handler for a given request, if available. Try to
// privilege speed, as this func is invoked for every incoming request
XrdHttpExtHandler * XrdHttpProtocol::FindMatchingExtHandler(const XrdHttpReq &req) {
std::vector<XrdHttpExtHandler *>::const_iterator it;
for (it = exthandler.begin(); it != exthandler.end(); it++) {
if ((*it)->MatchesPath(req.requestverb.c_str(), req.resource.c_str())) {
return *it;

for (int i = 0; i < exthandlercnt; i++) {
if (exthandler[i].ptr->MatchesPath(req.requestverb.c_str(), req.resource.c_str())) {
return exthandler[i].ptr;
}
}
return nullptr;
return NULL;
}
14 changes: 12 additions & 2 deletions src/XrdHttp/XrdHttpProtocol.hh
Original file line number Diff line number Diff line change
Expand Up @@ -172,23 +172,33 @@ private:
static int xheader2cgi(XrdOucStream &Config);

static XrdHttpSecXtractor *secxtractor;
static std::vector<XrdHttpExtHandler *> exthandler;

// Loads the SecXtractor plugin, if available
static int LoadSecXtractor(XrdSysError *eDest, const char *libName,
const char *libParms);

// An oldstyle struct array to hold exthandlers
#define MAX_XRDHTTPEXTHANDLERS 4
static struct XrdHttpExtHandlerInfo {
char name[16];
XrdHttpExtHandler *ptr;
} exthandler[MAX_XRDHTTPEXTHANDLERS];
static int exthandlercnt;

// Loads the ExtHandler plugin, if available
static int LoadExtHandler(XrdSysError *eDest, const char *libName,
const char *configFN, const char *libParms,
XrdOucEnv *myEnv);
XrdOucEnv *myEnv, const char *instName);

// Determines whether one of the loaded ExtHandlers are interested in
// handling a given request.
//
// Returns NULL if there is no matching handler.
static XrdHttpExtHandler *FindMatchingExtHandler(const XrdHttpReq &);

// Tells if an ext handler with the given name has already been loaded
static bool ExtHandlerLoaded(const char *handlername);

/// Circular Buffer used to read the request
XrdBuffer *myBuff;
/// The circular pointers
Expand Down

0 comments on commit 6b5c065

Please sign in to comment.