56static const std::string
VERSION =
"0.2.0";
59" TDavixFile/" +
VERSION +
" davix/" + Davix::version();
62#define ENVPFX "Davix."
93 if(!str)
return defvalue;
95 if(strcmp(str,
"n") == 0 || strcmp(str,
"no") == 0 || strcmp(str,
"0") == 0 || strcmp(str,
"false") == 0)
return false;
96 if(strcmp(str,
"y") == 0 || strcmp(str,
"yes") == 0 || strcmp(str,
"1") == 0 || strcmp(str,
"true") == 0)
return true;
106 old_flag |= O_RDONLY;
109 old_flag |= (O_CREAT | O_WRONLY | O_TRUNC);
112 old_flag |= (O_RDWR);
121 Int_t log_level = (
gEnv) ?
gEnv->GetValue(
"Davix.Debug", 0) : 0;
125 davix_set_log_level(0);
128 davix_set_log_level(DAVIX_LOG_WARNING);
131 davix_set_log_level(DAVIX_LOG_VERBOSE);
134 davix_set_log_level(DAVIX_LOG_DEBUG);
137 davix_set_log_level(DAVIX_LOG_ALL);
146 static const std::string whitespace =
" \t\f\n\v\r";
149 static const std::string nonheader_whitespace =
"\r\n";
150 auto begin = input_token.find_first_not_of(whitespace);
152 if (begin == std::string::npos) {
157 std::string token = input_token.substr(begin);
158 auto end = token.find_last_not_of(whitespace);
159 token = token.substr(0, end + 1);
163 if (token.find(nonheader_whitespace) != std::string::npos) {
168 output_token = token;
175 int fd = open(token_file.c_str(), O_RDONLY);
178 if (errno == ENOENT) {
189 static const size_t max_size = 16384;
190 std::vector<char> input_buffer;
191 input_buffer.resize(max_size);
192 ssize_t retval = read(fd, &input_buffer[0], max_size);
197 R__LOG_ERROR(
TDavixLogChannel()) <<
"Token discovery failure: failed to read file " << token_file.c_str() <<
"', error: " << strerror(errno);
200 if (retval == 16384) {
206 std::string token(&input_buffer[0], retval);
215 const char *bearer_token = std::getenv(
"BEARER_TOKEN");
217 if (bearer_token && *bearer_token){
219 if (!token.empty()) {
return token;}
222 const char *bearer_token_file = std::getenv(
"BEARER_TOKEN_FILE");
223 if (bearer_token_file) {
225 if (!token.empty()) {
return token;}
229 uid_t euid = geteuid();
230 std::string fname =
"/bt_u";
231 fname += std::to_string(euid);
233 const char *xdg_runtime_dir = std::getenv(
"XDG_RUNTIME_DIR");
234 if (xdg_runtime_dir) {
235 std::string xdg_token_file = std::string(xdg_runtime_dir) + fname;
237 if (!token.empty()) {
return token;}
256 char default_proxy[64];
257 const char *genvvar = 0, *genvvar1 = 0;
259 genvvar =
gEnv->GetValue(
"Davix.GSI.UserProxy", (
const char *) NULL);
261 ucert = ukey = genvvar;
263 Info(
"TDavixFile_http_get_ucert",
"Found proxy in gEnv");
268 if (std::getenv(
"X509_USER_PROXY")) {
270 Info(
"TDavixFile_http_get_ucert",
"Found proxy in X509_USER_PROXY");
271 ucert = ukey = std::getenv(
"X509_USER_PROXY");
276 snprintf(default_proxy,
sizeof(default_proxy),
"/tmp/x509up_u%d",
279 if (access(default_proxy, R_OK) == 0) {
281 Info(
"TDavixFile_http_get_ucert",
"Found proxy in /tmp");
282 ucert = ukey = default_proxy;
287 genvvar =
gEnv->GetValue(
"Davix.GSI.UserCert", (
const char *) NULL);
288 genvvar1 =
gEnv->GetValue(
"Davix.GSI.UserKey", (
const char *) NULL);
289 if (genvvar || genvvar1) {
291 Info(
"TDavixFile_http_get_ucert",
"Found cert and key in gEnv");
299 if (std::getenv(
"X509_USER_CERT"))
300 ucert = std::getenv(
"X509_USER_CERT");
301 if (std::getenv(
"X509_USER_KEY"))
302 ukey = std::getenv(
"X509_USER_KEY");
304 if ((ucert.size() > 0) || (ukey.size() > 0)) {
306 Info(
"TDavixFile_http_get_ucert",
"Found cert and key in gEnv");
315 Davix::X509Credential *cert, Davix::DavixError **
err)
319 std::string ucert, ukey;
322 if (ucert.empty() || ukey.empty()) {
323 Davix::DavixError::setupError(
err,
"TDavixFile",
324 Davix::StatusCode::AuthentificationError,
325 "Could not set the user's proxy or certificate");
328 return cert->loadFromFilePEM(ukey, ucert,
"",
err);
357 DavixError *davixErr = NULL;
365 DavixError *davixErr2 = NULL;
368 std::vector<DavFile> replicasLocal = file.getReplicas(NULL, &davixErr2);
369 for(
size_t i = 0; i < replicasLocal.size(); i++) {
370 replicas.push_back(replicasLocal[i].getUri().getString());
374 DavixError::clearError(&davixErr2);
379 Error(
"DavixOpen",
"can not open file \"%s\" with davix: %s (%d)",
381 davixErr->getErrMsg().c_str(), davixErr->getStatus());
383 DavixError::clearError(&davixErr);
386 davixPosix->fadvise(fd, 0, 300, Davix::AdviseRandom);
396 DavixError *davixErr = NULL;
398 Error(
"DavixClose",
"can not to close file with davix: %s (%d)",
399 davixErr->getErrMsg().c_str(), davixErr->getStatus());
400 DavixError::clearError(&davixErr);
408 const char *env_var = NULL;
411 Info(
"enableGridMode",
" grid mode enabled !");
413 if( ( env_var = std::getenv(
"X509_CERT_DIR")) == NULL){
414 env_var=
"/etc/grid-security/certificates/";
416 davixParam->addCertificateAuthorityPath(env_var);
418 Info(
"enableGridMode",
"Adding CAdir %s", env_var);
431template<
typename TRequestParams = Davix::RequestParams>
432static auto awsRegion(TRequestParams *parameters,
const char *region)
433 ->
decltype(parameters->setAwsRegion(region),
void())
435 if (
gDebug > 1)
Info(
"awsRegion",
"Setting S3 Region to '%s' - v4 signature will be used", region);
436 parameters->setAwsRegion(region);
439template<
typename TRequestParams = Davix::RequestParams>
441 Warning(
"setAwsRegion",
"Unable to set AWS region, not supported by this version of davix");
445template<
typename TRequestParams = Davix::RequestParams>
446static auto awsToken(TRequestParams *parameters,
const char *token)
447 ->
decltype(parameters->setAwsToken(token),
void())
449 if (
gDebug > 1)
Info(
"awsToken",
"Setting S3 STS temporary credentials");
450 parameters->setAwsToken(token);
453template<
typename TRequestParams = Davix::RequestParams>
455 Warning(
"awsToken",
"Unable to set AWS token, not supported by this version of davix");
459template<
typename TRequestParams = Davix::RequestParams>
461 ->
decltype(parameters->setAwsAlternate(option),
void())
463 if (
gDebug > 1)
Info(
"awsAlternate",
"Setting S3 path-based bucket option (s3alternate)");
464 parameters->setAwsAlternate(option);
467template<
typename TRequestParams = Davix::RequestParams>
469 Warning(
"awsAlternate",
"Unable to set AWS path-based bucket option (s3alternate), not supported by this version of davix");
473 if(!region.empty()) {
490 const std::string ®ion,
const std::string &token)
493 Info(
"setS3Auth",
" Aws S3 tokens configured");
495 davixParam->setAwsAuthorizationKeys(secret, access);
496 davixParam->setProtocol(RequestProtocol::AwsS3);
506 const char *env_var = NULL, *env_var2 = NULL;
508 davixParam->setTransparentRedirectionSupport(
true);
512 env_var =
gEnv->GetValue(
"Davix.GSI.CAdir", (
const char *) NULL);
514 davixParam->addCertificateAuthorityPath(env_var);
516 Info(
"parseConfig",
"Add CAdir: %s", env_var);
520 bool ca_check_local = !
isno(
gEnv->GetValue(
"Davix.GSI.CACheck", (
const char *)
"y"));
523 Info(
"parseConfig",
"Setting CAcheck to %s", ((ca_check_local) ? (
"true") : (
"false")));
526 std::string prefix =
"Bearer ";
528 if (!token.empty()) {
531 davixParam->addHeader(
"Authorization", prefix + token);
535 if (((env_var =
gEnv->GetValue(
"Davix.S3.SecretKey", std::getenv(
"S3_SECRET_KEY"))) != NULL)
536 && ((env_var2 =
gEnv->GetValue(
"Davix.S3.AccessKey", std::getenv(
"S3_ACCESS_KEY"))) != NULL)) {
537 Info(
"parseConfig",
"Setting S3 SecretKey and AccessKey. Access Key : %s ", env_var2);
538 davixParam->setAwsAuthorizationKeys(env_var, env_var2);
541 if ( (env_var =
gEnv->GetValue(
"Davix.S3.Region", std::getenv(
"S3_REGION"))) != NULL) {
545 if( (env_var =
gEnv->GetValue(
"Davix.S3.Token", std::getenv(
"S3_TOKEN"))) != NULL) {
549 if( (env_var =
gEnv->GetValue(
"Davix.S3.Alternate", std::getenv(
"S3_ALTERNATE"))) != NULL) {
554 env_var =
gEnv->GetValue(
"Davix.GSI.GridMode", (
const char *)
"y");
564 std::stringstream ss(option);
566 std::vector<std::string> parsed_options;
568 std::string s3seckey, s3acckey, s3region, s3token;
570 while (std::getline(ss, item,
' ')) {
571 parsed_options.push_back(item);
574 for (std::vector<std::string>::iterator it = parsed_options.begin(); it < parsed_options.end(); ++it) {
597 s3token = std::string(it->c_str() + strlen(
s3_token_opt));
607 if (s3seckey.size() > 0) {
608 setS3Auth(s3seckey, s3acckey, s3region, s3token);
622 davixParam->setMetalinkMode(Davix::MetalinkMode::Disable);
632 DavixError *davixErr = NULL;
636 Error(
"DavixStat",
"can not stat the file with davix: %s (%d)",
637 davixErr->getErrMsg().c_str(), davixErr->getStatus());
638 DavixError::clearError(&davixErr);
649 :
TFile(url, strstr(opt,
"_WITHOUT_GLOBALREGISTRATION") != nullptr ?
"WEB_WITHOUT_GLOBALREGISTRATION" :
"WEB"),
673 if ((
d_ptr->getDavixFileInstance()) == NULL){
684 std::vector<std::string> replicas =
d_ptr->getReplicas();
686 if(!replicas.empty()) {
687 std::stringstream ss;
688 for(
size_t i = 0; i < replicas.size(); i++) {
690 if(i != replicas.size()-1) ss <<
"|";
713 Error(
"Seek",
"seeking from end in archive is not (yet) supported");
719 Info(
"Seek",
" move cursor to %lld"
731 if ((fd =
d_ptr->getDavixFileInstance()) == NULL)
738 Info(
"ReadBuffer",
"%lld bytes of data read sequentially"
739 " (%d requested)",
ret, len);
749 if ((fd =
d_ptr->getDavixFileInstance()) == NULL)
757 Info(
"ReadBuffer",
"%lld bytes of data read from offset"
758 " %lld (%d requested)",
ret, pos, len);
767 if ((fd =
d_ptr->getDavixFileInstance()) == NULL)
770 d_ptr->davixPosix->fadvise(fd,
static_cast<dav_off_t
>(offs),
static_cast<dav_size_t
>(len), Davix::AdviseRandom);
773 Info(
"ReadBufferAsync",
"%d bytes of data prefected from offset"
774 " %lld ", len, offs);
783 if ((fd =
d_ptr->getDavixFileInstance()) == NULL)
791 Info(
"ReadBuffers",
"%lld bytes of data read from a list of %d buffers",
802 if ((fd =
d_ptr->getDavixFileInstance()) == NULL)
810 Info(
"WriteBuffer",
"%lld bytes of data write"
811 " %d requested",
ret, len);
819 d_ptr->davixParam->setSSLCAcheck((
bool)check);
826 d_ptr->enableGridMode();
834 std::vector<void *>::iterator
f = std::find(
dirdVec.begin(),
dirdVec.end(), fd);
851 std::vector<void *>::iterator
f = std::find(
dirdVec.begin(),
dirdVec.end(), fd);
864 Info(
"GetSize",
"file size requested: %lld", (
Long64_t)st.st_size);
903 DavixError *davixErr = NULL;
908 Error(
"DavixReadBuffer",
"can not read data with davix: %s (%d)",
909 davixErr->getErrMsg().c_str(), davixErr->getStatus());
910 DavixError::clearError(&davixErr);
923 DavixError *davixErr = NULL;
928 Error(
"DavixWriteBuffer",
"can not write data with davix: %s (%d)",
929 davixErr->getErrMsg().c_str(), davixErr->getStatus());
930 DavixError::clearError(&davixErr);
943 DavixError *davixErr = NULL;
948 Error(
"DavixPReadBuffer",
"can not read data with davix: %s (%d)",
949 davixErr->getErrMsg().c_str(), davixErr->getStatus());
950 DavixError::clearError(&davixErr);
963 DavixError *davixErr = NULL;
965 auto in = std::make_unique<DavIOVecInput[]>(nbuf);
966 auto out = std::make_unique<DavIOVecOuput[]>(nbuf);
969 for (
Int_t i = 0; i < nbuf; ++i) {
970 in[i].diov_buffer = &buf[lastPos];
971 in[i].diov_offset = pos[i];
972 in[i].diov_size = len[i];
976 Long64_t ret =
d_ptr->davixPosix->preadVec(fd, in.get(), out.get(), nbuf, &davixErr);
978 Error(
"DavixReadBuffers",
"can not read data with davix: %s (%d)",
979 davixErr->getErrMsg().c_str(), davixErr->getStatus());
980 DavixError::clearError(&davixErr);
#define R__LOG_ERROR(...)
int Int_t
Signed integer 4 bytes (int).
bool Bool_t
Boolean (0=false, 1=true) (bool).
double Double_t
Double 8 bytes.
const char Option_t
Option string (const char).
const char * s3_seckey_opt
bool normalizeToken(const std::string &input_token, std::string &output_token)
static const std::string VERSION
static void ConfigureDavixLogLevel()
static auto awsRegion(TRequestParams *parameters, const char *region) -> decltype(parameters->setAwsRegion(region), void())
bool findTokenInFile(const std::string &token_file, std::string &output_token)
static auto awsAlternate(TRequestParams *parameters, bool option) -> decltype(parameters->setAwsAlternate(option), void())
std::string DiscoverToken()
static int TDavixFile_http_authn_cert_X509(void *userdata, const Davix::SessionInfo &info, Davix::X509Credential *cert, Davix::DavixError **err)
const char * s3_alternate_opt
static auto awsToken(TRequestParams *parameters, const char *token) -> decltype(parameters->setAwsToken(token), void())
ROOT::RLogChannel & TDavixLogChannel()
const char * s3_token_opt
const char * ca_check_opt
const char * open_mode_new
const char * open_mode_update
const char * open_mode_create
const char * s3_acckey_opt
static Context * davix_context_s
const char * grid_mode_opt
int configure_open_flag(const std::string &str, int old_flag)
static void TDavixFile_http_get_ucert(std::string &ucert, std::string &ukey)
static const std::string gUserAgent
bool strToBool(const char *str, bool defvalue)
const char * s3_region_opt
const char * open_mode_read
Error("WriteTObject","The current directory (%s) is not associated with a file. The object (%s) has not been written.", GetName(), objname)
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
A log configuration for a channel, e.g.
Davix::RequestParams * davixParam
std::vector< void * > dirdVec
void setAwsToken(const std::string &token)
void setS3Auth(const std::string &secret, const std::string &access, const std::string ®ion, const std::string &token)
void setAwsAlternate(const bool &option)
static Davix::Context * getDavixInstance()
Davix::DavPosix * davixPosix
void parseParams(Option_t *option)
intput params
Int_t DavixStat(const char *url, struct stat *st)
Davix::Context * davixContext
void setAwsRegion(const std::string ®ion)
std::vector< std::string > replicas
void removeDird(void *fd)
Bool_t WriteBuffer(const char *buffer, Int_t bufferLength) override
Write a buffer to the file.
TString GetNewUrl() override
Long64_t GetSize() const override
Returns the current file size.
Long64_t DavixReadBuffers(Davix_fd *fd, char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
Long64_t DavixReadBuffer(Davix_fd *fd, char *buf, Int_t len)
Long64_t DavixPReadBuffer(Davix_fd *fd, char *buf, Long64_t pos, Int_t len)
Long64_t DavixWriteBuffer(Davix_fd *fd, const char *buf, Int_t len)
void Seek(Long64_t offset, ERelativeTo pos=kBeg) override
Set position from where to start reading.
TDavixFile(const char *url, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault)
Open function for TDavixFile.
void enableGridMode()
Enable the grid mode The grid Mode configure automatically all grid-CA path, VOMS authentication and ...
Bool_t ReadBuffer(char *buf, Int_t len) override
Read specified byte range from remote file via HTTP.
Bool_t ReadBufferAsync(Long64_t offs, Int_t len) override
TDavixFileInternal * d_ptr
void Init(Bool_t init) override
Initialize a TFile object.
void eventStop(Double_t t, Long64_t len, bool read=true)
set TFile state info
void setCACheck(Bool_t check)
Enable or disable certificate authority check.
Bool_t ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf) override
Read the nbuf blocks described in arrays pos and len.
Int_t fReadCalls
Number of read calls ( not counting the cache calls ).
static void SetFileBytesWritten(Long64_t bytes=0)
Long64_t fBytesRead
Number of bytes read from this file.
static Long64_t GetFileBytesWritten()
Static function returning the total number of bytes written to all files.
static void SetFileBytesRead(Long64_t bytes=0)
static void SetFileReadCalls(Int_t readcalls=0)
static Long64_t GetFileBytesRead()
Static function returning the total number of bytes read from all files.
Long64_t fArchiveOffset
!Offset at which file starts in archive
virtual void Init(Bool_t create)
Initialize a TFile object.
TFile(const TFile &)=delete
Long64_t fBytesWrite
Number of bytes written to this file.
Long64_t fOffset
!Seek offset cache
Long64_t fEND
Last used byte in file.
static Int_t GetFileReadCalls()
Static function returning the total number of read calls from all files.
The TTimeStamp encapsulates seconds and ns since EPOCH.
bool isno(const char *str)