XRootD
Loading...
Searching...
No Matches
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),
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

References XrdClHttp::CurlOperation::CurlOperation(), m_buffer, m_buffer_size, and m_op.

Referenced by XrdClHttp::CurlPgReadOp::CurlPgReadOp(), and XrdClHttp::CurlPrefetchOpenOp::CurlPrefetchOpenOp().

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

◆ ~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
const uint64_t kLogXrdClHttp
const uint16_t errInternal
Internal error.

References 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)

References 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)
const uint16_t stError
An error occurred that could potentially be retried.

References 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

◆ 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}

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

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 &)

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.

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}

References 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.

669{nullptr}; // Buffer passed by XrdCl; we do not own it.

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

◆ m_buffer_size

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

Definition at line 670 of file XrdClHttpOps.hh.

670{0}; // Size of the provided buffer

Referenced by CurlReadOp(), and 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 CurlReadOp(), Fail(), Setup(), XrdClHttp::CurlPgReadOp::Success(), and Success().

◆ m_written

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

Definition at line 668 of file XrdClHttpOps.hh.

668{0}; // Bytes written into the current client-provided buffer

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


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