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

XrdApp: Add XrdClProxyPlugin implementation #487

Merged
merged 1 commit into from
Mar 30, 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
1 change: 1 addition & 0 deletions packaging/rhel/xrootd.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,7 @@ fi
%files libs
%defattr(-,root,root,-)
%{_libdir}/libXrdAppUtils.so.1*
%{_libdir}/libXrdClProxyPlugin-4.so
%{_libdir}/libXrdCks*-4.so
%{_libdir}/libXrdCrypto.so.1*
%{_libdir}/libXrdCryptoLite.so.1*
Expand Down
25 changes: 24 additions & 1 deletion src/XrdApps.cmake
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@

include( XRootDCommon )

#-------------------------------------------------------------------------------
# Modules
#-------------------------------------------------------------------------------
set( LIB_XRDCL_PROXY_PREFIX XrdClProxyPrefix-${PLUGIN_VERSION} )

#-------------------------------------------------------------------------------
# Shared library version
#-------------------------------------------------------------------------------
Expand Down Expand Up @@ -121,11 +126,29 @@ target_link_libraries(
pthread
${EXTRA_LIBS} )

#-------------------------------------------------------------------------------
# XrdClProxyPlugin library
#-------------------------------------------------------------------------------
add_library(
${LIB_XRDCL_PROXY_PREFIX}
MODULE
XrdApps/XrdClProxyPlugin/ProxyPrefixPlugin.cc
XrdApps/XrdClProxyPlugin/ProxyPrefixFile.cc)

target_link_libraries(${LIB_XRDCL_PROXY_PREFIX} XrdCl)

set_target_properties(
${LIB_XRDCL_PROXY_PREFIX}
PROPERTIES
INTERFACE_LINK_LIBRARIES ""
LINK_INTERFACE_LIBRARIES "" )

#-------------------------------------------------------------------------------
# Install
#-------------------------------------------------------------------------------
install(
TARGETS xrdadler32 cconfig mpxstats wait41 xrdcp-old XrdAppUtils xrdmapc xrdacctest
TARGETS xrdadler32 cconfig mpxstats wait41 xrdcp-old XrdAppUtils xrdmapc
xrdacctest ${LIB_XRDCL_PROXY_PREFIX}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} )

Expand Down
199 changes: 199 additions & 0 deletions src/XrdApps/XrdClProxyPlugin/ProxyPrefixFile.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
//------------------------------------------------------------------------------
// Copyright (c) 2011-2017 by European Organization for Nuclear Research (CERN)
// Author: Elvin Sindrilaru <esindril@cern.ch>
//------------------------------------------------------------------------------
// This file is part of the XRootD software suite.
//
// XRootD is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// XRootD is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with XRootD. If not, see <http://www.gnu.org/licenses/>.
//
// In applying this licence, CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.
//------------------------------------------------------------------------------

#include "ProxyPrefixFile.hh"
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cctype>
#include "XrdCl/XrdClLog.hh"

namespace xrdcl_proxy
{
//------------------------------------------------------------------------------
// Constructor
//------------------------------------------------------------------------------
ProxyPrefixFile::ProxyPrefixFile():
mIsOpen(false),
pFile(0)
{}

//------------------------------------------------------------------------------
// Destructor
//------------------------------------------------------------------------------
ProxyPrefixFile::~ProxyPrefixFile()
{
if (pFile) {
delete pFile;
}
}

//------------------------------------------------------------------------------
// Open
//------------------------------------------------------------------------------
XRootDStatus
ProxyPrefixFile::Open(const std::string& url,
OpenFlags::Flags flags,
Access::Mode mode,
ResponseHandler* handler,
uint16_t timeout)
{
XRootDStatus st;

if (mIsOpen) {
st = XRootDStatus(stError, errInvalidOp);
return st;
}

pFile = new XrdCl::File(false);
std::string open_url = ConstructFinalUrl(url);
st = pFile->Open(open_url, flags, mode, handler, timeout);

if (st.IsOK()) {
mIsOpen = true;
}

return st;
}

//------------------------------------------------------------------------------
// Get proxy prefix Url
//------------------------------------------------------------------------------
std::string
ProxyPrefixFile::GetPrefixUrl() const
{
std::string url_prefix = (getenv("XROOT_PROXY") ? getenv("XROOT_PROXY") : "");

// Try out also the lower-case one
if (url_prefix.empty()) {
url_prefix = (getenv("xroot_proxy") ? getenv("xroot_proxy") : "");
}

return url_prefix;
}

//------------------------------------------------------------------------------
// Trim whitespaces from both ends for a string
//------------------------------------------------------------------------------
std::string
ProxyPrefixFile::trim(const std::string& in) const
{
std::string::const_iterator wsfront, wsback;
std::string::const_reverse_iterator rwsback;
wsfront = in.begin();
rwsback = in.rbegin();

while (*wsfront == ' ') {
++wsfront;
}

while (*rwsback == ' ') {
++rwsback;
}

wsback = rwsback.base();
return (wsback <= wsfront ? std::string() : std::string(wsfront, wsback));

/* TODO: To be used when C++11 is available
auto wsfront = std::find_if_not(in.begin(), in.end(),
[](int c) -> bool {return std::isspace(c);});
auto wsback = std::find_if_not(in.rbegin(), in.rend(),
[](int c) -> bool {return std::isspace(c);}).base();
return (wsback <= wsfront ? std::string() : std::string(wsfront, wsback));
*/
}

//------------------------------------------------------------------------------
// Get list of domains which are NOT to be prefixed
//------------------------------------------------------------------------------
std::list<std::string>
ProxyPrefixFile::GetExclDomains() const
{
std::string excl_domains = (getenv("XROOT_PROXY_EXCL_DOMAINS") ?
getenv("XROOT_PROXY_EXCL_DOMAINS") : "");

if (excl_domains.empty()) {
return std::list<std::string>();
}

char delim = ',';
std::string item;
std::list<std::string> lst;
std::stringstream ss(excl_domains);

while (getline(ss, item, delim)) {
lst.push_back(trim(item));
}

return lst;
}

//------------------------------------------------------------------------------
// Construct final Url
//------------------------------------------------------------------------------
std::string
ProxyPrefixFile::ConstructFinalUrl(const std::string& orig_surl) const
{
std::string final_surl = orig_surl;
std::string url_prefix = GetPrefixUrl();
XrdCl::Log* log = DefaultEnv::GetLog();
log->Debug(1, "url=%s, url_prefix=%s", orig_surl.c_str(), url_prefix.c_str());

if (!url_prefix.empty()) {
bool exclude = false;
std::list<std::string> lst_excl = GetExclDomains();
XrdCl::URL orig_url(orig_surl);
std::string orig_host = orig_url.GetHostId();
// Remove port if present
size_t pos = orig_host.find(':');

if (pos != std::string::npos) {
orig_host = orig_host.substr(0, pos);
}

log->Debug(1, "orig_host=%s", orig_host.c_str());

for (std::list<std::string>::iterator it_excl = lst_excl.begin();
it_excl != lst_excl.end(); ++it_excl) {
if (url_prefix.size() < it_excl->size()) {
continue;
}

if (std::equal(it_excl->rbegin(), it_excl->rend(), orig_host.rbegin())) {
exclude = true;
break;
}
}

if (!exclude) {
final_surl.insert(0, url_prefix);
}
}

log->Debug(1, "final_host=%s", final_surl.c_str());
return final_surl;
}

} // namespace xrdcl_proxy