XRootD
XrdClHttp::CurlReadOp Class Reference

#include <XrdClHttpOps.hh>

+ Inheritance diagram for XrdClHttp::CurlReadOp:
+ Collaboration diagram for XrdClHttp::CurlReadOp:

Public Member Functions

 CurlReadOp (XrdCl::ResponseHandler *handler, std::shared_ptr< XrdCl::ResponseHandler > default_handler, const std::string &url, struct timespec timeout, const std::pair< uint64_t, uint64_t > &op, char *buffer, size_t sz, XrdCl::Log *logger, CreateConnCalloutType callout, HeaderCallout *header_callout)
 
virtual ~CurlReadOp ()
 
bool Continue (std::shared_ptr< CurlOperation > op, XrdCl::ResponseHandler *handler, char *buffer, size_t buffer_size)
 
bool ContinueHandle () override
 
void Fail (uint16_t errCode, uint32_t errNum, const std::string &msg) override
 
virtual HttpVerb GetVerb () const override
 
virtual void Pause ()
 
void ReleaseHandle () override
 
virtual void SetContinueQueue (std::shared_ptr< XrdClHttp::HandlerQueue > queue) 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 ()
 
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 OptionsDone ()
 
virtual RedirectAction Redirect (std::string &target)
 
virtual bool RequiresOptions () const
 
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 Attributes

char * m_buffer {nullptr}
 
size_t m_buffer_size {0}
 
std::shared_ptr< XrdClHttp::HandlerQueuem_continue_queue
 
std::string m_err_msg
 
std::pair< uint64_t, uint64_t > m_op
 
uint64_t m_written {0}
 
- 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
 

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 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)
 
- 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 611 of file XrdClHttpOps.hh.

Constructor & Destructor Documentation

◆ CurlReadOp()

CurlReadOp::CurlReadOp ( XrdCl::ResponseHandler handler,
std::shared_ptr< XrdCl::ResponseHandler default_handler,
const std::string &  url,
struct timespec  timeout,
const std::pair< uint64_t, uint64_t > &  op,
char *  buffer,
size_t  sz,
XrdCl::Log logger,
CreateConnCalloutType  callout,
HeaderCallout header_callout 
)

Definition at line 30 of file XrdClHttpOpRead.cc.

33  :
34  CurlOperation(handler, url, timeout, logger, callout, header_callout),
35  m_default_handler(default_handler),
36  m_op(op),
37  m_buffer(buffer),
38  m_buffer_size(sz)
39  {}
CurlOperation(XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, XrdCl::Log *log, CreateConnCalloutType, HeaderCallout *header_callout)
std::pair< uint64_t, uint64_t > m_op

◆ ~CurlReadOp()

virtual XrdClHttp::CurlReadOp::~CurlReadOp ( )
inlinevirtual

Definition at line 617 of file XrdClHttpOps.hh.

617 {}

Member Function Documentation

◆ Continue()

bool CurlReadOp::Continue ( std::shared_ptr< CurlOperation op,
XrdCl::ResponseHandler handler,
char *  buffer,
size_t  buffer_size 
)

Definition at line 42 of file XrdClHttpOpRead.cc.

43 {
44  if (op.get() != this) {
45  m_logger->Debug(kLogXrdClHttp, "Interface error: must provide shared pointer to self");
46  Fail(XrdCl::errInternal, 0, "Interface error: must provide shared pointer to self");
47  return false;
48  }
49  m_handler = handler;
50  m_buffer = buffer;
51  m_buffer_size = buffer_size;
52  m_written = 0;
53 
54  if (!m_prefetch_buffer.empty()) {
55  auto prefetch_remaining = m_prefetch_buffer.size() - m_prefetch_buffer_offset;
56  auto to_copy = prefetch_remaining > buffer_size ? buffer_size : prefetch_remaining;
57  m_written += to_copy;
58  memcpy(buffer, m_prefetch_buffer.data() + m_prefetch_buffer_offset, to_copy);
59  m_prefetch_buffer_offset += to_copy;
60  if (m_prefetch_buffer_offset == m_prefetch_buffer.size()) {
61  m_prefetch_buffer.clear();
62  m_prefetch_buffer_offset = 0;
63  }
64  }
65 
66  // This handles the case where the transfer finished but its last WriteCallback
67  // produced more data than the client buffer could hold, the excess being stored
68  // in the prefetch buffer
69  // we just need to deliver the response without re-queuing to the continue queue
70  if (op->IsDone()) {
71  DeliverResponse();
72  } else {
73  try {
74  m_continue_queue->Produce(op);
75  } catch (...) {
76  Fail(XrdCl::errInternal, ENOMEM, "Failed to continue the curl operation");
77  return false;
78  }
79  }
80 
81  return true;
82 }
XrdCl::ResponseHandler * m_handler
void Fail(uint16_t errCode, uint32_t errNum, const std::string &msg) override
std::shared_ptr< XrdClHttp::HandlerQueue > m_continue_queue
void Debug(uint64_t topic, const char *format,...)
Print a debug message.
Definition: XrdClLog.cc:282
const uint16_t errInternal
Internal error.
Definition: XrdClStatus.hh:56
const uint64_t kLogXrdClHttp

References XrdCl::Log::Debug(), XrdCl::errInternal, Fail(), XrdClHttp::kLogXrdClHttp, m_buffer, m_buffer_size, m_continue_queue, XrdClHttp::CurlOperation::m_handler, XrdClHttp::CurlOperation::m_logger, and m_written.

+ Here is the call graph for this function:

◆ ContinueHandle()

bool CurlReadOp::ContinueHandle ( )
overridevirtual

Reimplemented from XrdClHttp::CurlOperation.

Definition at line 85 of file XrdClHttpOpRead.cc.

86 {
87  if (IsDone()) {
88  return false;
89  }
90  if (!m_curl) {
91  return false;
92  }
93 
94  CURLcode rc;
95  if ((rc = curl_easy_pause(m_curl.get(), CURLPAUSE_CONT)) != CURLE_OK) {
96  m_logger->Error(kLogXrdClHttp, "Failed to continue a paused handle: %s", curl_easy_strerror(rc));
97  return false;
98  }
99  SetPaused(false);
100  return m_curl.get();
101  }
std::unique_ptr< CURL, void(*)(CURL *)> m_curl
void SetPaused(bool paused)
void Error(uint64_t topic, const char *format,...)
Report an error.
Definition: XrdClLog.cc:231

References XrdCl::Log::Error(), XrdClHttp::CurlOperation::IsDone(), XrdClHttp::kLogXrdClHttp, XrdClHttp::CurlOperation::m_curl, XrdClHttp::CurlOperation::m_logger, and XrdClHttp::CurlOperation::SetPaused().

+ Here is the call graph for this function:

◆ Fail()

void CurlReadOp::Fail ( uint16_t  errCode,
uint32_t  errNum,
const std::string &  msg 
)
overridevirtual

Reimplemented from XrdClHttp::CurlOperation.

Definition at line 137 of file XrdClHttpOpRead.cc.

138 {
139  std::string custom_msg = msg;
140  SetDone(true);
141  if (m_handler == nullptr && m_default_handler == nullptr) {return;}
142  if (!custom_msg.empty()) {
143  m_logger->Debug(kLogXrdClHttp, "curl operation at offset %llu failed with message: %s%s", static_cast<long long unsigned>(m_op.first), msg.c_str(), m_err_msg.empty() ? "" : (", server message: " + m_err_msg).c_str());
144  custom_msg += " (read operation at offset " + std::to_string(static_cast<long long unsigned>(m_op.first)) + ")";
145  } else {
146  m_logger->Debug(kLogXrdClHttp, "curl operation at offset %llu failed with status code %d%s", static_cast<long long unsigned>(m_op.first), errNum, m_err_msg.empty() ? "" : (", server message: " + m_err_msg).c_str());
147  }
148  auto status = new XrdCl::XRootDStatus(XrdCl::stError, errCode, errNum, custom_msg);
149  auto handle = m_handler;
150  m_handler = nullptr;
151  if (handle) handle->HandleResponse(status, nullptr);
152  else m_default_handler->HandleResponse(status, nullptr);
153 }
void SetDone(bool has_failed)
virtual void HandleResponse(XRootDStatus *status, AnyObject *response)
const uint16_t stError
An error occurred that could potentially be retried.
Definition: XrdClStatus.hh:32

References XrdCl::Log::Debug(), XrdCl::ResponseHandler::HandleResponse(), XrdClHttp::kLogXrdClHttp, m_err_msg, XrdClHttp::CurlOperation::m_handler, XrdClHttp::CurlOperation::m_logger, m_op, XrdClHttp::CurlOperation::SetDone(), and XrdCl::stError.

Referenced by Continue().

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

◆ GetVerb()

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

Implements XrdClHttp::CurlOperation.

Reimplemented in XrdClHttp::CurlPgReadOp.

Definition at line 638 of file XrdClHttpOps.hh.

638 {return HttpVerb::GET;}

◆ Pause()

void CurlReadOp::Pause ( )
virtual

Reimplemented in XrdClHttp::CurlPrefetchOpenOp.

Definition at line 179 of file XrdClHttpOpRead.cc.

180 {
181  SetPaused(true);
182  if (m_handler == nullptr) {
183  m_logger->Warning(kLogXrdClHttp, "Get operation paused with no callback handler");
184  return;
185  }
186  DeliverResponse();
187 }
void Warning(uint64_t topic, const char *format,...)
Report a warning.
Definition: XrdClLog.cc:248

References XrdClHttp::kLogXrdClHttp, XrdClHttp::CurlOperation::m_handler, XrdClHttp::CurlOperation::m_logger, XrdClHttp::CurlOperation::SetPaused(), and XrdCl::Log::Warning().

Referenced by XrdClHttp::CurlPrefetchOpenOp::Pause().

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

◆ ReleaseHandle()

void CurlReadOp::ReleaseHandle ( )
overridevirtual

Reimplemented from XrdClHttp::CurlOperation.

Definition at line 205 of file XrdClHttpOpRead.cc.

206 {
207  if (m_curl == nullptr) return;
208  curl_easy_setopt(m_curl.get(), CURLOPT_WRITEFUNCTION, nullptr);
209  curl_easy_setopt(m_curl.get(), CURLOPT_WRITEDATA, nullptr);
210  curl_easy_setopt(m_curl.get(), CURLOPT_HTTPHEADER, nullptr);
211  curl_easy_setopt(m_curl.get(), CURLOPT_OPENSOCKETFUNCTION, nullptr);
212  curl_easy_setopt(m_curl.get(), CURLOPT_OPENSOCKETDATA, nullptr);
213  curl_easy_setopt(m_curl.get(), CURLOPT_SOCKOPTFUNCTION, nullptr);
214  curl_easy_setopt(m_curl.get(), CURLOPT_SOCKOPTDATA, nullptr);
216 }
virtual void ReleaseHandle()

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

+ Here is the call graph for this function:

◆ SetContinueQueue()

virtual void XrdClHttp::CurlReadOp::SetContinueQueue ( std::shared_ptr< XrdClHttp::HandlerQueue queue)
inlineoverridevirtual

Reimplemented from XrdClHttp::CurlOperation.

Definition at line 634 of file XrdClHttpOps.hh.

634  {
635  m_continue_queue = queue;
636  }

References m_continue_queue.

◆ Setup()

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

Reimplemented from XrdClHttp::CurlOperation.

Definition at line 104 of file XrdClHttpOpRead.cc.

105 {
106  if (!CurlOperation::Setup(curl, worker)) {return false;}
107 
108  curl_easy_setopt(m_curl.get(), CURLOPT_WRITEFUNCTION, CurlReadOp::WriteCallback);
109  curl_easy_setopt(m_curl.get(), CURLOPT_WRITEDATA, this);
110 
111  // Note: range requests are inclusive of the end byte, meaning "bytes=0-1023" is a 1024-byte request.
112  // This is why we subtract '1' off the end.
113  if (m_op.second == 0) {
114  Success();
115  return true;
116  }
117  if (m_op.second >= 1024*1024) {
118  curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, 128*1024);
119  }
120  else if (m_op.second >= 256*1024) {
121  curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, 64*1024);
122  }
123  else if (m_op.second >= 128*1024) {
124  curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, 32*1024);
125  }
126  // If the requested read size is UINT64_MAX, it means read the entire object;
127  // in this case, we do not set the Range header.
128  if (m_op.second != UINT64_MAX) {
129  auto range_req = "bytes=" + std::to_string(m_op.first) + "-" + std::to_string(m_op.first + m_op.second - 1);
130  m_headers_list.emplace_back("Range", range_req);
131  }
132 
133  return true;
134 }
std::vector< std::pair< std::string, std::string > > m_headers_list
virtual bool Setup(CURL *curl, CurlWorker &)
void Success() override

References XrdClHttp::CurlOperation::m_curl, XrdClHttp::CurlOperation::m_headers_list, m_op, XrdClHttp::CurlOperation::Setup(), and Success().

+ Here is the call graph for this function:

◆ Success()

void CurlReadOp::Success ( )
overridevirtual

Implements XrdClHttp::CurlOperation.

Reimplemented in XrdClHttp::CurlPgReadOp.

Definition at line 190 of file XrdClHttpOpRead.cc.

191 {
192  SetDone(false);
193  if (m_handler == nullptr) {return;}
194  auto status = new XrdCl::XRootDStatus();
195  auto chunk_info = new XrdCl::ChunkInfo(m_op.first + m_prefetch_object_offset, m_written, m_buffer);
196  m_prefetch_object_offset += m_written;
197  auto obj = new XrdCl::AnyObject();
198  obj->Set(chunk_info);
199  auto handle = m_handler;
200  m_handler = nullptr;
201  handle->HandleResponse(status, obj);
202 }
Describe a data chunk for vector read.

References XrdCl::ResponseHandler::HandleResponse(), m_buffer, XrdClHttp::CurlOperation::m_handler, m_op, m_written, and XrdClHttp::CurlOperation::SetDone().

Referenced by Setup().

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

Member Data Documentation

◆ m_buffer

char* XrdClHttp::CurlReadOp::m_buffer {nullptr}
protected

Definition at line 669 of file XrdClHttpOps.hh.

Referenced by Continue(), Success(), and XrdClHttp::CurlPgReadOp::Success().

◆ m_buffer_size

size_t XrdClHttp::CurlReadOp::m_buffer_size {0}
protected

Definition at line 670 of file XrdClHttpOps.hh.

Referenced by Continue().

◆ m_continue_queue

std::shared_ptr<XrdClHttp::HandlerQueue> XrdClHttp::CurlReadOp::m_continue_queue
protected

Definition at line 677 of file XrdClHttpOps.hh.

Referenced by Continue(), and SetContinueQueue().

◆ m_err_msg

std::string XrdClHttp::CurlReadOp::m_err_msg
protected

Definition at line 674 of file XrdClHttpOps.hh.

Referenced by Fail().

◆ m_op

std::pair<uint64_t, uint64_t> XrdClHttp::CurlReadOp::m_op
protected

Definition at line 667 of file XrdClHttpOps.hh.

Referenced by Fail(), Setup(), Success(), and XrdClHttp::CurlPgReadOp::Success().

◆ m_written

uint64_t XrdClHttp::CurlReadOp::m_written {0}
protected

Definition at line 668 of file XrdClHttpOps.hh.

Referenced by Continue(), Success(), and XrdClHttp::CurlPgReadOp::Success().


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