XRootD
XrdClHttp::CurlStatOp Class Reference

#include <XrdClHttpOps.hh>

+ Inheritance diagram for XrdClHttp::CurlStatOp:
+ Collaboration diagram for XrdClHttp::CurlStatOp:

Public Member Functions

 CurlStatOp (XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, XrdCl::Log *log, bool response_info, CreateConnCalloutType callout, HeaderCallout *header_callout)
 
virtual ~CurlStatOp ()
 
std::pair< int64_t, bool > GetStatInfo ()
 
virtual HttpVerb GetVerb () const override
 
virtual void OptionsDone () override
 
RedirectAction Redirect (std::string &target) override
 
void ReleaseHandle () override
 
virtual bool RequiresOptions () const override
 
bool Setup (CURL *curl, CurlWorker &) override
 
void Success () override
 
- Public Member Functions inherited from XrdClHttp::CurlOperation
 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 ()
 
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
 
CURLGetCurlHandle () const
 
OpError GetError () const
 
std::chrono::steady_clock::time_point GetHeaderExpiry () const
 
std::chrono::steady_clock::time_point GetOperationExpiry ()
 
std::unique_ptr< ResponseInfoGetResponseInfo ()
 
int GetStatusCode () const
 
std::string GetStatusMessage () const
 
bool GetTriedBoker () const
 
const std::string & GetUrl () const
 
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< ResponseInfoMoveResponseInfo ()
 
bool OperationTimeoutExpired (const std::chrono::steady_clock::time_point &now)
 
virtual void SetContinueQueue (std::shared_ptr< XrdClHttp::HandlerQueue > queue)
 
void SetTriedBoker ()
 
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 ()
 
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)
 

Protected Member Functions

void SuccessImpl (bool returnObj)
 
- Protected Member Functions inherited from XrdClHttp::CurlOperation
int FailCallback (XErrorCode ecode, const std::string &emsg)
 
void SetDone (bool has_failed)
 
void SetPaused (bool paused)
 
void UpdateBytes (uint64_t bytes)
 

Additional Inherited Members

- Public Types inherited from XrdClHttp::CurlOperation
using HeaderList = std::vector< std::pair< std::string, std::string > >
 
enum class  HttpVerb {
  COPY ,
  DELETE ,
  HEAD ,
  GET ,
  MKCOL ,
  OPTIONS ,
  PROPFIND ,
  PUT ,
  Count
}
 
enum  OpError {
  ErrNone ,
  ErrHeaderTimeout ,
  ErrCallback ,
  ErrOperationTimeout ,
  ErrTransferClientStall ,
  ErrTransferStall ,
  ErrTransferSlow
}
 
enum class  RedirectAction {
  Fail ,
  Reinvoke ,
  ReinvokeAfterAllow
}
 
- Static Public Member Functions inherited from XrdClHttp::CurlOperation
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 Attributes inherited from XrdClHttp::CurlOperation
std::unique_ptr< CURL, void(*)(CURL *)> m_curl
 
XrdCl::ResponseHandlerm_handler {nullptr}
 
HeaderCalloutm_header_callout
 
std::chrono::steady_clock::time_point m_header_expiry
 
HeaderParser m_headers
 
std::vector< std::pair< std::string, std::string > > m_headers_list
 
XrdCl::Logm_logger
 
int m_minimum_rate {m_minimum_transfer_rate}
 
std::chrono::steady_clock::time_point m_operation_expiry
 
const std::string m_url
 
- Static Protected Attributes inherited from XrdClHttp::CurlOperation
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 445 of file XrdClHttpOps.hh.

Constructor & Destructor Documentation

◆ CurlStatOp()

XrdClHttp::CurlStatOp::CurlStatOp ( XrdCl::ResponseHandler handler,
const std::string &  url,
struct timespec  timeout,
XrdCl::Log log,
bool  response_info,
CreateConnCalloutType  callout,
HeaderCallout header_callout 
)
inline

Definition at line 447 of file XrdClHttpOps.hh.

448  :
449  CurlOperation(handler, url, timeout, log, callout, header_callout),
450  m_response_info(response_info)
451  {
453  }
CurlOperation(XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, XrdCl::Log *log, CreateConnCalloutType, HeaderCallout *header_callout)
std::chrono::steady_clock::time_point m_header_expiry
std::chrono::steady_clock::time_point m_operation_expiry

References XrdClHttp::CurlOperation::m_header_expiry, and XrdClHttp::CurlOperation::m_operation_expiry.

◆ ~CurlStatOp()

virtual XrdClHttp::CurlStatOp::~CurlStatOp ( )
inlinevirtual

Definition at line 455 of file XrdClHttpOps.hh.

455 {}

Member Function Documentation

◆ GetStatInfo()

std::pair< int64_t, bool > CurlStatOp::GetStatInfo ( )

Definition at line 148 of file XrdClHttpOpStat.cc.

148  {
149  if (!m_is_propfind) {
150  m_length = m_headers.GetContentLength();
151  return {m_length, false};
152  }
153  if (m_length >= 0) {
154  return {m_length, m_is_dir};
155  }
156 
157  TiXmlDocument doc;
158  doc.Parse(m_response.c_str());
159  if (doc.Error()) {
160  m_logger->Error(kLogXrdClHttp, "Failed to parse XML response: %s", m_response.substr(0, 1024).c_str());
161  return {-1, false};
162  }
163 
164  auto elem = doc.RootElement();
165  if (strcasecmp(elem->Value(), "D:multistatus")) {
166  m_logger->Error(kLogXrdClHttp, "Unexpected XML response: %s", m_response.substr(0, 1024).c_str());
167  return {-1, false};
168  }
169  auto found_response = false;
170  for (auto response = elem->FirstChildElement(); response != nullptr; response = response->NextSiblingElement()) {
171  if (!strcasecmp(response->Value(), "D:response")) {
172  found_response = true;
173  elem = response;
174  break;
175  }
176  }
177  if (!found_response) {
178  m_logger->Error(kLogXrdClHttp, "Failed to find response element in XML response: %s", m_response.substr(0, 1024).c_str());
179  return {-1, false};
180  }
181  for (auto child = elem->FirstChildElement(); child != nullptr; child = child->NextSiblingElement()) {
182  if (strcasecmp(child->Value(), "D:propstat")) {
183  continue;
184  }
185  for (auto prop = child->FirstChildElement(); prop != nullptr; prop = prop->NextSiblingElement()) {
186  if (!strcasecmp(prop->Value(), "D:prop")) {
187  return ParseProp(prop);
188  }
189  }
190  }
191  m_logger->Error(kLogXrdClHttp, "Failed to find properties in XML response: %s", m_response.substr(0, 1024).c_str());
192  return {-1, false};
193 }
static void child()
int64_t GetContentLength() const
void Error(uint64_t topic, const char *format,...)
Report an error.
Definition: XrdClLog.cc:231
const uint64_t kLogXrdClHttp

References child(), XrdCl::Log::Error(), XrdClHttp::HeaderParser::GetContentLength(), XrdClHttp::kLogXrdClHttp, XrdClHttp::CurlOperation::m_headers, and XrdClHttp::CurlOperation::m_logger.

Referenced by XrdClHttp::CurlOpenOp::Success(), and SuccessImpl().

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

◆ GetVerb()

virtual HttpVerb XrdClHttp::CurlStatOp::GetVerb ( ) const
inlineoverridevirtual

Implements XrdClHttp::CurlOperation.

Reimplemented in XrdClHttp::CurlChecksumOp.

Definition at line 467 of file XrdClHttpOps.hh.

467 {return m_is_propfind ? HttpVerb::PROPFIND : HttpVerb::HEAD;}

◆ OptionsDone()

void CurlStatOp::OptionsDone ( )
overridevirtual

Reimplemented from XrdClHttp::CurlOperation.

Reimplemented in XrdClHttp::CurlChecksumOp.

Definition at line 34 of file XrdClHttpOpStat.cc.

35 {
36  auto &instance = VerbsCache::Instance();
37  auto target = m_headers.GetLocation();
38  auto verbs = instance.Get(target.empty() ? m_url : target);
39  if (verbs.IsSet(VerbsCache::HttpVerb::kPROPFIND)) {
40  curl_easy_setopt(m_curl.get(), CURLOPT_CUSTOMREQUEST, "PROPFIND");
41  m_headers_list.emplace_back("Depth", "0");
42  curl_easy_setopt(m_curl.get(), CURLOPT_NOBODY, 0L);
43  m_is_propfind = true;
44  } else {
45  m_is_propfind = false;
46  curl_easy_setopt(m_curl.get(), CURLOPT_NOBODY, 1L);
47  }
48 }
const std::string m_url
std::unique_ptr< CURL, void(*)(CURL *)> m_curl
std::vector< std::pair< std::string, std::string > > m_headers_list
const std::string & GetLocation() const
static VerbsCache & Instance()

References XrdClHttp::HeaderParser::GetLocation(), XrdClHttp::VerbsCache::Instance(), XrdClHttp::VerbsCache::kPROPFIND, XrdClHttp::CurlOperation::m_curl, XrdClHttp::CurlOperation::m_headers, XrdClHttp::CurlOperation::m_headers_list, and XrdClHttp::CurlOperation::m_url.

+ Here is the call graph for this function:

◆ Redirect()

CurlOperation::RedirectAction CurlStatOp::Redirect ( std::string &  target)
overridevirtual

Reimplemented from XrdClHttp::CurlOperation.

Reimplemented in XrdClHttp::CurlChecksumOp.

Definition at line 51 of file XrdClHttpOpStat.cc.

52 {
53  auto headers = m_headers;
54  auto result = CurlOperation::Redirect(target);
55  if (result == CurlOperation::RedirectAction::Fail) {
56  return result;
57  }
58  auto &instance = VerbsCache::Instance();
59  auto verbs = instance.Get(target);
60  if (verbs.IsSet(VerbsCache::HttpVerb::kUnset)) {
61  m_headers = std::move(headers);
62  return CurlOperation::RedirectAction::ReinvokeAfterAllow;
63  }
64 
65  if (verbs.IsSet(VerbsCache::HttpVerb::kPROPFIND)) {
66  curl_easy_setopt(m_curl.get(), CURLOPT_CUSTOMREQUEST, "PROPFIND");
67  m_headers_list.emplace_back("Depth", "0");
68  curl_easy_setopt(m_curl.get(), CURLOPT_NOBODY, 0L);
69  m_is_propfind = true;
70  } else {
71  m_is_propfind = false;
72  curl_easy_setopt(m_curl.get(), CURLOPT_NOBODY, 1L);
73  }
74  return CurlOperation::RedirectAction::Reinvoke;
75 }
virtual RedirectAction Redirect(std::string &target)

References XrdClHttp::VerbsCache::Instance(), XrdClHttp::VerbsCache::kPROPFIND, XrdClHttp::VerbsCache::kUnset, XrdClHttp::CurlOperation::m_curl, XrdClHttp::CurlOperation::m_headers, XrdClHttp::CurlOperation::m_headers_list, and XrdClHttp::CurlOperation::Redirect().

+ Here is the call graph for this function:

◆ ReleaseHandle()

void CurlStatOp::ReleaseHandle ( )
overridevirtual

Reimplemented from XrdClHttp::CurlOperation.

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

Definition at line 98 of file XrdClHttpOpStat.cc.

99 {
100  if (m_curl == nullptr) return;
101  curl_easy_setopt(m_curl.get(), CURLOPT_NOBODY, 0L);
102  if (m_is_propfind) {
103  curl_easy_setopt(m_curl.get(), CURLOPT_CUSTOMREQUEST, nullptr);
104  }
105  curl_easy_setopt(m_curl.get(), CURLOPT_WRITEFUNCTION, nullptr);
106  curl_easy_setopt(m_curl.get(), CURLOPT_WRITEDATA, nullptr);
108 }
virtual void ReleaseHandle()

References XrdClHttp::CurlOperation::m_curl, and XrdClHttp::CurlOperation::ReleaseHandle().

Referenced by XrdClHttp::CurlOpenOp::ReleaseHandle(), and XrdClHttp::CurlChecksumOp::ReleaseHandle().

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

◆ RequiresOptions()

bool CurlStatOp::RequiresOptions ( ) const
overridevirtual

Reimplemented from XrdClHttp::CurlOperation.

Definition at line 195 of file XrdClHttpOpStat.cc.

196 {
197  auto &instance = VerbsCache::Instance();
198  auto verbs = instance.Get(m_url);
199  return verbs.IsSet(VerbsCache::HttpVerb::kUnset);
200 }

References XrdClHttp::VerbsCache::Instance(), XrdClHttp::VerbsCache::kUnset, and XrdClHttp::CurlOperation::m_url.

+ Here is the call graph for this function:

◆ Setup()

bool CurlStatOp::Setup ( CURL curl,
CurlWorker worker 
)
overridevirtual

Reimplemented from XrdClHttp::CurlOperation.

Reimplemented in XrdClHttp::CurlChecksumOp.

Definition at line 78 of file XrdClHttpOpStat.cc.

79 {
80  if (!CurlOperation::Setup(curl, worker)) return false;
81  curl_easy_setopt(m_curl.get(), CURLOPT_WRITEFUNCTION, CurlStatOp::WriteCallback);
82  curl_easy_setopt(m_curl.get(), CURLOPT_WRITEDATA, this);
83 
84  auto &instance = VerbsCache::Instance();
85  auto verbs = instance.Get(m_url);
86  if (verbs.IsSet(VerbsCache::HttpVerb::kPROPFIND)) {
87  curl_easy_setopt(m_curl.get(), CURLOPT_CUSTOMREQUEST, "PROPFIND");
88  m_headers_list.emplace_back("Depth", "0");
89  curl_easy_setopt(m_curl.get(), CURLOPT_NOBODY, 0L);
90  m_is_propfind = true;
91  } else {
92  curl_easy_setopt(m_curl.get(), CURLOPT_NOBODY, 1L);
93  }
94  return true;
95 }
virtual bool Setup(CURL *curl, CurlWorker &)

References XrdClHttp::VerbsCache::Instance(), XrdClHttp::VerbsCache::kPROPFIND, XrdClHttp::CurlOperation::m_curl, XrdClHttp::CurlOperation::m_headers_list, XrdClHttp::CurlOperation::m_url, and XrdClHttp::CurlOperation::Setup().

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

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

◆ Success()

void CurlStatOp::Success ( )
overridevirtual

Implements XrdClHttp::CurlOperation.

Reimplemented in XrdClHttp::CurlQueryOp, XrdClHttp::CurlChecksumOp, and XrdClHttp::CurlOpenOp.

Definition at line 202 of file XrdClHttpOpStat.cc.

203 {
204  SuccessImpl(true);
205 }
void SuccessImpl(bool returnObj)

References SuccessImpl().

+ Here is the call graph for this function:

◆ SuccessImpl()

void CurlStatOp::SuccessImpl ( bool  returnObj)
protected

Definition at line 208 of file XrdClHttpOpStat.cc.

209 {
210  SetDone(false);
211  m_logger->Debug(kLogXrdClHttp, "CurlStatOp::Success");
212  if (m_handler == nullptr) {return;}
213  XrdCl::AnyObject *obj = nullptr;
214  if (returnObj) {
215  auto [size, isdir] = GetStatInfo();
216  if (size < 0) {
217  m_logger->Error(kLogXrdClHttp, "Failed to get stat info for %s", m_url.c_str());
218  Fail(XrdCl::errErrorResponse, kXR_FSError, "Server responded without object size");
219  return;
220  }
221  if (m_is_propfind) {
222  m_logger->Debug(kLogXrdClHttp, "Successful propfind operation on %s (size %lld, isdir %d)", m_url.c_str(), static_cast<long long>(size), isdir);
223  } else {
224  m_logger->Debug(kLogXrdClHttp, "Successful stat operation on %s (size %lld)", m_url.c_str(), static_cast<long long>(size));
225  }
226 
227  XrdCl::StatInfo *stat_info;
228  if (m_response_info){
229  auto info = new XrdClHttp::StatResponse("nobody", size,
230  XrdCl::StatInfo::Flags::IsReadable | (isdir ? XrdCl::StatInfo::Flags::IsDir : 0), time(NULL));
231  info->SetResponseInfo(MoveResponseInfo());
232  stat_info = info;
233  } else {
234  stat_info = new XrdCl::StatInfo("nobody", size,
235  XrdCl::StatInfo::Flags::IsReadable | (isdir ? XrdCl::StatInfo::Flags::IsDir : 0), time(NULL));
236  }
237  obj = new XrdCl::AnyObject();
238  obj->Set(stat_info);
239  } else if (m_response_info) {
240  auto info = new XrdClHttp::OpenResponseInfo();
241  info->SetResponseInfo(MoveResponseInfo());
242  obj = new XrdCl::AnyObject();
243  obj->Set(info);
244  }
245 
246  auto handle = m_handler;
247  m_handler = nullptr;
248  handle->HandleResponse(new XrdCl::XRootDStatus(), obj);
249 }
@ kXR_FSError
Definition: XProtocol.hh:1037
void SetDone(bool has_failed)
virtual void Fail(uint16_t errCode, uint32_t errNum, const std::string &)
XrdCl::ResponseHandler * m_handler
std::unique_ptr< ResponseInfo > MoveResponseInfo()
std::pair< int64_t, bool > GetStatInfo()
void Set(Type object, bool own=true)
void Debug(uint64_t topic, const char *format,...)
Print a debug message.
Definition: XrdClLog.cc:282
virtual void HandleResponse(XRootDStatus *status, AnyObject *response)
Object stat info.
const uint16_t errErrorResponse
Definition: XrdClStatus.hh:105

References XrdCl::Log::Debug(), XrdCl::errErrorResponse, XrdCl::Log::Error(), XrdClHttp::CurlOperation::Fail(), GetStatInfo(), XrdCl::ResponseHandler::HandleResponse(), XrdClHttp::kLogXrdClHttp, kXR_FSError, XrdClHttp::CurlOperation::m_handler, XrdClHttp::CurlOperation::m_logger, XrdClHttp::CurlOperation::m_url, XrdClHttp::CurlOperation::MoveResponseInfo(), XrdCl::AnyObject::Set(), and XrdClHttp::CurlOperation::SetDone().

Referenced by XrdClHttp::CurlOpenOp::Fail(), Success(), and XrdClHttp::CurlOpenOp::Success().

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

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