Skip to content

Commit

Permalink
Merge pull request #22 from bbockelm/generic_http
Browse files Browse the repository at this point in the history
Add support for more generic HTTP prefixes
  • Loading branch information
jhiemstrawisc authored Mar 26, 2024
2 parents a7586b7 + 57dc71e commit a0eb944
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 26 deletions.
42 changes: 29 additions & 13 deletions src/HTTPFile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,31 +52,42 @@ HTTPFile::HTTPFile(XrdSysError &log, HTTPFileSystem *oss) :
last_modified(0)
{}

// Ensures that path is of the form /storagePrefix/object and returns
// the resulting object value. The storagePrefix does not necessarily begin
// with '/'
//
// Examples:
// /foo/bar, /foo/bar/baz -> baz
// storage.com/foo, /storage.com/foo/bar -> bar
// /baz, /foo/bar -> error
int
parse_path( const std::string & hname, const char * path, std::string & object ) {
const std::filesystem::path p(path);
const std::filesystem::path h(hname);
parse_path(const std::string &storagePrefixStr, const char *pathStr, std::string &object) {
const std::filesystem::path storagePath(pathStr);
const std::filesystem::path storagePrefix(storagePrefixStr);

auto prefixComponents = h.begin();
auto pathComponents = p.begin();
auto prefixComponents = storagePrefix.begin();
auto pathComponents = storagePath.begin();

std::filesystem::path full;
std::filesystem::path prefix;

pathComponents++; // The path will begin with '/' while the hostname will not. Skip the first slash for comparison
pathComponents++;
if (!storagePrefixStr.empty() && storagePrefixStr[0] == '/') {
prefixComponents++;
}

while (prefixComponents != h.end() && *prefixComponents == *pathComponents ) {
while (prefixComponents != storagePrefix.end() && *prefixComponents == *pathComponents ) {
full /= *prefixComponents++;
prefix /= *pathComponents++;
}

// Check that nothing diverged before reaching end of service name
if (prefixComponents != h.end()) {
if (prefixComponents != storagePrefix.end()) {
return -ENOENT;
}

std::filesystem::path obj_path;
while (pathComponents != p.end()) {
while (pathComponents != storagePath.end()) {
obj_path /= *pathComponents++;
}

Expand All @@ -90,12 +101,17 @@ HTTPFile::Open(const char *path, int Oflag, mode_t Mode, XrdOucEnv &env)
{
auto configured_hostname = m_oss->getHTTPHostName();
auto configured_hostUrl = m_oss->getHTTPHostUrl();
const auto &configured_url_base = m_oss->getHTTPUrlBase();
if (!configured_url_base.empty()) {
configured_hostUrl = configured_url_base;
configured_hostname = m_oss->getStoragePrefix();
}

//
// Check the path for validity.
//
std::string object;
int rv = parse_path( configured_hostname, path, object );
int rv = parse_path(configured_hostname, path, object);

if( rv != 0 ) { return rv; }

Expand Down Expand Up @@ -136,10 +152,10 @@ HTTPFile::Read(void *buffer, off_t offset, size_t size)
int
HTTPFile::Fstat(struct stat *buff)
{
m_log.Log(LogMask::Debug, "HTTPFile::Fstat", "About to perform HTTPFile::Fstat(): hostname / object", hostname.c_str(), object.c_str());
m_log.Log(LogMask::Debug, "HTTPFile::Fstat", "About to perform HTTPFile::Fstat():", hostUrl.c_str(), object.c_str());
HTTPHead head(
this->hostUrl,
this->object,
hostUrl,
object,
m_log
);

Expand Down
28 changes: 17 additions & 11 deletions src/HTTPFileSystem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,19 +108,25 @@ HTTPFileSystem::Config(XrdSysLogger *lp, const char *configfn)
if(! temporary) { continue; }
value = temporary;

if(! handle_required_config( attribute, "httpserver.host_name",
value, this->http_host_name ) ) { Config.Close(); return false; }
if(! handle_required_config( attribute, "httpserver.host_url",
value, this->http_host_url ) ) { Config.Close(); return false; }
if (!handle_required_config(attribute, "httpserver.host_name", value, http_host_name) ||
!handle_required_config(attribute, "httpserver.host_url", value, http_host_url) ||
!handle_required_config(attribute, "httpserver.url_base", value, m_url_base) ||
!handle_required_config(attribute, "httpserver.storage_prefix", value, m_storage_prefix))
{
Config.Close();
return false;
}
}

if( this->http_host_name.empty() ) {
m_log.Emsg("Config", "httpserver.host_name not specified");
return false;
}
if( this->http_host_url.empty() ) {
m_log.Emsg("Config", "httpserver.host_url not specified");
return false;
if (m_url_base.empty()) {
if (http_host_name.empty()) {
m_log.Emsg("Config", "httpserver.host_name not specified; this or httpserver.url_base are required");
return false;
}
if (http_host_url.empty()) {
m_log.Emsg("Config", "httpserver.host_url not specified; this or httpserver.url_base are required");
return false;
}
}

int retc = Config.LastError();
Expand Down
8 changes: 6 additions & 2 deletions src/HTTPFileSystem.hh
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ public:
int Lfn2Pfn(const char *Path, char *buff, int blen) {return -ENOSYS;}
const char *Lfn2Pfn(const char *Path, char *buff, int blen, int &rc) {return nullptr;}

const std::string & getHTTPHostName() const { return http_host_name; }
const std::string & getHTTPHostUrl() const { return http_host_url; }
const std::string &getHTTPHostName() const {return http_host_name;}
const std::string &getHTTPHostUrl() const {return http_host_url;}
const std::string &getHTTPUrlBase() const {return m_url_base;}
const std::string &getStoragePrefix() const {return m_storage_prefix;}

protected:
XrdOucEnv *m_env;
Expand All @@ -92,4 +94,6 @@ protected:
private:
std::string http_host_name;
std::string http_host_url;
std::string m_url_base;
std::string m_storage_prefix;
};

0 comments on commit a0eb944

Please sign in to comment.