XRootD
XrdClHttp::CurlOperation Class Referenceabstract

#include <XrdClHttpOps.hh>

+ Inheritance diagram for XrdClHttp::CurlOperation:
+ Collaboration diagram for XrdClHttp::CurlOperation:

Public Types

using HeaderList = std::vector< std::pair< std::string, std::string > >
 
using HttpVerb = XrdClHttp::HttpVerb
 
enum  OpError {
  ErrNone ,
  ErrHeaderTimeout ,
  ErrCallback ,
  ErrOperationTimeout ,
  ErrTransferClientStall ,
  ErrTransferStall ,
  ErrTransferSlow
}
 
enum class  RedirectAction {
  Fail ,
  Reinvoke ,
  ReinvokeAfterAllow
}
 

Public Member Functions

 CurlOperation (const CurlOperation &)=delete
 
 CurlOperation (XrdCl::ResponseHandler *handler, const std::string &url, std::chrono::steady_clock::time_point expiry, XrdCl::Log *log, CreateConnCalloutType, HeaderCallout *header_callout)
 
 CurlOperation (XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, XrdCl::Log *log, CreateConnCalloutType, HeaderCallout *header_callout)
 
virtual ~CurlOperation ()
 
virtual bool ContinueHandle ()
 
void ExtendDeadline (struct timespec timeout)
 
virtual void Fail (uint16_t errCode, uint32_t errNum, const std::string &)
 
bool FinishSetup (CURL *curl)
 
std::pair< XErrorCode, std::string > GetCallbackError () const
 
CreateConnCalloutType GetConnCalloutFunc () const
 
std::string GetCurlErrorMessage () const
 
CURL * GetCurlHandle () const
 
OpError GetError () const
 
std::chrono::steady_clock::time_point GetHeaderExpiry () const
 
std::chrono::steady_clock::time_point GetOperationExpiry ()
 
std::unique_ptr< ResponseInfo > GetResponseInfo ()
 
int GetStatusCode () const
 
std::string GetStatusMessage () const
 
bool GetTriedBoker () const
 
const std::string & GetUrl () const
 
virtual HttpVerb GetVerb () const =0
 
bool HasFailed () const
 
bool HeaderTimeoutExpired (const std::chrono::steady_clock::time_point &now)
 
bool IsDone () const
 
bool IsPaused () const
 
bool IsRedirect () const
 
std::unique_ptr< ResponseInfo > MoveResponseInfo ()
 
bool OperationTimeoutExpired (const std::chrono::steady_clock::time_point &now)
 
virtual void OptionsDone ()
 
virtual RedirectAction Redirect (std::string &target)
 
virtual void ReleaseHandle ()
 
virtual bool RequiresOptions () const
 
virtual void SetContinueQueue (std::shared_ptr< XrdClHttp::HandlerQueue > queue)
 
void SetTriedBoker ()
 
virtual bool Setup (CURL *curl, CurlWorker &)
 
bool StartConnectionCallout (std::string &err)
 
std::tuple< uint64_t, std::chrono::steady_clock::duration, std::chrono::steady_clock::duration, std::chrono::steady_clock::duration > StatisticsReset ()
 
virtual void Success ()=0
 
bool TransferStalled (uint64_t xfer_bytes, const std::chrono::steady_clock::time_point &now)
 
bool UseConnectionCallout ()
 
virtual int WaitSocket ()
 
virtual int WaitSocketCallback (std::string &err)
 

Static Public Member Functions

static void CleanupDnsCache ()
 
static int GetDefaultSlowRateBytesSec ()
 
static int GetDefaultStallTimeout ()
 
static const std::string GetVerbString (HttpVerb)
 
static void SetSlowRateBytesSec (int rate)
 
static void SetStallTimeout (const std::chrono::steady_clock::duration &stall_interval)
 
static void SetStallTimeout (int stall_interval)
 

Protected Member Functions

int FailCallback (XErrorCode ecode, const std::string &emsg)
 
void SetDone (bool has_failed)
 
void SetPaused (bool paused)
 
bool SetupNextRequest (const std::string &url, CurlWorker &worker)
 
void UpdateBytes (uint64_t bytes)
 

Protected Attributes

std::unique_ptr< CURL, void(*)(CURL *)> m_curl
 
XrdCl::ResponseHandler * m_handler {nullptr}
 
HeaderCallout * m_header_callout
 
std::atomic< std::chrono::steady_clock::time_point > m_header_expiry
 
HeaderParser m_headers
 
std::vector< std::pair< std::string, std::string > > m_headers_list
 
XrdCl::Log * m_logger
 
int m_minimum_rate {m_minimum_transfer_rate}
 
std::chrono::steady_clock::time_point m_operation_expiry
 
std::string m_request_url
 
const std::string m_url
 

Static Protected Attributes

static constexpr int m_default_minimum_rate {1024 * 256}
 
static int m_minimum_transfer_rate {CurlOperation::m_default_minimum_rate}
 

Detailed Description

Definition at line 60 of file XrdClHttpOps.hh.

Member Typedef Documentation

◆ HeaderList

using XrdClHttp::CurlOperation::HeaderList = std::vector<std::pair<std::string, std::string> >

Definition at line 62 of file XrdClHttpOps.hh.

◆ HttpVerb

using XrdClHttp::CurlOperation::HttpVerb = XrdClHttp::HttpVerb

Definition at line 63 of file XrdClHttpOps.hh.

Member Enumeration Documentation

◆ OpError

enum XrdClHttp::CurlOperation::OpError
Enumerator
ErrNone 
ErrHeaderTimeout 
ErrCallback 
ErrOperationTimeout 
ErrTransferClientStall 
ErrTransferStall 
ErrTransferSlow 

Definition at line 216 of file XrdClHttpOps.hh.

216  {
217  ErrNone, // No error
218  ErrHeaderTimeout, // Header was not sent back in time
219  ErrCallback, // Error in the read/write callback (e.g., response too large for propfind)
220  ErrOperationTimeout, // Entire curl request operation has timed out
221  ErrTransferClientStall, // Transfer stalled while client had paused it (no data was available)
222  ErrTransferStall, // Transfer has stalled, not receiving any data within 60 seconds
223  ErrTransferSlow, // Average transfer rate is below the minimum
224  };

◆ RedirectAction

enum XrdClHttp::CurlOperation::RedirectAction
strong
Enumerator
Fail 
Reinvoke 
ReinvokeAfterAllow 

Definition at line 145 of file XrdClHttpOps.hh.

145  {
146  Fail, // The redirect parsing failed and Fail() was called
147  Reinvoke, // Reinvoke the curl handle, following redirect
148  ReinvokeAfterAllow, // Reinvoke the Redirect function once the allowed verbs are known.
149  };
virtual void Fail(uint16_t errCode, uint32_t errNum, const std::string &)

Constructor & Destructor Documentation

◆ CurlOperation() [1/3]

XrdClHttp::CurlOperation::CurlOperation ( XrdCl::ResponseHandler *  handler,
const std::string &  url,
struct timespec  timeout,
XrdCl::Log *  log,
CreateConnCalloutType  ,
HeaderCallout *  header_callout 
)

◆ CurlOperation() [2/3]

XrdClHttp::CurlOperation::CurlOperation ( XrdCl::ResponseHandler *  handler,
const std::string &  url,
std::chrono::steady_clock::time_point  expiry,
XrdCl::Log *  log,
CreateConnCalloutType  ,
HeaderCallout *  header_callout 
)

◆ ~CurlOperation()

CurlOperation::~CurlOperation ( )
virtual

Definition at line 191 of file XrdClHttpOps.cc.

191 {}

◆ CurlOperation() [3/3]

XrdClHttp::CurlOperation::CurlOperation ( const CurlOperation &  )
delete

Member Function Documentation

◆ CleanupDnsCache()

void CurlOperation::CleanupDnsCache ( )
static

Definition at line 780 of file XrdClHttpOps.cc.

781 {
782  auto now = std::chrono::steady_clock::now();
783  for (auto it = fake_dns_refcount.begin(); it != fake_dns_refcount.end(); ) {
784  if (it->second->count <= 0 && it->second->IsExpired(now)) {
785  auto rev_iter = reverse_fake_dns_map.find(*it->first);
786  if (rev_iter != reverse_fake_dns_map.end()) {
787  fake_dns_map.erase(rev_iter->second.first);
788  reverse_fake_dns_map.erase(rev_iter);
789  }
790  it = fake_dns_refcount.erase(it);
791  } else {
792  ++it;
793  }
794  }
795 }

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

+ Here is the caller graph for this function:

◆ ContinueHandle()

virtual bool XrdClHttp::CurlOperation::ContinueHandle ( )
inlinevirtual

Reimplemented in XrdClHttp::CurlPutOp, and XrdClHttp::CurlReadOp.

Definition at line 139 of file XrdClHttpOps.hh.

139 {return true;}

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

+ Here is the caller graph for this function:

◆ ExtendDeadline()

void CurlOperation::ExtendDeadline ( struct timespec  timeout)

Definition at line 194 of file XrdClHttpOps.cc.

195 {
196  auto expiry = CalculateExpiry(timeout);
197  auto current = m_header_expiry.load(std::memory_order_relaxed);
198  while (expiry > current &&
199  !m_header_expiry.compare_exchange_weak(current, expiry,
200  std::memory_order_relaxed))
201  ;
202 }
std::chrono::steady_clock::time_point CalculateExpiry(struct timespec timeout)
std::atomic< std::chrono::steady_clock::time_point > m_header_expiry

References CalculateExpiry().

+ Here is the call graph for this function:

◆ Fail()

virtual void XrdClHttp::CurlOperation::Fail ( uint16_t  errCode,
uint32_t  errNum,
const std::string &   
)
virtual

◆ FailCallback()

int CurlOperation::FailCallback ( XErrorCode  ecode,
const std::string &  emsg 
)
protected

Definition at line 221 of file XrdClHttpOps.cc.

221  {
222  m_callback_error_code = ecode;
223  m_callback_error_str = emsg;
224  m_error = OpError::ErrCallback;
225  m_logger->Debug(kLogXrdClHttp, "%s", emsg.c_str());
226  return 0;
227 }
int emsg(int rc, char *msg)
void Debug(uint64_t topic, const char *format,...)
Print a debug message.
Definition: XrdClLog.cc:282
const uint64_t kLogXrdClHttp

References emsg().

Referenced by XrdClHttp::CurlVectorReadOp::Write().

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

◆ FinishSetup()

bool CurlOperation::FinishSetup ( CURL *  curl)

Definition at line 230 of file XrdClHttpOps.cc.

231 {
232  if(m_parsed_url)
233  {
234  InjectBearerToken(*m_parsed_url, m_headers_list, m_logger);
235  }
236 
237  // The client asks every request to carry the headers given by the HttpHeaders
238  // environment setting. HeaderBuilder interprets the contents.
239  std::string spec;
240  if (auto env = XrdCl::DefaultEnv::GetEnv()) {
241  env->GetString("HttpHeaders", spec);
242  }
243 
244  if (!spec.empty()) {
245  // Refuse to send anything when the requested headers could not be understood;
246  // quietly omitting them changes what the request asks for.
247  //
248  // Fail here rather than leaving it to the caller, whose failure message for a
249  // setup error would suggest the wrong cause entirely.
250  HeaderList requested;
251  if (!HeaderBuilder::Build(spec, requested)) {
252  m_logger->Error(kLogXrdClHttp, "Not sending request to %s: the requested"
253  " headers could not be used", m_url.c_str());
254  Fail(XrdCl::errInvalidArgs, EINVAL, "Invalid header requested");
255  return false;
256  }
258  }
259 
260  if (!m_header_callout) {
261  m_header_slist.reset();
262  for (const auto &header : m_headers_list) {
263  m_header_slist.reset(curl_slist_append(m_header_slist.release(),
264  (header.first + ": " + header.second).c_str()));
265  }
266  return curl_easy_setopt(curl, CURLOPT_HTTPHEADER, m_header_slist.get()) == CURLE_OK;
267  }
268  const auto &verb = GetVerbString(GetVerb());
269 
270  auto extra_headers = m_header_callout->GetHeaders(
272  if (!extra_headers) {
274  "Failed to get headers from header callout for %s",
275  m_request_url.c_str());
276  return false;
277  }
278  m_header_slist.reset();
279  for (const auto &header : *extra_headers) {
280  if (HeaderBuilder::CompareIgnoreCase(header.first, "Content-Length")) {
281  auto upload_size = std::stoull(header.second);
282  curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, upload_size);
283  continue;
284  }
285  m_header_slist.reset(curl_slist_append(m_header_slist.release(),
286  (header.first + ": " + header.second).c_str()));
287  }
288  return curl_easy_setopt(curl, CURLOPT_HTTPHEADER, m_header_slist.get()) == CURLE_OK;
289 }
static unsigned long long int stoull(const std::string &s)
simple integer parsing, to be replaced by std::stoll when C++11 can be used
std::vector< std::pair< std::string, std::string > > HeaderList
Definition: XrdClHttpOps.hh:62
const std::string m_url
static const std::string GetVerbString(HttpVerb)
virtual HttpVerb GetVerb() const =0
std::vector< std::pair< std::string, std::string > > m_headers_list
HeaderCallout * m_header_callout
virtual std::shared_ptr< HeaderList > GetHeaders(const std::string &verb, const std::string &url, const HeaderList &headers)=0
static Env * GetEnv()
Get default client environment.
void Error(uint64_t topic, const char *format,...)
Report an error.
Definition: XrdClLog.cc:231
bool CompareIgnoreCase(const std::string_view lhs, const std::string_view rhs)
void AppendMissing(const HeaderList &extra, HeaderList &headers)
bool Build(const std::string_view spec, HeaderList &headers)
void InjectBearerToken(const XrdCl::URL &url, std::vector< std::pair< std::string, std::string >> &headers, XrdCl::Log *logger=nullptr)
const uint16_t errInvalidArgs
Definition: XrdClStatus.hh:58

References XrdClHttp::HeaderBuilder::AppendMissing(), XrdClHttp::HeaderBuilder::Build(), XrdClHttp::HeaderBuilder::CompareIgnoreCase(), XrdCl::errInvalidArgs, XrdCl::DefaultEnv::GetEnv(), XrdClHttp::InjectBearerToken(), and stoull().

Referenced by XrdClHttp::CurlWorker::Run(), and XrdClHttp::CurlTapeOp::Success().

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

◆ GetCallbackError()

std::pair<XErrorCode, std::string> XrdClHttp::CurlOperation::GetCallbackError ( ) const
inline

Definition at line 236 of file XrdClHttpOps.hh.

236 {return std::make_pair(m_callback_error_code, m_callback_error_str);}

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

+ Here is the caller graph for this function:

◆ GetConnCalloutFunc()

CreateConnCalloutType XrdClHttp::CurlOperation::GetConnCalloutFunc ( ) const
inline

Definition at line 92 of file XrdClHttpOps.hh.

92 {return m_conn_callout;}

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

+ Here is the caller graph for this function:

◆ GetCurlErrorMessage()

std::string XrdClHttp::CurlOperation::GetCurlErrorMessage ( ) const
inline

Definition at line 262 of file XrdClHttpOps.hh.

262  {
263  if (m_curl_error_buffer[0] != '\0')
264  return m_curl_error_buffer;
265  return "";
266  }

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

+ Here is the caller graph for this function:

◆ GetCurlHandle()

CURL* XrdClHttp::CurlOperation::GetCurlHandle ( ) const
inline

Definition at line 227 of file XrdClHttpOps.hh.

227 {return m_curl.get();}
std::unique_ptr< CURL, void(*)(CURL *)> m_curl

References m_curl.

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

+ Here is the caller graph for this function:

◆ GetDefaultSlowRateBytesSec()

static int XrdClHttp::CurlOperation::GetDefaultSlowRateBytesSec ( )
inlinestatic

Definition at line 288 of file XrdClHttpOps.hh.

289  {
290  return m_default_minimum_rate;
291  }
static constexpr int m_default_minimum_rate

References m_default_minimum_rate.

◆ GetDefaultStallTimeout()

static int XrdClHttp::CurlOperation::GetDefaultStallTimeout ( )
inlinestatic

Definition at line 282 of file XrdClHttpOps.hh.

283  {
284  return std::chrono::duration_cast<std::chrono::seconds>(m_default_stall_interval).count();
285  }

◆ GetError()

OpError XrdClHttp::CurlOperation::GetError ( ) const
inline

Definition at line 230 of file XrdClHttpOps.hh.

230 {return m_error;}

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

+ Here is the caller graph for this function:

◆ GetHeaderExpiry()

std::chrono::steady_clock::time_point XrdClHttp::CurlOperation::GetHeaderExpiry ( ) const
inline

Definition at line 103 of file XrdClHttpOps.hh.

103  {
104  return m_header_expiry.load(std::memory_order_relaxed);
105  }

References m_header_expiry.

Referenced by XrdClHttp::CurlStatOp::CurlStatOp(), and GetOperationExpiry().

+ Here is the caller graph for this function:

◆ GetOperationExpiry()

std::chrono::steady_clock::time_point XrdClHttp::CurlOperation::GetOperationExpiry ( )
inline

Definition at line 116 of file XrdClHttpOps.hh.

116  {
117  if (m_last_xfer != std::chrono::steady_clock::time_point()) {
118  return m_last_xfer + m_stall_interval;
119  }
120  // Headers have arrived but no payload byte has been accounted for yet.
121  // The header deadline no longer applies (HeaderTimeoutExpired stops
122  // enforcing it at the same point), so anchor the stall clock on the
123  // last header activity instead of reviving a deadline that is moot.
124  if (m_received_header) {
125  return m_header_lastop + m_stall_interval;
126  }
127  return GetHeaderExpiry();
128  }
std::chrono::steady_clock::time_point GetHeaderExpiry() const

References GetHeaderExpiry().

+ Here is the call graph for this function:

◆ GetResponseInfo()

std::unique_ptr<ResponseInfo> XrdClHttp::CurlOperation::GetResponseInfo ( )

◆ GetStatusCode()

int XrdClHttp::CurlOperation::GetStatusCode ( ) const
inline

Definition at line 239 of file XrdClHttpOps.hh.

239 {return m_headers.GetStatusCode();}

References XrdClHttp::HeaderParser::GetStatusCode(), and m_headers.

Referenced by XrdClHttp::CurlTapeOp::Fail(), XrdClHttp::CurlMkcolOp::Fail(), XrdClHttp::CurlWorker::Run(), XrdClHttp::CurlTapeOp::Success(), and XrdClHttp::CurlVectorReadOp::Write().

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

◆ GetStatusMessage()

std::string XrdClHttp::CurlOperation::GetStatusMessage ( ) const
inline

Definition at line 242 of file XrdClHttpOps.hh.

242 {return m_headers.GetStatusMessage();}
std::string GetStatusMessage() const

References XrdClHttp::HeaderParser::GetStatusMessage(), and m_headers.

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

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

◆ GetTriedBoker()

bool XrdClHttp::CurlOperation::GetTriedBoker ( ) const
inline

Definition at line 177 of file XrdClHttpOps.hh.

177 {return m_tried_broker;} // Returns true if the connection broker has been tried.

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

+ Here is the caller graph for this function:

◆ GetUrl()

const std::string& XrdClHttp::CurlOperation::GetUrl ( ) const
inline

Definition at line 187 of file XrdClHttpOps.hh.

187 {return m_request_url;}

References m_request_url.

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

+ Here is the caller graph for this function:

◆ GetVerb()

◆ GetVerbString()

const std::string CurlOperation::GetVerbString ( CurlOperation::HttpVerb  verb)
static

Definition at line 292 of file XrdClHttpOps.cc.

293 {
294  switch (verb) {
295  case HttpVerb::COPY:
296  return "COPY";
297  case HttpVerb::DELETE:
298  return "DELETE";
299  case HttpVerb::GET:
300  return "GET";
301  case HttpVerb::POST:
302  return "POST";
303  case HttpVerb::HEAD:
304  return "HEAD";
305  case HttpVerb::MKCOL:
306  return "MKCOL";
307  case HttpVerb::OPTIONS:
308  return "OPTIONS";
309  case HttpVerb::PROPFIND:
310  return "PROPFIND";
311  case HttpVerb::PUT:
312  return "PUT";
313  case HttpVerb::Count:
314  return "UNKNOWN";
315  }
316  return "UNKNOWN";
317 }

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

+ Here is the caller graph for this function:

◆ HasFailed()

bool XrdClHttp::CurlOperation::HasFailed ( ) const
inline

Definition at line 251 of file XrdClHttpOps.hh.

251 {return m_has_failed.load(std::memory_order_acquire);}

◆ HeaderTimeoutExpired()

bool CurlOperation::HeaderTimeoutExpired ( const std::chrono::steady_clock::time_point &  now)

Definition at line 502 of file XrdClHttpOps.cc.

502  {
503  if (m_received_header) return false;
504 
505  if (now > GetHeaderExpiry()) {
506  if (m_error == OpError::ErrNone) m_error = OpError::ErrHeaderTimeout;
507  return true;
508  }
509  return false;
510 }

◆ IsDone()

bool XrdClHttp::CurlOperation::IsDone ( ) const
inline

Definition at line 245 of file XrdClHttpOps.hh.

245 {return m_done;}

Referenced by XrdClHttp::CurlReadOp::ContinueHandle(), and XrdClHttp::CurlWorker::Run().

+ Here is the caller graph for this function:

◆ IsPaused()

bool XrdClHttp::CurlOperation::IsPaused ( ) const
inline

Definition at line 248 of file XrdClHttpOps.hh.

248 {return m_is_paused;}

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

+ Here is the caller graph for this function:

◆ IsRedirect()

bool XrdClHttp::CurlOperation::IsRedirect ( ) const
inline

Definition at line 161 of file XrdClHttpOps.hh.

161 {return m_headers.GetStatusCode() >= 300 && m_headers.GetStatusCode() < 400;}

References XrdClHttp::HeaderParser::GetStatusCode(), and m_headers.

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

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

◆ MoveResponseInfo()

std::unique_ptr<ResponseInfo> XrdClHttp::CurlOperation::MoveResponseInfo ( )
inline

Definition at line 233 of file XrdClHttpOps.hh.

233 {return std::move(m_response_info);}

Referenced by XrdClHttp::CurlChecksumOp::Success(), XrdClHttp::CurlDeleteOp::Success(), XrdClHttp::CurlMkcolOp::Success(), XrdClHttp::CurlListdirOp::Success(), and XrdClHttp::CurlStatOp::SuccessImpl().

+ Here is the caller graph for this function:

◆ OperationTimeoutExpired()

bool CurlOperation::OperationTimeoutExpired ( const std::chrono::steady_clock::time_point &  now)

Definition at line 513 of file XrdClHttpOps.cc.

513  {
514  if (m_operation_expiry == std::chrono::steady_clock::time_point{} ||
515  !m_received_header) {
516  return false;
517  }
518 
519  if (now > m_operation_expiry) {
520  if (m_error == OpError::ErrNone) m_error = OpError::ErrOperationTimeout;
521  return true;
522  }
523  return false;
524 }
std::chrono::steady_clock::time_point m_operation_expiry

◆ OptionsDone()

virtual void XrdClHttp::CurlOperation::OptionsDone ( )
inlinevirtual

Reimplemented in XrdClHttp::CurlChecksumOp, and XrdClHttp::CurlStatOp.

Definition at line 184 of file XrdClHttpOps.hh.

184 {}

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

+ Here is the caller graph for this function:

◆ Redirect()

CurlOperation::RedirectAction CurlOperation::Redirect ( std::string &  target)
virtual

Reimplemented in XrdClHttp::CurlChecksumOp, and XrdClHttp::CurlStatOp.

Definition at line 352 of file XrdClHttpOps.cc.

353 {
354  m_callout.reset();
355  m_conn_callout_result = -1;
356  m_conn_callout_listener = -1;
357  m_tried_broker = false;
358 
359  auto location = m_headers.GetLocation();
360  if (location.empty()) {
361  m_logger->Warning(kLogXrdClHttp, "After request to %s, server returned a redirect with no new location", m_request_url.c_str());
362  Fail(XrdCl::errErrorResponse, kXR_ServerError, "Server returned redirect without updated location");
363  return RedirectAction::Fail;
364  }
365  if (location.size() && location[0] == '/') { // hostname not included in the location - redirect to self.
366  std::string_view orig_url(m_request_url);
367  auto scheme_loc = orig_url.find("://");
368  if (scheme_loc == std::string_view::npos) {
369  Fail(XrdCl::errErrorResponse, kXR_ServerError, "Server returned a location with unknown hostname");
370  return RedirectAction::Fail;
371  }
372  auto path_loc = orig_url.find('/', scheme_loc + 3);
373  if (path_loc == std::string_view::npos) {
374  location = m_request_url + location;
375  } else {
376  location = std::string(orig_url.substr(0, path_loc)) + location;
377  }
378  }
379  m_logger->Debug(kLogXrdClHttp, "Request for %s redirected to %s", m_request_url.c_str(), location.c_str());
380  m_request_url = DavToHttp(location);
381  target = m_request_url;
382  curl_easy_setopt(m_curl.get(), CURLOPT_URL, m_request_url.c_str());
383  int disable_x509;
384  auto env = XrdCl::DefaultEnv::GetEnv();
385  if (env->GetInt("HttpDisableX509", disable_x509) && !disable_x509) {
386  std::string cert, key;
387  env->GetString("HttpClientCertFile", cert);
388  env->GetString("HttpClientKeyFile", key);
389  if (!cert.empty())
390  curl_easy_setopt(m_curl.get(), CURLOPT_SSLCERT, cert.c_str());
391  if (!key.empty())
392  curl_easy_setopt(m_curl.get(), CURLOPT_SSLKEY, key.c_str());
393  }
394  m_headers = HeaderParser();
395 
396  if (m_conn_callout) {
397  auto conn_callout = m_conn_callout(m_request_url, *m_response_info);
398  if (conn_callout != nullptr) {
399 
400  auto [host, port] = ParseHostPort(m_request_url);
401  if (host.empty() || port == -1) {
402  Fail(XrdCl::errInternal, 0, "Failed to parse host and port from URL " + m_request_url);
403  return RedirectAction::Fail;
404  }
405  auto fake_addr = GetFakeEndpointForHost(host, port);
406  if (!fake_addr || fake_addr->empty()) {
407  Fail(XrdCl::errInternal, 0, "Failed to generate a fake address for host " + host);
408  return RedirectAction::Fail;
409  }
410  m_resolve_slist.reset(curl_slist_append(m_resolve_slist.release(),
411  (host + ":" + std::to_string(port) + ":" + *fake_addr).c_str()));
412  m_logger->Debug(kLogXrdClHttp, "For connection callout in redirect, mapping %s:%d -> %s", host.c_str(), port, fake_addr->c_str());
413 
414  m_callout.reset(conn_callout);
415  std::string err;
416  SetTriedBoker();
417  // BeginCallout takes the expiration by non-const reference; hand it
418  // a copy rather than the atomic's storage.
419  auto expiry = GetHeaderExpiry();
420  if ((m_conn_callout_listener = m_callout->BeginCallout(err, expiry)) == -1) {
421  auto errMsg = "Failed to start a connection callout request: " + err;
422  Fail(XrdCl::errInternal, 0, errMsg.c_str());
423  return RedirectAction::Fail;
424  }
425  curl_easy_setopt(m_curl.get(), CURLOPT_OPENSOCKETFUNCTION, CurlOperation::OpenSocketCallback);
426  curl_easy_setopt(m_curl.get(), CURLOPT_CLOSESOCKETFUNCTION, CurlOperation::CloseSocketCallback);
427  curl_easy_setopt(m_curl.get(), CURLOPT_OPENSOCKETDATA, this);
428  curl_easy_setopt(m_curl.get(), CURLOPT_CLOSESOCKETDATA, fake_addr);
429  curl_easy_setopt(m_curl.get(), CURLOPT_SOCKOPTFUNCTION, CurlOperation::SockOptCallback);
430  curl_easy_setopt(m_curl.get(), CURLOPT_SOCKOPTDATA, this);
431  curl_easy_setopt(m_curl.get(), CURLOPT_CONNECT_TO, m_resolve_slist.get());
432  }
433  }
434  m_received_header = false;
435 
436  m_last_header_reset = m_last_reset = m_header_start = m_start_op = m_header_lastop = std::chrono::steady_clock::now();
437  return RedirectAction::Reinvoke;
438 }
@ kXR_ServerError
Definition: XProtocol.hh:1044
const std::string & GetLocation() const
void Warning(uint64_t topic, const char *format,...)
Report a warning.
Definition: XrdClLog.cc:248
const uint16_t errErrorResponse
Definition: XrdClStatus.hh:105
const uint16_t errInternal
Internal error.
Definition: XrdClStatus.hh:56

References XrdCl::errErrorResponse, XrdCl::errInternal, XrdCl::DefaultEnv::GetEnv(), and kXR_ServerError.

Referenced by XrdClHttp::CurlStatOp::Redirect(), XrdClHttp::CurlChecksumOp::Redirect(), and XrdClHttp::CurlWorker::Run().

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

◆ ReleaseHandle()

void CurlOperation::ReleaseHandle ( )
virtual

Reimplemented in XrdClHttp::CurlPutOp, XrdClHttp::CurlCopyOp, XrdClHttp::CurlListdirOp, XrdClHttp::CurlVectorReadOp, XrdClHttp::CurlReadOp, XrdClHttp::CurlTapeOp, XrdClHttp::CurlMkcolOp, XrdClHttp::CurlDeleteOp, XrdClHttp::CurlChecksumOp, XrdClHttp::CurlOpenOp, XrdClHttp::CurlStatOp, and XrdClHttp::CurlOptionsOp.

Definition at line 688 of file XrdClHttpOps.cc.

689 {
690  m_conn_callout_listener = -1;
691  m_conn_callout_result = -1;
692  m_tried_broker = false;
693  m_callout.reset();
694 
695  if (m_curl == nullptr) return;
696  curl_easy_setopt(m_curl.get(), CURLOPT_OPENSOCKETFUNCTION, nullptr);
697  curl_easy_setopt(m_curl.get(), CURLOPT_CLOSESOCKETFUNCTION, nullptr);
698  curl_easy_setopt(m_curl.get(), CURLOPT_OPENSOCKETDATA, nullptr);
699  curl_easy_setopt(m_curl.get(), CURLOPT_CLOSESOCKETDATA, nullptr);
700  curl_easy_setopt(m_curl.get(), CURLOPT_SOCKOPTFUNCTION, nullptr);
701  curl_easy_setopt(m_curl.get(), CURLOPT_SOCKOPTDATA, nullptr);
702  curl_easy_setopt(m_curl.get(), CURLOPT_SSLCERT, nullptr);
703  curl_easy_setopt(m_curl.get(), CURLOPT_SSLKEY, nullptr);
704  curl_easy_setopt(m_curl.get(), CURLOPT_HTTPHEADER, nullptr);
705  curl_easy_setopt(m_curl.get(), CURLOPT_CONNECT_TO, nullptr);
706  m_header_slist.reset();
707  m_curl.release();
708 }

Referenced by XrdClHttp::CurlOptionsOp::ReleaseHandle(), XrdClHttp::CurlStatOp::ReleaseHandle(), XrdClHttp::CurlDeleteOp::ReleaseHandle(), XrdClHttp::CurlMkcolOp::ReleaseHandle(), XrdClHttp::CurlTapeOp::ReleaseHandle(), XrdClHttp::CurlReadOp::ReleaseHandle(), XrdClHttp::CurlVectorReadOp::ReleaseHandle(), XrdClHttp::CurlListdirOp::ReleaseHandle(), XrdClHttp::CurlCopyOp::ReleaseHandle(), XrdClHttp::CurlPutOp::ReleaseHandle(), and XrdClHttp::CurlWorker::Run().

+ Here is the caller graph for this function:

◆ RequiresOptions()

virtual bool XrdClHttp::CurlOperation::RequiresOptions ( ) const
inlinevirtual

Reimplemented in XrdClHttp::CurlStatOp.

Definition at line 181 of file XrdClHttpOps.hh.

181 {return false;}

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

+ Here is the caller graph for this function:

◆ SetContinueQueue()

virtual void XrdClHttp::CurlOperation::SetContinueQueue ( std::shared_ptr< XrdClHttp::HandlerQueue >  queue)
inlinevirtual

Reimplemented in XrdClHttp::CurlPutOp, and XrdClHttp::CurlReadOp.

Definition at line 143 of file XrdClHttpOps.hh.

143 {}

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

+ Here is the caller graph for this function:

◆ SetDone()

void XrdClHttp::CurlOperation::SetDone ( bool  has_failed)
inlineprotected

◆ SetPaused()

void CurlOperation::SetPaused ( bool  paused)
protected

Definition at line 451 of file XrdClHttpOps.cc.

451  {
452  m_is_paused = paused;
453  if (m_is_paused) {
454  m_pause_start = std::chrono::steady_clock::now();
455  } else if (m_pause_start != std::chrono::steady_clock::time_point{}) {
456  m_pause_duration += std::chrono::steady_clock::now() - m_pause_start;
457  m_pause_start = std::chrono::steady_clock::time_point{};
458  }
459 }

Referenced by XrdClHttp::CurlReadOp::ContinueHandle(), XrdClHttp::CurlPutOp::ContinueHandle(), XrdClHttp::CurlReadOp::Pause(), and XrdClHttp::CurlPutOp::Pause().

+ Here is the caller graph for this function:

◆ SetSlowRateBytesSec()

static void XrdClHttp::CurlOperation::SetSlowRateBytesSec ( int  rate)
inlinestatic

Definition at line 294 of file XrdClHttpOps.hh.

295  {
297  }
static int m_minimum_transfer_rate

References m_minimum_transfer_rate.

◆ SetStallTimeout() [1/2]

static void XrdClHttp::CurlOperation::SetStallTimeout ( const std::chrono::steady_clock::duration &  stall_interval)
inlinestatic

Definition at line 276 of file XrdClHttpOps.hh.

277  {
278  m_stall_interval = stall_interval;
279  }

◆ SetStallTimeout() [2/2]

static void XrdClHttp::CurlOperation::SetStallTimeout ( int  stall_interval)
inlinestatic

Definition at line 269 of file XrdClHttpOps.hh.

270  {
271  std::chrono::seconds seconds{stall_interval};
272  m_stall_interval = std::chrono::duration_cast<std::chrono::steady_clock::duration>(seconds);
273  }

◆ SetTriedBoker()

void XrdClHttp::CurlOperation::SetTriedBoker ( )
inline

Definition at line 178 of file XrdClHttpOps.hh.

178 {m_tried_broker = true;} // Note that the connection broker has been attempted.

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

+ Here is the caller graph for this function:

◆ Setup()

bool CurlOperation::Setup ( CURL *  curl,
CurlWorker &  worker 
)
virtual

Reimplemented in XrdClHttp::CurlTapeOp, XrdClHttp::CurlPutOp, XrdClHttp::CurlCopyOp, XrdClHttp::CurlListdirOp, XrdClHttp::CurlVectorReadOp, XrdClHttp::CurlReadOp, XrdClHttp::CurlMkcolOp, XrdClHttp::CurlDeleteOp, XrdClHttp::CurlChecksumOp, XrdClHttp::CurlStatOp, and XrdClHttp::CurlOptionsOp.

Definition at line 575 of file XrdClHttpOps.cc.

576 {
577  if (curl == nullptr) {
578  throw std::runtime_error("Unable to setup curl operation with no handle");
579  }
580  struct timespec now;
581  if (clock_gettime(CLOCK_MONOTONIC, &now) == -1) {
582  throw std::runtime_error("Unable to get current time");
583  }
584 
585  m_pause_start = {};
586  m_last_header_reset = m_last_reset = m_start_op = m_header_start = m_header_lastop = std::chrono::steady_clock::now();
587 
588  m_curl.reset(curl);
589  m_curl_error_buffer[0] = '\0';
590  curl_easy_setopt(m_curl.get(), CURLOPT_URL, m_request_url.c_str());
591  curl_easy_setopt(m_curl.get(), CURLOPT_ERRORBUFFER, m_curl_error_buffer);
592  curl_easy_setopt(m_curl.get(), CURLOPT_HEADERFUNCTION, CurlStatOp::HeaderCallback);
593  curl_easy_setopt(m_curl.get(), CURLOPT_HEADERDATA, this);
594  curl_easy_setopt(m_curl.get(), CURLOPT_WRITEFUNCTION, NullCallback);
595  curl_easy_setopt(m_curl.get(), CURLOPT_WRITEDATA, nullptr);
596  curl_easy_setopt(m_curl.get(), CURLOPT_XFERINFOFUNCTION, CurlOperation::XferInfoCallback);
597  curl_easy_setopt(m_curl.get(), CURLOPT_XFERINFODATA, this);
598  curl_easy_setopt(m_curl.get(), CURLOPT_NOPROGRESS, 0L);
599  // Note: libcurl is not threadsafe unless this option is set.
600  // Before we set it, we saw deadlocks (and partial deadlocks) in practice.
601  curl_easy_setopt(m_curl.get(), CURLOPT_NOSIGNAL, 1L);
602 
603  m_parsed_url = std::make_unique<XrdCl::URL>(m_request_url);
604  auto env = XrdCl::DefaultEnv::GetEnv();
605  int disable_x509;
606  if (env->GetInt("HttpDisableX509", disable_x509) && !disable_x509) {
607  auto [cert, key] = worker.ClientX509CertKeyFile();
608  if (!cert.empty()) {
610  "Using client X.509 credential found at %s", cert.c_str());
611  curl_easy_setopt(m_curl.get(), CURLOPT_SSLCERT, cert.c_str());
612  if (key.empty()) {
614  "X.509 client credential specified but not the client key");
615  } else {
616  curl_easy_setopt(m_curl.get(), CURLOPT_SSLKEY, key.c_str());
617  }
618  }
619  }
620 
621  if (m_conn_callout) {
622  ResponseInfo info;
623  auto callout = m_conn_callout(m_request_url, info);
624  if (callout) {
625  m_callout.reset(callout);
626  m_conn_callout_listener = -1;
627  m_conn_callout_result = -1;
628  m_tried_broker = false;
629 
630  auto [host, port] = ParseHostPort(m_request_url);
631  if (host.empty() || port == -1) {
632  throw std::runtime_error(
633  "Failed to parse host and port from URL " + m_request_url);
634  }
635  auto fake_addr = GetFakeEndpointForHost(host, port);
636  if (!fake_addr || fake_addr->empty()) {
637  throw std::runtime_error("Failed to generate a fake address for host " + host);
638  }
639  m_resolve_slist.reset(curl_slist_append(m_resolve_slist.release(),
640  (host + ":" + std::to_string(port) + ":" + *fake_addr).c_str()));
641  m_logger->Debug(kLogXrdClHttp, "For connection callout in operation setup, mapping %s:%d -> %s", host.c_str(), port, fake_addr->c_str());
642 
643  curl_easy_setopt(m_curl.get(), CURLOPT_CONNECT_TO, m_resolve_slist.get());
644 
645  curl_easy_setopt(m_curl.get(), CURLOPT_OPENSOCKETFUNCTION, CurlOperation::OpenSocketCallback);
646  curl_easy_setopt(m_curl.get(), CURLOPT_CLOSESOCKETFUNCTION, CurlOperation::CloseSocketCallback);
647  curl_easy_setopt(m_curl.get(), CURLOPT_OPENSOCKETDATA, this);
648  curl_easy_setopt(m_curl.get(), CURLOPT_CLOSESOCKETDATA, fake_addr);
649  curl_easy_setopt(m_curl.get(), CURLOPT_SOCKOPTFUNCTION, CurlOperation::SockOptCallback);
650  curl_easy_setopt(m_curl.get(), CURLOPT_SOCKOPTDATA, this);
651  }
652  }
653 
654  return true;
655 }

References XrdClHttp::CurlWorker::ClientX509CertKeyFile(), and XrdCl::DefaultEnv::GetEnv().

Referenced by XrdClHttp::CurlWorker::Run(), XrdClHttp::CurlOptionsOp::Setup(), XrdClHttp::CurlStatOp::Setup(), XrdClHttp::CurlDeleteOp::Setup(), XrdClHttp::CurlMkcolOp::Setup(), XrdClHttp::CurlReadOp::Setup(), XrdClHttp::CurlVectorReadOp::Setup(), XrdClHttp::CurlListdirOp::Setup(), XrdClHttp::CurlCopyOp::Setup(), XrdClHttp::CurlPutOp::Setup(), and XrdClHttp::CurlTapeOp::Setup().

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

◆ SetupNextRequest()

bool CurlOperation::SetupNextRequest ( const std::string &  url,
CurlWorker &  worker 
)
protected

Definition at line 658 of file XrdClHttpOps.cc.

659 {
660  if (!m_curl) return false;
661 
662  curl_easy_reset(m_curl.get());
663  ConfigureHandle(m_curl.get(), false);
664 
665  m_request_url = DavToHttp(url);
666  m_headers = HeaderParser();
667  m_headers_list.clear();
668  m_header_slist.reset();
669  m_response_info.reset();
670  m_resolve_slist.reset();
671  m_callout.reset();
672  m_conn_callout_listener = -1;
673  m_conn_callout_result = -1;
674  m_tried_broker = false;
675  m_received_header = false;
676  m_error = OpError::ErrNone;
677  m_callback_error_code = kXR_noErrorYet;
678  m_callback_error_str.clear();
679  m_last_xfer = {};
680  m_last_xfer_count = 0;
681  m_ema_rate = -1.0;
682 
683  CURL *curl = m_curl.release();
684  return CurlOperation::Setup(curl, worker);
685 }
@ kXR_noErrorYet
Definition: XProtocol.hh:1069
void CURL
virtual bool Setup(CURL *curl, CurlWorker &)
void ConfigureHandle(CURL *curl, bool verbose)

References XrdClHttp::ConfigureHandle(), and kXR_noErrorYet.

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

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

◆ StartConnectionCallout()

bool CurlOperation::StartConnectionCallout ( std::string &  err)

Definition at line 462 of file XrdClHttpOps.cc.

463 {
464  auto expiry = GetHeaderExpiry();
465  if ((m_conn_callout_listener = m_callout->BeginCallout(err, expiry)) == -1) {
466  err = "Failed to start a callout for a socket connection: " + err;
467  Fail(XrdCl::errInternal, 1, err.c_str());
468  return false;
469  }
470  return true;
471 }

References XrdCl::errInternal.

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

+ Here is the caller graph for this function:

◆ StatisticsReset()

std::tuple< uint64_t, std::chrono::steady_clock::duration, std::chrono::steady_clock::duration, std::chrono::steady_clock::duration > CurlOperation::StatisticsReset ( )

Definition at line 474 of file XrdClHttpOps.cc.

474  {
475  auto now = std::chrono::steady_clock::now();
476  std::chrono::steady_clock::duration pre_header{}, post_header{}, pause_duration{};
477  if (m_received_header) {
478  if (m_last_header_reset < m_header_start) {
479  pre_header = m_header_start - m_last_header_reset;
480  m_last_header_reset = m_header_start;
481  }
482  post_header = now - ((m_last_reset < m_header_start) ? m_header_start : m_last_reset);
483  m_last_reset = now;
484  } else {
485  pre_header = now - m_last_header_reset;
486  m_last_header_reset = now;
487  }
488  if (IsPaused()) {
489  m_pause_duration += now - m_pause_start;
490  m_pause_start = now;
491  }
492  if (m_pause_duration != std::chrono::steady_clock::duration::zero()) {
493  pause_duration = m_pause_duration;
494  m_pause_duration = std::chrono::steady_clock::duration::zero();
495  }
496  auto bytes = m_bytes;
497  m_bytes = 0;
498  return {bytes, pre_header, post_header, pause_duration};
499 }

◆ Success()

virtual void XrdClHttp::CurlOperation::Success ( )
pure virtual

◆ TransferStalled()

bool CurlOperation::TransferStalled ( uint64_t  xfer_bytes,
const std::chrono::steady_clock::time_point &  now 
)

Definition at line 527 of file XrdClHttpOps.cc.

528 {
529  // First, check to see how long it's been since any data was sent.
530  if (m_last_xfer == std::chrono::steady_clock::time_point()) {
531  m_last_xfer = m_header_lastop;
532  }
533  auto elapsed = now - m_last_xfer;
534  uint64_t xfer_diff = 0;
535  if (xfer > m_last_xfer_count) {
536  xfer_diff = xfer - m_last_xfer_count;
537  m_last_xfer_count = xfer;
538  m_last_xfer = now;
539  }
540 
541  // If progress is made in this callback do not classify as stalled
542  if (elapsed > m_stall_interval && xfer_diff == 0) {
543  if (m_error == OpError::ErrNone) m_error = IsPaused() ? OpError::ErrTransferClientStall : OpError::ErrTransferStall;
544  return true;
545  }
546 
547  // Curl updated us with new timing but the byte count hasn't changed; no need to update the EMA.
548  if (xfer_diff == 0) {
549  return false;
550  }
551 
552  // If the transfer is not stalled, then we check to see if the exponentially-weighted
553  // moving average of the transfer rate is below the minimum.
554 
555  // If the stall interval since the last header hasn't passed, then we don't check for slow transfers.
556  auto elapsed_since_last_headerop = now - m_header_lastop;
557  if (elapsed_since_last_headerop < m_stall_interval) {
558  return false;
559  } else if (m_ema_rate < 0) {
560  m_ema_rate = xfer / std::chrono::duration<double>(elapsed_since_last_headerop).count();
561  }
562  // Calculate the exponential moving average of the transfer rate.
563  double elapsed_seconds = std::chrono::duration<double>(elapsed).count();
564  auto recent_rate = static_cast<double>(xfer_diff) / elapsed_seconds;
565  auto alpha = 1.0 - exp(-elapsed_seconds / std::chrono::duration<double>(m_stall_interval).count());
566  m_ema_rate = (1.0 - alpha) * m_ema_rate + alpha * recent_rate;
567  if (m_ema_rate < static_cast<double>(m_minimum_rate)) {
568  if (m_error == OpError::ErrNone) m_error = OpError::ErrTransferSlow;
569  return true;
570  }
571  return false;
572 }

◆ UpdateBytes()

void XrdClHttp::CurlOperation::UpdateBytes ( uint64_t  bytes)
inlineprotected

Definition at line 307 of file XrdClHttpOps.hh.

307 {m_bytes += bytes;}

Referenced by XrdClHttp::CurlVectorReadOp::Write().

+ Here is the caller graph for this function:

◆ UseConnectionCallout()

bool XrdClHttp::CurlOperation::UseConnectionCallout ( )
inline

Definition at line 176 of file XrdClHttpOps.hh.

176 {return m_callout.get();} // Returns true if the callout should be tried.

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

+ Here is the caller graph for this function:

◆ WaitSocket()

virtual int XrdClHttp::CurlOperation::WaitSocket ( )
inlinevirtual

Definition at line 164 of file XrdClHttpOps.hh.

164 {return m_conn_callout_listener;}

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

+ Here is the caller graph for this function:

◆ WaitSocketCallback()

int CurlOperation::WaitSocketCallback ( std::string &  err)
virtual

Definition at line 813 of file XrdClHttpOps.cc.

814 {
815  m_conn_callout_result = m_callout ? m_callout->FinishCallout(err) : -1;
816  if (m_callout && m_conn_callout_result == -1) {
817  m_logger->Error(kLogXrdClHttp, "Error when getting socket callout: %s", err.c_str());
818  } else if (m_callout) {
819  m_logger->Debug(kLogXrdClHttp, "Got callback socket %d", m_conn_callout_result);
820  }
821  return m_conn_callout_result;
822 }

Member Data Documentation

◆ m_curl

◆ m_default_minimum_rate

constexpr int XrdClHttp::CurlOperation::m_default_minimum_rate {1024 * 256}
staticconstexprprotected

Definition at line 319 of file XrdClHttpOps.hh.

Referenced by GetDefaultSlowRateBytesSec().

◆ m_handler

◆ m_header_callout

HeaderCallout* XrdClHttp::CurlOperation::m_header_callout
protected

Definition at line 339 of file XrdClHttpOps.hh.

◆ m_header_expiry

std::atomic<std::chrono::steady_clock::time_point> XrdClHttp::CurlOperation::m_header_expiry
protected

Definition at line 336 of file XrdClHttpOps.hh.

Referenced by GetHeaderExpiry().

◆ m_headers

◆ m_headers_list

◆ m_logger

◆ m_minimum_rate

int XrdClHttp::CurlOperation::m_minimum_rate {m_minimum_transfer_rate}
protected

◆ m_minimum_transfer_rate

int CurlOperation::m_minimum_transfer_rate {CurlOperation::m_default_minimum_rate}
staticprotected

Definition at line 324 of file XrdClHttpOps.hh.

Referenced by SetSlowRateBytesSec().

◆ m_operation_expiry

std::chrono::steady_clock::time_point XrdClHttp::CurlOperation::m_operation_expiry
protected

Definition at line 330 of file XrdClHttpOps.hh.

Referenced by XrdClHttp::CurlStatOp::CurlStatOp().

◆ m_request_url

std::string XrdClHttp::CurlOperation::m_request_url
protected

Definition at line 414 of file XrdClHttpOps.hh.

Referenced by GetUrl(), and XrdClHttp::CurlTapeOp::Setup().

◆ m_url


The documentation for this class was generated from the following files: