XRootD
XrdClHttp::CurlPutOp Class Referencefinal

#include <XrdClHttpOps.hh>

+ Inheritance diagram for XrdClHttp::CurlPutOp:
+ Collaboration diagram for XrdClHttp::CurlPutOp:

Public Member Functions

 CurlPutOp (XrdCl::ResponseHandler *handler, std::shared_ptr< XrdCl::ResponseHandler > default_handler, const std::string &url, const char *buffer, size_t buffer_size, struct timespec timeout, XrdCl::Log *logger, CreateConnCalloutType callout, HeaderCallout *header_callout)
 
 CurlPutOp (XrdCl::ResponseHandler *handler, std::shared_ptr< XrdCl::ResponseHandler > default_handler, const std::string &url, XrdCl::Buffer &&buffer, struct timespec timeout, XrdCl::Log *logger, CreateConnCalloutType callout, HeaderCallout *header_callout)
 
virtual ~CurlPutOp ()
 
bool Continue (std::shared_ptr< CurlOperation > op, XrdCl::ResponseHandler *handler, const char *buffer, size_t buffer_size)
 
bool Continue (std::shared_ptr< CurlOperation > op, XrdCl::ResponseHandler *handler, XrdCl::Buffer &&buffer)
 
bool ContinueHandle () override
 
void Fail (uint16_t errCode, uint32_t errNum, const std::string &msg) override
 
virtual HttpVerb GetVerb () const override
 
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)
 

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

Constructor & Destructor Documentation

◆ CurlPutOp() [1/2]

CurlPutOp::CurlPutOp ( XrdCl::ResponseHandler handler,
std::shared_ptr< XrdCl::ResponseHandler default_handler,
const std::string &  url,
const char *  buffer,
size_t  buffer_size,
struct timespec  timeout,
XrdCl::Log logger,
CreateConnCalloutType  callout,
HeaderCallout header_callout 
)

Definition at line 27 of file XrdClHttpOpPut.cc.

30  : CurlOperation(handler, url, timeout, logger, callout, header_callout),
31  m_data(buffer, buffer_size),
32  m_default_handler(default_handler)
33 {
34 }
CurlOperation(XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, XrdCl::Log *log, CreateConnCalloutType, HeaderCallout *header_callout)

◆ CurlPutOp() [2/2]

CurlPutOp::CurlPutOp ( XrdCl::ResponseHandler handler,
std::shared_ptr< XrdCl::ResponseHandler default_handler,
const std::string &  url,
XrdCl::Buffer &&  buffer,
struct timespec  timeout,
XrdCl::Log logger,
CreateConnCalloutType  callout,
HeaderCallout header_callout 
)

Definition at line 36 of file XrdClHttpOpPut.cc.

39  : CurlOperation(handler, url, timeout, logger, callout, header_callout),
40  m_owned_buffer(std::move(buffer)),
41  m_data(buffer.GetBuffer(), buffer.GetSize()),
42  m_default_handler(default_handler)
43 {
44 
45 }
const char * GetBuffer(uint32_t offset=0) const
Get the message buffer.
Definition: XrdClBuffer.hh:72
uint32_t GetSize() const
Get the size of the message.
Definition: XrdClBuffer.hh:132

◆ ~CurlPutOp()

virtual XrdClHttp::CurlPutOp::~CurlPutOp ( )
inlinevirtual

Definition at line 879 of file XrdClHttpOps.hh.

879 {}

Member Function Documentation

◆ Continue() [1/2]

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

Definition at line 145 of file XrdClHttpOpPut.cc.

146 {
147  if (op.get() != this) {
148  Fail(XrdCl::errInternal, 0, "Interface error: must provide shared pointer to self");
149  return false;
150  }
151  m_handler = handler;
152  m_data = std::string_view(buffer, buffer_size);
153  if (!buffer_size)
154  {
155  m_final = true;
156  }
157 
158  try {
159  m_continue_queue->Produce(op);
160  } catch (...) {
161  Fail(XrdCl::errInternal, ENOMEM, "Failed to continue the curl operation");
162  return false;
163  }
164  return true;
165 }
XrdCl::ResponseHandler * m_handler
void Fail(uint16_t errCode, uint32_t errNum, const std::string &msg) override
const uint16_t errInternal
Internal error.
Definition: XrdClStatus.hh:56

References XrdCl::errInternal, Fail(), and XrdClHttp::CurlOperation::m_handler.

+ Here is the call graph for this function:

◆ Continue() [2/2]

bool CurlPutOp::Continue ( std::shared_ptr< CurlOperation op,
XrdCl::ResponseHandler handler,
XrdCl::Buffer &&  buffer 
)

Definition at line 168 of file XrdClHttpOpPut.cc.

169 {
170  if (op.get() != this) {
171  Fail(XrdCl::errInternal, 0, "Interface error: must provide shared pointer to self");
172  return false;
173  }
174  m_handler = handler;
175  m_data = std::string_view(buffer.GetBuffer(), buffer.GetSize());
176  if (!buffer.GetSize())
177  {
178  m_final = true;
179  }
180 
181  try {
182  m_continue_queue->Produce(op);
183  } catch (...) {
184  Fail(XrdCl::errInternal, ENOMEM, "Failed to continue the curl operation");
185  return false;
186  }
187  return true;
188 }

References XrdCl::errInternal, Fail(), and XrdClHttp::CurlOperation::m_handler.

+ Here is the call graph for this function:

◆ ContinueHandle()

bool CurlPutOp::ContinueHandle ( )
overridevirtual

Reimplemented from XrdClHttp::CurlOperation.

Definition at line 129 of file XrdClHttpOpPut.cc.

130 {
131  if (!m_curl_handle) {
132  return false;
133  }
134 
135  CURLcode rc;
136  if ((rc = curl_easy_pause(m_curl_handle, CURLPAUSE_CONT)) != CURLE_OK) {
137  m_logger->Error(kLogXrdClHttp, "Failed to continue a paused handle: %s", curl_easy_strerror(rc));
138  return false;
139  }
140  SetPaused(false);
141  return m_curl_handle;
142 }
void SetPaused(bool paused)
void Error(uint64_t topic, const char *format,...)
Report an error.
Definition: XrdClLog.cc:231
const uint64_t kLogXrdClHttp

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

+ Here is the call graph for this function:

◆ Fail()

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

Reimplemented from XrdClHttp::CurlOperation.

Definition at line 48 of file XrdClHttpOpPut.cc.

49 {
50  SetDone(true);
51  if (m_handler == nullptr && m_default_handler == nullptr) {return;}
52  if (!msg.empty()) {
53  m_logger->Debug(kLogXrdClHttp, "PUT operation at offset %llu failed with message: %s", static_cast<long long unsigned>(m_offset), msg.c_str());
54  } else {
55  m_logger->Debug(kLogXrdClHttp, "PUT operation at offset %llu failed with status code %d", static_cast<long long unsigned>(m_offset), errNum);
56  }
57 
58  auto status = new XrdCl::XRootDStatus(XrdCl::stError, errCode, errNum, msg);
59  auto handle = m_handler;
60  m_handler = nullptr;
61  if (handle) handle->HandleResponse(status, nullptr);
62  else m_default_handler->HandleResponse(status, nullptr);
63 }
void SetDone(bool has_failed)
void Debug(uint64_t topic, const char *format,...)
Print a debug message.
Definition: XrdClLog.cc:282
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, XrdClHttp::CurlOperation::m_handler, XrdClHttp::CurlOperation::m_logger, 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::CurlPutOp::GetVerb ( ) const
inlineoverridevirtual

Implements XrdClHttp::CurlOperation.

Definition at line 903 of file XrdClHttpOps.hh.

903 {return HttpVerb::PUT;}

◆ Pause()

void CurlPutOp::Pause ( )

Definition at line 96 of file XrdClHttpOpPut.cc.

97 {
98  SetPaused(true);
99  if (m_handler == nullptr && m_default_handler == nullptr) {
100  m_logger->Warning(kLogXrdClHttp, "Put operation paused with no callback handler");
101  return;
102  }
103  auto handle = m_handler;
104  auto status = new XrdCl::XRootDStatus();
105  m_handler = nullptr;
106  m_owned_buffer.Free();
107  // Note: As soon as this is invoked, another thread may continue and start to manipulate
108  // the CurlPutOp object. To avoid race conditions, all reads/writes to member data must
109  // be done *before* the callback is invoked.
110  if (handle) handle->HandleResponse(status, nullptr);
111  else m_default_handler->HandleResponse(status, nullptr);
112 }
void Free()
Free the buffer.
Definition: XrdClBuffer.hh:99
void Warning(uint64_t topic, const char *format,...)
Report a warning.
Definition: XrdClLog.cc:248

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

+ Here is the call graph for this function:

◆ ReleaseHandle()

void CurlPutOp::ReleaseHandle ( )
overridevirtual

Reimplemented from XrdClHttp::CurlOperation.

Definition at line 81 of file XrdClHttpOpPut.cc.

82 {
83  curl_easy_setopt(m_curl.get(), CURLOPT_READFUNCTION, nullptr);
84  curl_easy_setopt(m_curl.get(), CURLOPT_READDATA, nullptr);
85  curl_easy_setopt(m_curl.get(), CURLOPT_UPLOAD, 0);
86  // If one uses just `-1` here -- instead of casting it to `curl_off_t`, then on Linux
87  // we have observed compilers casting the `-1` to an unsigned, resulting in the file
88  // size being set to 4294967295 instead of "unknown". This causes the second use of the
89  // handle to claim to upload a large file, resulting in the client hanging while waiting
90  // for more input data (which will never come).
91  curl_easy_setopt(m_curl.get(), CURLOPT_INFILESIZE_LARGE, static_cast<curl_off_t>(-1));
93 }
std::unique_ptr< CURL, void(*)(CURL *)> m_curl
virtual void ReleaseHandle()

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

+ Here is the call graph for this function:

◆ SetContinueQueue()

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

Reimplemented from XrdClHttp::CurlOperation.

Definition at line 887 of file XrdClHttpOps.hh.

887  {
888  m_continue_queue = queue;
889  }

◆ Setup()

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

Reimplemented from XrdClHttp::CurlOperation.

Definition at line 66 of file XrdClHttpOpPut.cc.

67 {
68  m_curl_handle = curl;
69  if (!CurlOperation::Setup(curl, worker)) return false;
70 
71  curl_easy_setopt(m_curl.get(), CURLOPT_UPLOAD, 1);
72  curl_easy_setopt(m_curl.get(), CURLOPT_READDATA, this);
73  curl_easy_setopt(m_curl.get(), CURLOPT_READFUNCTION, CurlPutOp::ReadCallback);
74  if (m_object_size >= 0) {
75  curl_easy_setopt(m_curl.get(), CURLOPT_INFILESIZE_LARGE, m_object_size);
76  }
77  return true;
78 }
virtual bool Setup(CURL *curl, CurlWorker &)

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

+ Here is the call graph for this function:

◆ Success()

void CurlPutOp::Success ( )
overridevirtual

Implements XrdClHttp::CurlOperation.

Definition at line 115 of file XrdClHttpOpPut.cc.

116 {
117  SetDone(false);
118  if (m_handler == nullptr) {
119  m_logger->Warning(kLogXrdClHttp, "Put operation succeeded with no callback handler");
120  return;
121  }
122  auto status = new XrdCl::XRootDStatus();
123  auto handle = m_handler;
124  m_handler = nullptr;
125  handle->HandleResponse(status, nullptr);
126 }

References XrdCl::ResponseHandler::HandleResponse(), XrdClHttp::kLogXrdClHttp, XrdClHttp::CurlOperation::m_handler, XrdClHttp::CurlOperation::m_logger, XrdClHttp::CurlOperation::SetDone(), and XrdCl::Log::Warning().

+ Here is the call graph for this function:

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