XRootD
XrdClHttp Namespace Reference

Namespaces

 HeaderBuilder
 
 ThirdPartyCopyOpTypes
 

Classes

struct  ChecksumEntry
 
class  ChecksumInfo
 
class  ConnectionCallout
 
class  Factory
 
class  VerbsCache
 

Functions

void ConfigureHandle (CURL *curl, bool verbose)
 
std::string GetBearerToken (XrdCl::Log *logger=nullptr)
 
size_t GetChecksumLength (ChecksumType ctype)
 
CURL * GetHandle (bool verbose)
 
ChecksumType GetTypeFromString (const std::string &str)
 
const std::string GetTypeString (ChecksumType ctype)
 
std::pair< uint16_t, uint32_t > HTTPStatusConvert (unsigned status)
 
bool HTTPStatusIsError (unsigned status)
 
void InjectBearerToken (const XrdCl::URL &url, std::vector< std::pair< std::string, std::string >> &headers, XrdCl::Log *logger=nullptr)
 
std::string_view ltrim_view (const std::string_view &input_view)
 
std::string MarshalDuration (const struct timespec &timeout)
 
bool ParseTimeout (const std::string &duration, struct timespec &, std::string &errmsg)
 
bool ParseTokenFile (const std::string &token_file, CurlCopyOp::Headers &src_hdrs, CurlCopyOp::Headers &dst_hdrs)
 
bool ShouldUseBearerToken (const std::string &protocols, bool hasX509Credential, bool hasBearerToken)
 
static std::optional< std::size_t > stat_size (HandlerQueue &queue, const std::string &url, const CurlCopyOp::Headers &hdrs, time_t timeout, XrdCl::Log *log, const char *what)
 
std::string TapeProblemResponse (long statusCode, const std::string &body)
 
std::string_view trim_view (const std::string_view &input_view)
 

Class Documentation

◆ XrdClHttp::ChecksumEntry

struct XrdClHttp::ChecksumEntry

Definition at line 103 of file XrdClHttpChecksum.hh.

+ Collaboration diagram for XrdClHttp::ChecksumEntry:
Class Members
ChecksumType type
array< unsigned char, g_max_checksum_length > value

Function Documentation

◆ ConfigureHandle()

void XrdClHttp::ConfigureHandle ( CURL *  curl,
bool  verbose 
)

Definition at line 763 of file XrdClHttpUtil.cc.

763  {
764  curl_easy_setopt(curl, CURLOPT_USERAGENT, "xrdcl-http/" XrdVERSION);
765  curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, DumpHeader);
766  curl_easy_setopt(curl, CURLOPT_DEBUGDATA, XrdCl::DefaultEnv::GetLog());
767  if (verbose)
768  curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
769 
770  auto env = XrdCl::DefaultEnv::GetEnv();
771  std::string ca_file;
772  if (!env->GetString("HttpCertFile", ca_file) || ca_file.empty()) {
773  char *x509_ca_file = getenv("X509_CERT_FILE");
774  if (x509_ca_file) {
775  ca_file = std::string(x509_ca_file);
776  }
777  }
778  if (!ca_file.empty()) {
779  curl_easy_setopt(curl, CURLOPT_CAINFO, ca_file.c_str());
780  }
781  std::string ca_dir;
782  if (!env->GetString("HttpCertDir", ca_dir) || ca_dir.empty()) {
783  char *x509_ca_dir = getenv("X509_CERT_DIR");
784  if (x509_ca_dir) {
785  ca_dir = std::string(x509_ca_dir);
786  }
787  }
788  if (!ca_dir.empty()) {
789  curl_easy_setopt(curl, CURLOPT_CAPATH, ca_dir.c_str());
790  }
791 
792  curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, 32*1024);
793 }
static Log * GetLog()
Get default log.
static Env * GetEnv()
Get default client environment.

References XrdCl::DefaultEnv::GetEnv(), and XrdCl::DefaultEnv::GetLog().

Referenced by XrdClHttp::CurlOperation::SetupNextRequest().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetBearerToken()

std::string XrdClHttp::GetBearerToken ( XrdCl::Log *  logger = nullptr)

Definition at line 116 of file XrdClHttpUtil.cc.

117 {
118  auto env = XrdCl::DefaultEnv::GetEnv();
119  if (!env) return {};
120 
121  std::string token;
122  if (!env->GetString("BearerToken", token) || token.empty()) {
123  env->ImportString("BearerToken", "BEARER_TOKEN");
124  env->GetString("BearerToken", token);
125  }
126  if (!token.empty()) {
127  XrdCl::Utils::Trim(token);
128  return token;
129  }
130 
131  std::string token_file;
132  if (!env->GetString("BearerTokenFile", token_file) || token_file.empty()) {
133  env->ImportString("BearerTokenFile", "BEARER_TOKEN_FILE");
134  env->GetString("BearerTokenFile", token_file);
135  }
136  if (token_file.empty()) return {};
137 
138  std::ifstream input(token_file);
139  if (!input) return {};
140  std::getline(input, token);
141  XrdCl::Utils::Trim(token);
142  return token;
143 }
void getline(uchar *buff, int blen)
static void Trim(std::string &str)
Trim a string.
Definition: XrdClUtils.cc:606

References XrdCl::DefaultEnv::GetEnv(), getline(), and XrdCl::Utils::Trim().

Referenced by InjectBearerToken().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetChecksumLength()

size_t XrdClHttp::GetChecksumLength ( ChecksumType  ctype)
inline

Definition at line 65 of file XrdClHttpChecksum.hh.

65  {
66  switch (ctype) {
67  case ChecksumType::kADLER32:
68  case ChecksumType::kCRC32:
69  case ChecksumType::kCRC32C:
70  return 4;
71  case ChecksumType::kMD5:
72  return 16;
73  case ChecksumType::kSHA1:
74  return 20;
75  case ChecksumType::kSHA256:
76  return 32;
77  case ChecksumType::kAll: // fallthrough
78  case ChecksumType::kUnknown:
79  return 0;
80  }
81  return 0;
82 }

Referenced by XrdClHttp::HeaderParser::ParseDigest(), and XrdClHttp::CurlChecksumOp::Success().

+ Here is the caller graph for this function:

◆ GetHandle()

CURL* XrdClHttp::GetHandle ( bool  verbose)

Referenced by XrdClHttp::HandlerQueue::GetHandle().

+ Here is the caller graph for this function:

◆ GetTypeFromString()

ChecksumType XrdClHttp::GetTypeFromString ( const std::string &  str)
inline

Definition at line 84 of file XrdClHttpChecksum.hh.

84  {
85  if (str == "adler" || str == "adler32") {
86  return ChecksumType::kADLER32;
87  } else if (str == "crc32") {
88  return ChecksumType::kCRC32;
89  } else if (str == "crc32c") {
90  return ChecksumType::kCRC32C;
91  } else if (str == "md5") {
92  return ChecksumType::kMD5;
93  } else if (str == "sha1") {
94  return ChecksumType::kSHA1;
95  } else if (str == "sha256") {
96  return ChecksumType::kSHA256;
97  }
98  return ChecksumType::kUnknown;
99 }

◆ GetTypeString()

const std::string XrdClHttp::GetTypeString ( ChecksumType  ctype)
inline

Definition at line 44 of file XrdClHttpChecksum.hh.

44  {
45  switch (ctype) {
46  case ChecksumType::kADLER32:
47  return "adler32";
48  case ChecksumType::kCRC32:
49  return "crc32";
50  case ChecksumType::kCRC32C:
51  return "crc32c";
52  case ChecksumType::kMD5:
53  return "md5";
54  case ChecksumType::kSHA1:
55  return "sha1";
56  case ChecksumType::kSHA256:
57  return "sha256";
58  case ChecksumType::kAll: // fallthrough
59  case ChecksumType::kUnknown:
60  return "unknown";
61  }
62  return "unknown";
63 }

Referenced by XrdClHttp::CurlChecksumOp::Success().

+ Here is the caller graph for this function:

◆ HTTPStatusConvert()

std::pair< uint16_t, uint32_t > XrdClHttp::HTTPStatusConvert ( unsigned  status)

Definition at line 207 of file XrdClHttpUtil.cc.

207  {
208  switch (status) {
209  case 400: // Bad Request
210  return std::make_pair(XrdCl::errErrorResponse, kXR_InvalidRequest);
211  case 401: // Unauthorized (needs authentication)
212  return std::make_pair(XrdCl::errErrorResponse, kXR_NotAuthorized);
213  case 402: // Payment Required
214  case 403: // Forbidden (failed authorization)
215  return std::make_pair(XrdCl::errErrorResponse, kXR_NotAuthorized);
216  case 404:
217  return std::make_pair(XrdCl::errErrorResponse, kXR_NotFound);
218  case 405: // Method not allowed
219  return std::make_pair(XrdCl::errErrorResponse, kXR_Unsupported);
220  case 406: // Not acceptable
221  return std::make_pair(XrdCl::errErrorResponse, kXR_InvalidRequest);
222  case 407: // Proxy Authentication Required
223  return std::make_pair(XrdCl::errErrorResponse, kXR_NotAuthorized);
224  case 408: // Request timeout
225  return std::make_pair(XrdCl::errErrorResponse, kXR_ReqTimedOut);
226  case 409: // Conflict
227  return std::make_pair(XrdCl::errErrorResponse, kXR_Conflict);
228  case 410: // Gone
229  return std::make_pair(XrdCl::errErrorResponse, kXR_NotFound);
230  case 411: // Length required
231  case 412: // Precondition failed
232  case 413: // Payload too large
233  case 414: // URI too long
234  case 415: // Unsupported Media Type
235  case 416: // Range Not Satisfiable
236  case 417: // Expectation Failed
237  case 418: // I'm a teapot
238  return std::make_pair(XrdCl::errErrorResponse, kXR_InvalidRequest);
239  case 421: // Misdirected Request
240  case 422: // Unprocessable Content
241  return std::make_pair(XrdCl::errErrorResponse, kXR_InvalidRequest);
242  case 423: // Locked
243  return std::make_pair(XrdCl::errErrorResponse, kXR_FileLocked);
244  case 424: // Failed Dependency
245  case 425: // Too Early
246  case 426: // Upgrade Required
247  case 428: // Precondition Required
248  return std::make_pair(XrdCl::errErrorResponse, kXR_InvalidRequest);
249  case 429: // Too Many Requests
250  return std::make_pair(XrdCl::errErrorResponse, kXR_Overloaded);
251  case 431: // Request Header Fields Too Large
252  return std::make_pair(XrdCl::errErrorResponse, kXR_InvalidRequest);
253  case 451: // Unavailable For Legal Reasons
254  return std::make_pair(XrdCl::errErrorResponse, kXR_Impossible);
255  case 500: // Internal Server Error
256  return std::make_pair(XrdCl::errErrorResponse, kXR_ServerError);
257  case 501: // Not Implemented
258  return std::make_pair(XrdCl::errErrorResponse, kXR_Unsupported);
259  case 502: // Bad Gateway
260  return std::make_pair(XrdCl::errErrorResponse, kXR_ServerError);
261  case 503: // Service Unavailable
262  return std::make_pair(XrdCl::errErrorResponse, kXR_Overloaded);
263  case 504: // Gateway Timeout
264  return std::make_pair(XrdCl::errErrorResponse, kXR_ReqTimedOut);
265  case 507: // Insufficient Storage
266  return std::make_pair(XrdCl::errErrorResponse, kXR_overQuota);
267  case 508: // Loop Detected
268  case 510: // Not Extended
269  case 511: // Network Authentication Required
270  return std::make_pair(XrdCl::errErrorResponse, kXR_ServerError);
271  }
272  return std::make_pair(XrdCl::errUnknown, status);
273 }
@ kXR_InvalidRequest
Definition: XProtocol.hh:1038
@ kXR_Impossible
Definition: XProtocol.hh:1063
@ kXR_NotAuthorized
Definition: XProtocol.hh:1042
@ kXR_NotFound
Definition: XProtocol.hh:1043
@ kXR_FileLocked
Definition: XProtocol.hh:1035
@ kXR_overQuota
Definition: XProtocol.hh:1053
@ kXR_Unsupported
Definition: XProtocol.hh:1045
@ kXR_Conflict
Definition: XProtocol.hh:1064
@ kXR_ServerError
Definition: XProtocol.hh:1044
@ kXR_Overloaded
Definition: XProtocol.hh:1056
@ kXR_ReqTimedOut
Definition: XProtocol.hh:1066
const uint16_t errUnknown
Unknown error.
Definition: XrdClStatus.hh:50
const uint16_t errErrorResponse
Definition: XrdClStatus.hh:105

References XrdCl::errErrorResponse, XrdCl::errUnknown, kXR_Conflict, kXR_FileLocked, kXR_Impossible, kXR_InvalidRequest, kXR_NotAuthorized, kXR_NotFound, kXR_Overloaded, kXR_overQuota, kXR_ReqTimedOut, kXR_ServerError, and kXR_Unsupported.

Referenced by XrdClHttp::CurlWorker::Run().

+ Here is the caller graph for this function:

◆ HTTPStatusIsError()

bool XrdClHttp::HTTPStatusIsError ( unsigned  status)

Definition at line 112 of file XrdClHttpUtil.cc.

112  {
113  return (status < 100) || (status >= 400);
114 }

Referenced by XrdClHttp::CurlWorker::Run(), and XrdClHttp::CurlVectorReadOp::Write().

+ Here is the caller graph for this function:

◆ InjectBearerToken()

void XrdClHttp::InjectBearerToken ( const XrdCl::URL &  url,
std::vector< std::pair< std::string, std::string >> &  headers,
XrdCl::Log *  logger = nullptr 
)

Definition at line 164 of file XrdClHttpUtil.cc.

168 {
169  if(url.GetParams().count("authz")) return;
170  for(const auto &header : headers)
171  {
172  if(header.first == "Authorization") return;
173  }
174 
175  const std::string token = GetBearerToken(logger);
176  if(token.empty()) return;
177 
178  bool hasX509Credential = false;
179  auto env = XrdCl::DefaultEnv::GetEnv();
180  if(env)
181  {
182  int disableX509 = 0;
183  std::string certificate;
184  hasX509Credential =
185  env->GetInt("HttpDisableX509", disableX509)
186  && !disableX509
187  && env->GetString("HttpClientCertFile", certificate)
188  && !certificate.empty();
189  }
190 
191  const char *configuredProtocols = std::getenv("XrdSecPROTOCOL");
192  if(!ShouldUseBearerToken(configuredProtocols ? configuredProtocols : "",
193  hasX509Credential, true))
194  {
195  return;
196  }
197 
198  if(logger)
199  {
200  logger->Debug(kLogXrdClHttp,
201  "Injecting bearer token from environment for %s",
202  url.GetURL().c_str());
203  }
204  headers.emplace_back("Authorization", "Bearer " + token);
205 }
void Debug(uint64_t topic, const char *format,...)
Print a debug message.
Definition: XrdClLog.cc:282
std::string GetURL() const
Get the URL.
Definition: XrdClURL.hh:86
const ParamsMap & GetParams() const
Get the URL params.
Definition: XrdClURL.hh:244
bool ShouldUseBearerToken(const std::string &protocols, bool hasX509Credential, bool hasBearerToken)
std::string GetBearerToken(XrdCl::Log *logger=nullptr)

References XrdCl::Log::Debug(), GetBearerToken(), XrdCl::DefaultEnv::GetEnv(), XrdCl::URL::GetParams(), XrdCl::URL::GetURL(), kLogXrdClHttp, and ShouldUseBearerToken().

Referenced by XrdClHttp::CurlOperation::FinishSetup().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ltrim_view()

std::string_view XrdClHttp::ltrim_view ( const std::string_view &  input_view)

Definition at line 753 of file XrdClHttpUtil.cc.

753  {
754  for (size_t idx = 0; idx < input_view.size(); idx++) {
755  if (!isspace(input_view[idx])) {
756  return input_view.substr(idx);
757  }
758  }
759  return "";
760 }

Referenced by trim_view(), and XrdClS3::Factory::TrimView().

+ Here is the caller graph for this function:

◆ MarshalDuration()

std::string XrdClHttp::MarshalDuration ( const struct timespec &  timeout)

◆ ParseTimeout()

bool XrdClHttp::ParseTimeout ( const std::string &  duration,
struct timespec &  ,
std::string &  errmsg 
)

◆ ParseTokenFile()

bool XrdClHttp::ParseTokenFile ( const std::string &  token_file,
CurlCopyOp::Headers &  src_hdrs,
CurlCopyOp::Headers &  dst_hdrs 
)

Referenced by XrdClHttp::Filesystem::ThirdPartyCopy().

+ Here is the caller graph for this function:

◆ ShouldUseBearerToken()

bool XrdClHttp::ShouldUseBearerToken ( const std::string &  protocols,
bool  hasX509Credential,
bool  hasBearerToken 
)

Definition at line 145 of file XrdClHttpUtil.cc.

148 {
149  if(protocols.empty()) return hasBearerToken;
150 
151  std::vector<std::string> requested;
152  XrdCl::Utils::splitString(requested, protocols, ",");
153  for(auto protocol : requested)
154  {
155  XrdCl::Utils::Trim(protocol);
156  std::transform(protocol.begin(), protocol.end(), protocol.begin(),
157  [](unsigned char c) { return std::tolower(c); });
158  if(protocol == "gsi" && hasX509Credential) return false;
159  if(protocol == "ztn" && hasBearerToken) return true;
160  }
161  return false;
162 }
static void splitString(Container &result, const std::string &input, const std::string &delimiter)
Split a string.
Definition: XrdClUtils.hh:56

References XrdCl::Utils::splitString(), and XrdCl::Utils::Trim().

Referenced by InjectBearerToken().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ stat_size()

static std::optional<std::size_t> XrdClHttp::stat_size ( HandlerQueue &  queue,
const std::string &  url,
const CurlCopyOp::Headers &  hdrs,
time_t  timeout,
XrdCl::Log *  log,
const char *  what 
)
static

Definition at line 430 of file XrdClHttpFilesystem.cc.

436 {
437  try
438  {
439  const auto callout = std::make_shared<ExtraHeaderCallout>(hdrs);
440  const auto rh = std::make_shared<SyncResponseHandler>();
441  const auto op = std::make_shared<StatOp>(rh.get(), url, timespec{timeout, 0}, log, true, nullptr, callout.get());
442 
443  // The queue may run the operation after this function returns, thus
444  // the operation keeps its handler and header callout alive.
445  queue.Produce(std::shared_ptr<StatOp>(op.get(), [callout, rh, op](auto){}));
446 
447  if (!rh->wait(std::chrono::seconds(timeout)))
448  log->Warning(kLogXrdClHttp, "Failed to stat the %s: Operation timed out", what);
449  else if (!op->IsDone() || op->HasFailed())
450  log->Debug(kLogXrdClHttp, "Failed to stat the %s", what);
451  else
452  return static_cast<std::size_t>(op->GetStatInfo().first);
453  }
454  catch (const std::exception &e) {
455  log->Warning(kLogXrdClHttp, "Failed to stat the %s - %s", what, e.what());
456  }
457 
458  return std::nullopt;
459 }
void Warning(uint64_t topic, const char *format,...)
Report a warning.
Definition: XrdClLog.cc:248

References XrdCl::Log::Debug(), kLogXrdClHttp, and XrdCl::Log::Warning().

Referenced by XrdClHttp::Filesystem::ThirdPartyCopy().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ TapeProblemResponse()

std::string XrdClHttp::TapeProblemResponse ( long  statusCode,
const std::string &  body 
)

Definition at line 1123 of file XrdClHttpTape.cc.

1124  {
1125  return FormatProblemResponse(statusCode, body);
1126  }

Referenced by XrdClHttp::CurlTapeOp::Fail().

+ Here is the caller graph for this function:

◆ trim_view()

std::string_view XrdClHttp::trim_view ( const std::string_view &  input_view)

Definition at line 742 of file XrdClHttpUtil.cc.

742  {
743  auto view = XrdClHttp::ltrim_view(input_view);
744  for (size_t idx = 0; idx < input_view.size(); idx++) {
745  if (!isspace(view[view.size() - 1 - idx])) {
746  return view.substr(0, view.size() - idx);
747  }
748  }
749  return "";
750 }
std::string_view ltrim_view(const std::string_view &input_view)

References ltrim_view().

Referenced by XrdClHttp::HeaderParser::ParseDigest().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: