Skip to content

Commit

Permalink
Implement staticpreload and staticredir to handle in-memory
Browse files Browse the repository at this point in the history
and off-site custom static content also with third-party
n2n translator (like Rucio or LFC)
  • Loading branch information
ffurano committed May 5, 2014
1 parent 3117adc commit d680aed
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 20 deletions.
111 changes: 111 additions & 0 deletions src/XrdHttp/XrdHttpProtocol.cc
Expand Up @@ -74,6 +74,9 @@ char *XrdHttpProtocol::sslcadir = 0;
char *XrdHttpProtocol::listredir = 0;
bool XrdHttpProtocol::listdeny = false;
bool XrdHttpProtocol::embeddedstatic = true;
char *XrdHttpProtocol::staticredir = 0;
XrdOucHash<XrdHttpProtocol::StaticPreloadInfo> *XrdHttpProtocol::staticpreload = 0;

kXR_int32 XrdHttpProtocol::myRole = kXR_isManager;
bool XrdHttpProtocol::selfhttps2http = false;
bool XrdHttpProtocol::isdesthttps = false;
Expand Down Expand Up @@ -710,6 +713,8 @@ int XrdHttpProtocol::Config(const char *ConfigFN) {
else if TS_Xeq("selfhttps2http", xselfhttps2http);
else if TS_Xeq("embeddedstatic", xembeddedstatic);
else if TS_Xeq("listingredir", xlistredir);
else if TS_Xeq("staticredir", xstaticredir);
else if TS_Xeq("staticpreload", xstaticpreload);
else if TS_Xeq("listingdeny", xlistdeny);
else {
eDest.Say("Config warning: ignoring unknown directive '", var, "'.");
Expand Down Expand Up @@ -1871,6 +1876,112 @@ int XrdHttpProtocol::xembeddedstatic(XrdOucStream & Config) {



/******************************************************************************/
/* x r e d i r s t a t i c */
/******************************************************************************/

/* Function: xstaticredir
Purpose: To parse the directive: staticredir <Url>
<Url> http/https server to redirect to in the case of /static
Output: 0 upon success or !0 upon failure.
*/

int XrdHttpProtocol::xstaticredir(XrdOucStream & Config) {
char *val;

// Get the path
//
val = Config.GetWord();
if (!val || !val[0]) {
eDest.Emsg("Config", "staticredir url not specified");
return 1;
}

// Record the value
//
if (staticredir) free(staticredir);
staticredir = strdup(val);

return 0;
}


/******************************************************************************/
/* x p r e l o a d s t a t i c */
/******************************************************************************/

/* Function: xpreloadstatic
Purpose: To parse the directive: preloadstatic <http url path> <local file>
<http url path> http/http path whose response we are preloading
e.g. /static/mycss.css
NOTE: this must start with /static
Output: 0 upon success or !0 upon failure.
*/

int XrdHttpProtocol::xstaticpreload(XrdOucStream & Config) {
char *val, *k, key[1024];

// Get the key
//
k = Config.GetWord();
if (!k || !k[0]) {
eDest.Emsg("Config", "preloadstatic urlpath not specified");
return 1;
}

strcpy(key, k);

// Get the val
//
val = Config.GetWord();
if (!val || !val[0]) {
eDest.Emsg("Config", "preloadstatic filename not specified");
return 1;
}

// Try to load the file into memory
int fp = open(val, O_RDONLY);
if( fp < 0 ) {
eDest.Emsg("Config", "Cannot open preloadstatic filename '", val, "'");
eDest.Emsg("Config", "Cannot open preloadstatic filename. err: ", strerror(errno));
return 1;
}

StaticPreloadInfo *nfo = new StaticPreloadInfo;
// Max 64Kb ok?
nfo->data = (char *)malloc(65536);
nfo->len = read(fp, (void *)nfo->data, 65536);
close(fp);

if (nfo->len <= 0) {
eDest.Emsg("Config", "Cannot read from preloadstatic filename '", val, "'");
eDest.Emsg("Config", "Cannot read from preloadstatic filename. err: ", strerror(errno));
return 1;
}

if (nfo->len >= 65536) {
eDest.Emsg("Config", "Truncated preloadstatic filename. Max is 64 KB '", val, "'");
return 1;
}

// Record the value
//
if (!staticpreload)
staticpreload = new XrdOucHash<StaticPreloadInfo>;

staticpreload->Rep((const char *)key, nfo);
return 0;
}




/******************************************************************************/
/* x s e l f h t t p s 2 h t t p */
Expand Down
14 changes: 13 additions & 1 deletion src/XrdHttp/XrdHttpProtocol.hh
Expand Up @@ -46,6 +46,7 @@
#include "XrdXrootd/XrdXrootdBridge.hh"
#include "XrdOuc/XrdOucStream.hh"
#include "Xrd/XrdProtocol.hh"
#include "XrdOuc/XrdOucHash.hh"

#include <openssl/ssl.h>

Expand Down Expand Up @@ -160,6 +161,8 @@ private:
static int xlistredir(XrdOucStream &Config);
static int xselfhttps2http(XrdOucStream &Config);
static int xembeddedstatic(XrdOucStream &Config);
static int xstaticredir(XrdOucStream &Config);
static int xstaticpreload(XrdOucStream &Config);
static int xsslcafile(XrdOucStream &Config);
static int xsslverifydepth(XrdOucStream &Config);
static int xsecretkey(XrdOucStream &Config);
Expand Down Expand Up @@ -309,7 +312,16 @@ protected:
/// If true, use the embedded css and icons
static bool embeddedstatic;


// Url to redirect to in the case a /static is requested
static char *staticredir;

// Hash that keeps preloaded files
struct StaticPreloadInfo {
char *data;
int len;
};
static XrdOucHash<StaticPreloadInfo> *staticpreload;

/// Our role
static kXR_int32 myRole;

Expand Down
71 changes: 53 additions & 18 deletions src/XrdHttp/XrdHttpReq.cc
Expand Up @@ -682,28 +682,63 @@ int XrdHttpReq::ProcessHTTPReq() {
case XrdHttpReq::rtGET:
{

if (prot->embeddedstatic && resource.beginswith("/static/")) {
// This is a request for an embedded static resource
// The sysadmin can always use the file system if he wants to put his own.
// In that case he has to respect the behavior of
// the xrootd with the oss.localroot and all.export directives, which is
// not very practical.

if (resource == "/static/css/xrdhttp.css") {
prot->SendSimpleResp(200, NULL, NULL, (char *) static_css_xrdhttp_css, static_css_xrdhttp_css_len);
reset();
return 1;
}
if (resource == "/static/icons/xrdhttp.ico") {
prot->SendSimpleResp(200, NULL, NULL, (char *) favicon_ico, favicon_ico_len);
reset();
return 1;
}
if (resource.beginswith("/static/")) {

// This is a request for a /static resource
// If we have to use the embedded ones then we return the ones in memory as constants

}
// The sysadmin can always redirect the request to another host that
// contains his static resources

// We also allow xrootd to preread from the local disk all the files
// that have to be served as static resources.

if (prot->embeddedstatic) {

// Default case: the icon and the css of the HTML rendering of XrdHttp
if (resource == "/static/css/xrdhttp.css") {
prot->SendSimpleResp(200, NULL, NULL, (char *) static_css_xrdhttp_css, static_css_xrdhttp_css_len);
reset();
return 1;
}
if (resource == "/static/icons/xrdhttp.ico") {
prot->SendSimpleResp(200, NULL, NULL, (char *) favicon_ico, favicon_ico_len);
reset();
return 1;
}

}

// If we are here then none of the embedded resources match (or they are disabled)
// We may have to redirect to a host that is supposed to serve the static resources
if (prot->staticredir) {

XrdOucString s = "Location: ";
s.append(prot->staticredir);

if (s.endswith('/'))
s.erasefromend(1);

s.append(resource);
appendOpaque(s, 0, 0, 0);

prot->SendSimpleResp(302, NULL, (char *) s.c_str(), 0, 0);
return -1;


} else {

// We lookup the requested path in a hash containing the preread files
XrdHttpProtocol::StaticPreloadInfo *mydata = prot->staticpreload->Find(resource.c_str());
if (mydata) {
prot->SendSimpleResp(200, NULL, NULL, (char *) mydata->data, mydata->len);
reset();
return 1;
}
}


}

switch (reqstate) {
case 0: // Stat()
Expand Down
7 changes: 7 additions & 0 deletions src/XrdHttp/xrootd-http-rdr.cf
Expand Up @@ -61,6 +61,13 @@ http.embeddedstatic yes
#http.secxtractor /home/furano/Park/xrootd/xrootd_trunk2/xrootd/build/src/XrdHTTP/libXrdHttpVOMS.so


# As an example of preloading files, let's preload in memory
# the /etc/services and /etc/hosts files
# and assign them to some urlpaths in /static
http.staticpreload /static/services_preload1 /etc/services
http.staticpreload /static/services_preload2 /etc/services
http.staticpreload /static/hosts_preload /etc/hosts

all.role manager
all.manager pcitgt02:1213

9 changes: 8 additions & 1 deletion src/XrdHttp/xrootd-http.cf
Expand Up @@ -13,9 +13,16 @@ fi
http.cert /etc/grid-security/hostcert.pem
http.key /etc/grid-security/hostkey.pem
http.cadir /etc/grid-security/certificates
#http.secretkey CHANGEME
http.secretkey etc/hosts8374653847t37t8873t3t3u
#http.secxtractor /usr/lib64/libXrdHttpVOMS.so.1

# As an example of preloading files, let's preload in memory
# the /etc/services and /etc/hosts files
# and assign them to some urlpaths in /static
http.staticpreload /static/services_preload1 /etc/services
http.staticpreload /static/services_preload2 /etc/services
http.staticpreload /static/hosts_preload /etc/hosts

all.role server
all.manager pcitgt02.cern.ch:1213
all.export /
Expand Down

0 comments on commit d680aed

Please sign in to comment.