Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of the option http.header2cgi #597

Merged
merged 4 commits into from
Oct 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
63 changes: 63 additions & 0 deletions src/XrdHttp/XrdHttpProtocol.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ BIO *XrdHttpProtocol::sslbio_err = 0;
XrdCryptoFactory *XrdHttpProtocol::myCryptoFactory = 0;
XrdHttpSecXtractor *XrdHttpProtocol::secxtractor = 0;
XrdHttpExtHandler *XrdHttpProtocol::exthandler = 0;
std::map< std::string, std::string > XrdHttpProtocol::hdr2cgimap;

static const unsigned char *s_server_session_id_context = (const unsigned char *) "XrdHTTPSessionCtx";
static int s_server_session_id_context_len = 18;
Expand Down Expand Up @@ -868,6 +869,7 @@ int XrdHttpProtocol::Config(const char *ConfigFN, XrdOucEnv *myEnv) {
else if TS_Xeq("staticredir", xstaticredir);
else if TS_Xeq("staticpreload", xstaticpreload);
else if TS_Xeq("listingdeny", xlistdeny);
else if TS_Xeq("header2cgi", xheader2cgi);
else {
eDest.Say("Config warning: ignoring unknown directive '", var, "'.");
Config.Echo();
Expand Down Expand Up @@ -2224,7 +2226,68 @@ int XrdHttpProtocol::xexthandler(XrdOucStream & Config, const char *ConfigFN, Xr



/* Function: xheader2cgi
*
* Purpose: To parse the directive: header2cgi <headerkey> <cgikey>
*
* <headerkey> the name of an incoming HTTP header
* to be transformed
* <cgikey> the name to be given when adding it to the cgi info
* that is kept only internally
*
* Output: 0 upon success or !0 upon failure.
*/

int XrdHttpProtocol::xheader2cgi(XrdOucStream & Config) {
char *val, keybuf[1024], parmbuf[1024];
char *parm;

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

// Trim the beginning, in place
while ( *val && !isalnum(*val) ) val++;
strcpy(keybuf, val);

// Trim the end, in place
char *pp;
pp = keybuf + strlen(keybuf) - 1;
while ( (pp >= keybuf) && (!isalnum(*pp)) ) {
*pp = '\0';
pp--;
}

parm = Config.GetWord();

// Trim the beginning, in place
while ( *parm && !isalnum(*parm) ) parm++;
strcpy(parmbuf, parm);

// Trim the end, in place
pp = parmbuf + strlen(parmbuf) - 1;
while ( (pp >= parmbuf) && (!isalnum(*pp)) ) {
*pp = '\0';
pp--;
}

// Add this mapping to the map that will be used
try {
hdr2cgimap[keybuf] = parmbuf;
} catch ( ... ) {
eDest.Emsg("Config", "Can't insert new header2cgi rule. key: '", keybuf, "'");
return 1;
}

}


return 0;
}



Expand Down
6 changes: 5 additions & 1 deletion src/XrdHttp/XrdHttpProtocol.hh
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ private:
static int xsslcafile(XrdOucStream &Config);
static int xsslverifydepth(XrdOucStream &Config);
static int xsecretkey(XrdOucStream &Config);

static int xheader2cgi(XrdOucStream &Config);

static XrdHttpSecXtractor *secxtractor;
static XrdHttpExtHandler *exthandler;

Expand Down Expand Up @@ -343,5 +344,8 @@ protected:
/// Our role
static kXR_int32 myRole;

/// Rules that turn HTTP headers to cgi tokens in the URL, for internal comsumption
static std::map< std::string, std::string > hdr2cgimap;

};
#endif
38 changes: 37 additions & 1 deletion src/XrdHttp/XrdHttpReq.cc
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,23 @@ int XrdHttpReq::parseLine(char *line, int len) {

} else if (!strcmp(key, "Expect") && strstr(val, "100-continue")) {
sendcontinue = true;
} else {
// Some headers need to be translated into "local" cgi info. In theory they should already be quoted
std::map< std:: string, std:: string > ::iterator it = prot->hdr2cgimap.find(key);
if (it != prot->hdr2cgimap.end()) {
std:: string s;
s.assign(val, line+len-val);
trim(s);

if (hdr2cgistr.length() > 0) {
hdr2cgistr.append("&");
}
hdr2cgistr.append(it->second);
hdr2cgistr.append("=");
hdr2cgistr.append(s);


}
}

// We memorize the heaers also as a string
Expand Down Expand Up @@ -767,7 +784,25 @@ int XrdHttpReq::ProcessHTTPReq() {

}


/// If we have to add extra header information, add it here.
if (!hdr2cgistr.empty()) {
const char *p = strchr(resourceplusopaque.c_str(), '?');
if (p) {
resourceplusopaque.append("&");
} else {
resourceplusopaque.append("?");
}

char *q = quote(hdr2cgistr.c_str());
resourceplusopaque.append(q);
TRACEI(DEBUG, "Appended header fields to opaque info: '" << hdr2cgistr << "'");
free(q);

// Once we've appended the authorization to the full resource+opaque string,
// reset the authz to empty: this way, any operation that triggers repeated ProcessHTTPReq
// calls won't also trigger multiple copies of the authz.
hdr2cgistr = "";
}

//
// Here we process the request locally
Expand Down Expand Up @@ -2232,6 +2267,7 @@ void XrdHttpReq::reset() {

host = "";
destination = "";
hdr2cgistr = "";

iovP = 0;
iovN = 0;
Expand Down
4 changes: 3 additions & 1 deletion src/XrdHttp/XrdHttpReq.hh
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,9 @@ public:
/// The destination field specified in the req
std::string destination;


/// Additional opaque info that may come from the hdr2cgi directive
std::string hdr2cgistr;

//
// Area for coordinating request and responses to/from the bridge
//
Expand Down
2 changes: 1 addition & 1 deletion src/XrdHttp/XrdHttpUtils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ char *unquote(char *str) {

// Quote a string and return a new one

char *quote(char *str) {
char *quote(const char *str) {
int l = strlen(str);
char *r = (char *) malloc(l*3 + 1);
r[0] = '\0';
Expand Down
2 changes: 1 addition & 1 deletion src/XrdHttp/XrdHttpUtils.hh
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ int compareHash(


// Create a new quoted string
char *quote(char *str);
char *quote(const char *str);

// unquote a string and return a new one
char *unquote(char *str);
Expand Down