21#ifndef XRDCLHTTP_CURLOPS_HH
22#define XRDCLHTTP_CURLOPS_HH
58 using HeaderList = std::vector<std::pair<std::string, std::string>>;
92 virtual void Fail(uint16_t errCode, uint32_t errNum,
const std::string &);
114 if (m_last_xfer == std::chrono::steady_clock::time_point()) {
117 return m_last_xfer + m_stall_interval;
204 bool TransferStalled(uint64_t xfer_bytes,
const std::chrono::steady_clock::time_point &now);
226 std::pair<XErrorCode, std::string>
GetCallbackError()
const {
return std::make_pair(m_callback_error_code, m_callback_error_str);}
241 bool HasFailed()
const {
return m_has_failed.load(std::memory_order_acquire);}
249 std::tuple<uint64_t, std::chrono::steady_clock::duration, std::chrono::steady_clock::duration, std::chrono::steady_clock::duration>
StatisticsReset();
253 if (m_curl_error_buffer[0] !=
'\0')
254 return m_curl_error_buffer;
261 std::chrono::seconds seconds{stall_interval};
262 m_stall_interval = std::chrono::duration_cast<std::chrono::steady_clock::duration>(seconds);
266 static void SetStallTimeout(
const std::chrono::steady_clock::duration &stall_interval)
268 m_stall_interval = stall_interval;
274 return std::chrono::duration_cast<std::chrono::seconds>(m_default_stall_interval).count();
324 bool Header(
const std::string &header);
325 static size_t HeaderCallback(
char *buffer,
size_t size,
size_t nitems,
void *data);
328 std::unique_ptr<ResponseInfo> m_response_info;
335 static constexpr std::chrono::steady_clock::duration m_default_stall_interval{std::chrono::seconds(60)};
336 static std::chrono::steady_clock::duration m_stall_interval;
340 std::string m_callback_error_str;
341 bool m_tried_broker{
false};
342 bool m_received_header{
false};
344 std::atomic<bool> m_has_failed{
false};
345 bool m_is_paused{
false};
346 int m_conn_callout_result{-1};
347 int m_conn_callout_listener{-1};
349 std::chrono::steady_clock::time_point m_last_reset{};
350 std::chrono::steady_clock::time_point m_last_header_reset{};
351 std::chrono::steady_clock::time_point m_start_op{};
352 std::chrono::steady_clock::time_point m_header_start{};
353 std::chrono::steady_clock::time_point m_pause_start{};
354 std::chrono::steady_clock::duration m_pause_duration{};
357 std::unique_ptr<
struct curl_slist, void(*)(
struct curl_slist *)> m_header_slist{
nullptr, &curl_slist_free_all};
363 std::chrono::steady_clock::time_point m_header_lastop;
366 std::chrono::steady_clock::time_point m_last_xfer;
369 uint64_t m_last_xfer_count{0};
372 double m_ema_rate{-1.0};
375 char m_curl_error_buffer[CURL_ERROR_SIZE]{};
378 std::unique_ptr<ConnectionCallout> m_callout;
379 std::unique_ptr<XrdCl::URL> m_parsed_url{
nullptr};
382 std::unique_ptr<
struct curl_slist, void(*)(
struct curl_slist *)> m_resolve_slist{
nullptr, &curl_slist_free_all};
384 static curl_socket_t OpenSocketCallback(
void *clientp, curlsocktype purpose,
struct curl_sockaddr *address);
385 static int SockOptCallback(
void *clientp, curl_socket_t curlfd, curlsocktype purpose);
386 static curl_socket_t CloseSocketCallback(
void *clientp, curl_socket_t item);
389 static int XferInfoCallback(
void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
392 void SetDone(
bool has_failed) {m_done =
true; m_has_failed.store(has_failed, std::memory_order_release);}
423 void Fail(uint16_t errCode, uint32_t errNum,
const std::string &)
override;
437 std::shared_ptr<CurlOperation> m_parent;
438 CURL *m_parent_curl{
nullptr};
449 CurlOperation(handler, url, timeout, log, callout, header_callout),
450 m_response_info(response_info)
480 std::pair<int64_t, bool> ParseProp(TiXmlElement *prop);
482 static size_t WriteCallback(
char *buffer,
size_t size,
size_t nitems,
void *this_ptr);
485 bool m_response_info{
false};
487 bool m_is_propfind{
false};
489 bool m_is_dir{
false};
490 std::string m_response;
491 int64_t m_length{-1};
509 void Fail(uint16_t errCode, uint32_t errNum,
const std::string &)
override;
518 void SetOpenProperties(
bool setSize);
565 bool m_response_info{
false};
581 void Fail(uint16_t errCode, uint32_t errNum,
const std::string &msg)
override;
589 bool m_response_info{
false};
598 CurlStatOp(handler, url, timeout, log, response_info, callout, header_callout),
614 const std::string &url,
struct timespec timeout,
const std::pair<uint64_t, uint64_t> &op,
627 virtual void Pause();
630 void Fail(uint16_t errCode, uint32_t errNum,
const std::string &msg)
override;
643 void DeliverResponse();
645 static size_t WriteCallback(
char *buffer,
size_t size,
size_t nitems,
void *this_ptr);
646 size_t Write(
char *buffer,
size_t size);
654 std::string m_prefetch_buffer;
657 size_t m_prefetch_buffer_offset{0};
660 off_t m_prefetch_object_offset{0};
664 std::shared_ptr<XrdCl::ResponseHandler> m_default_handler;
667 std::pair<uint64_t, uint64_t>
m_op;
684 const std::string &url,
struct timespec timeout,
const std::pair<uint64_t, uint64_t> &op,
686 :
CurlReadOp(handler, default_handler, url, timeout, op, buffer, sz, logger, callout, header_callout), m_file(file)
691 virtual void Pause()
override;
694 bool m_first_pause{
true};
707 void Fail(uint16_t errCode, uint32_t errNum,
const std::string &msg)
override;
723 size_t Write(
char *buffer,
size_t size);
728 static size_t WriteCallback(
char *buffer,
size_t size,
size_t nitems,
void *this_ptr);
732 void CalculateNextBuffer();
741 std::unique_ptr<XrdCl::VectorReadInfo>
m_vr;
748 const std::string &url,
struct timespec timeout,
const std::pair<uint64_t, uint64_t> &op,
752 CurlReadOp(handler, default_handler, url, timeout, op, buffer, buffer_size, logger, callout, header_callout)
780 bool m_isexec{
false};
782 time_t m_lastmodified{-1};
788 bool ParseProp(DavEntry &entry, TiXmlElement *prop);
791 const bool m_response_info{
false};
794 std::pair<DavEntry, bool> ParseResponse(TiXmlElement *response);
797 static size_t WriteCallback(
char *buffer,
size_t size,
size_t nitems,
void *this_ptr);
800 bool m_is_origin{
false};
803 std::string m_response;
806 std::string m_host_addr;
814 using Headers = std::vector<std::pair<std::string, std::string>>;
837 static size_t WriteCallback(
char *buffer,
size_t size,
size_t nitems,
void *this_ptr);
840 void HandleLine(std::string_view line);
843 bool ControlChannelTimeoutExpired()
const;
846 std::string m_source_url;
849 std::string m_line_buffer;
852 std::unique_ptr<CurlProgressCallback> m_callback;
855 off_t m_bytemark{-1};
858 bool m_sent_success{
false};
861 std::string m_failure;
871 const std::string &url,
const char *buffer,
size_t buffer_size,
881 void Fail(uint16_t errCode, uint32_t errNum,
const std::string &msg)
override;
888 m_continue_queue = queue;
909 static size_t ReadCallback(
char *buffer,
size_t size,
size_t n,
void *v);
912 CURL *m_curl_handle{
nullptr};
915 std::shared_ptr<XrdClHttp::HandlerQueue> m_continue_queue;
922 std::string_view m_data;
927 std::shared_ptr<XrdCl::ResponseHandler> m_default_handler;
933 off_t m_object_size{-1};
int emsg(int rc, char *msg)
virtual void OptionsDone() override
RedirectAction Redirect(std::string &target) override
void ReleaseHandle() override
CurlChecksumOp(XrdCl::ResponseHandler *handler, const std::string &url, XrdClHttp::ChecksumType preferred, struct timespec timeout, XrdCl::Log *logger, bool response_info, CreateConnCalloutType callout, HeaderCallout *header_callout)
virtual HttpVerb GetVerb() const override
bool Setup(CURL *curl, CurlWorker &) override
virtual ~CurlChecksumOp()
virtual void Progress(off_t bytemark)=0
virtual ~CurlProgressCallback()
virtual HttpVerb GetVerb() const override
std::vector< std::pair< std::string, std::string > > Headers
void ReleaseHandle() override
CurlCopyOp(XrdCl::ResponseHandler *handler, const std::string &source_url, const Headers &source_hdrs, const std::string &dest_url, const Headers &dest_hdrs, struct timespec timeout, XrdCl::Log *logger, CreateConnCalloutType callout)
bool Setup(CURL *curl, CurlWorker &) override
void SetCallback(std::unique_ptr< CurlProgressCallback > callback)
bool Setup(CURL *curl, CurlWorker &) override
CurlDeleteOp(XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, XrdCl::Log *logger, bool response_info, CreateConnCalloutType callout, HeaderCallout *header_callout)
void ReleaseHandle() override
virtual HttpVerb GetVerb() const override
bool Setup(CURL *curl, CurlWorker &) override
CurlListdirOp(XrdCl::ResponseHandler *handler, const std::string &url, const std::string &host_addr, bool response_info, struct timespec timeout, XrdCl::Log *logger, CreateConnCalloutType callout, HeaderCallout *header_callout)
virtual HttpVerb GetVerb() const override
void ReleaseHandle() override
void Fail(uint16_t errCode, uint32_t errNum, const std::string &msg) override
bool Setup(CURL *curl, CurlWorker &) override
virtual HttpVerb GetVerb() const override
void ReleaseHandle() override
CurlMkcolOp(XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, XrdCl::Log *logger, bool response_info, CreateConnCalloutType callout, HeaderCallout *header_callout)
void ReleaseHandle() override
void Fail(uint16_t errCode, uint32_t errNum, const std::string &) override
CurlOpenOp(XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, XrdCl::Log *logger, XrdClHttp::File *file, bool response_info, CreateConnCalloutType callout, HeaderCallout *header_callout)
virtual void OptionsDone()
void SetDone(bool has_failed)
static void SetStallTimeout(const std::chrono::steady_clock::duration &stall_interval)
int FailCallback(XErrorCode ecode, const std::string &emsg)
int GetStatusCode() const
static int m_minimum_transfer_rate
std::chrono::steady_clock::time_point GetHeaderExpiry() const
bool FinishSetup(CURL *curl)
std::unique_ptr< ResponseInfo > MoveResponseInfo()
std::chrono::steady_clock::time_point m_header_expiry
const std::string & GetUrl() const
CURL * GetCurlHandle() const
std::unique_ptr< CURL, void(*)(CURL *)> m_curl
bool TransferStalled(uint64_t xfer_bytes, const std::chrono::steady_clock::time_point &now)
static const std::string GetVerbString(HttpVerb)
bool UseConnectionCallout()
virtual HttpVerb GetVerb() const =0
std::string GetCurlErrorMessage() const
virtual void ReleaseHandle()
void UpdateBytes(uint64_t bytes)
virtual bool RequiresOptions() const
static void CleanupDnsCache()
bool GetTriedBoker() const
std::chrono::steady_clock::time_point GetOperationExpiry()
std::tuple< uint64_t, std::chrono::steady_clock::duration, std::chrono::steady_clock::duration, std::chrono::steady_clock::duration > StatisticsReset()
virtual bool ContinueHandle()
std::string GetStatusMessage() const
static constexpr int m_default_minimum_rate
static void SetSlowRateBytesSec(int rate)
static void SetStallTimeout(int stall_interval)
CreateConnCalloutType GetConnCalloutFunc() const
std::vector< std::pair< std::string, std::string > > HeaderList
std::vector< std::pair< std::string, std::string > > m_headers_list
HeaderCallout * m_header_callout
static int GetDefaultSlowRateBytesSec()
bool HeaderTimeoutExpired(const std::chrono::steady_clock::time_point &now)
virtual int WaitSocketCallback(std::string &err)
std::unique_ptr< ResponseInfo > GetResponseInfo()
std::chrono::steady_clock::time_point m_operation_expiry
virtual void Fail(uint16_t errCode, uint32_t errNum, const std::string &)
virtual RedirectAction Redirect(std::string &target)
XrdCl::ResponseHandler * m_handler
CurlOperation(XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, XrdCl::Log *log, CreateConnCalloutType, HeaderCallout *header_callout)
static int GetDefaultStallTimeout()
void SetPaused(bool paused)
virtual void SetContinueQueue(std::shared_ptr< XrdClHttp::HandlerQueue > queue)
bool StartConnectionCallout(std::string &err)
bool OperationTimeoutExpired(const std::chrono::steady_clock::time_point &now)
CurlOperation(const CurlOperation &)=delete
virtual bool Setup(CURL *curl, CurlWorker &)
std::pair< XErrorCode, std::string > GetCallbackError() const
CurlOptionsOp(CURL *curl, std::shared_ptr< CurlOperation > op, const std::string &url, XrdCl::Log *log, CreateConnCalloutType callout)
virtual HttpVerb GetVerb() const override
std::shared_ptr< CurlOperation > GetOperation() const
CURL * GetParentCurlHandle() const
void ReleaseHandle() override
bool Setup(CURL *curl, CurlWorker &) override
void Fail(uint16_t errCode, uint32_t errNum, const std::string &) override
virtual HttpVerb GetVerb() const override
CurlPgReadOp(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 buffer_size, XrdCl::Log *logger, CreateConnCalloutType callout, HeaderCallout *header_callout)
CurlPrefetchOpenOp(XrdClHttp::File &file, 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 void Pause() override
bool ContinueHandle() override
void Fail(uint16_t errCode, uint32_t errNum, const std::string &msg) override
bool Setup(CURL *curl, CurlWorker &) override
bool Continue(std::shared_ptr< CurlOperation > op, XrdCl::ResponseHandler *handler, const char *buffer, size_t buffer_size)
virtual HttpVerb GetVerb() const override
virtual void SetContinueQueue(std::shared_ptr< XrdClHttp::HandlerQueue > queue) override
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)
void ReleaseHandle() override
CurlQueryOp(XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, XrdCl::Log *log, bool response_info, CreateConnCalloutType callout, int queryCode, HeaderCallout *header_callout)
void Fail(uint16_t errCode, uint32_t errNum, const std::string &msg) override
std::pair< uint64_t, uint64_t > m_op
bool Setup(CURL *curl, CurlWorker &) override
std::shared_ptr< XrdClHttp::HandlerQueue > m_continue_queue
bool ContinueHandle() override
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 void SetContinueQueue(std::shared_ptr< XrdClHttp::HandlerQueue > queue) override
virtual HttpVerb GetVerb() const override
bool Continue(std::shared_ptr< CurlOperation > op, XrdCl::ResponseHandler *handler, char *buffer, size_t buffer_size)
void ReleaseHandle() override
void ReleaseHandle() override
void SuccessImpl(bool returnObj)
virtual bool RequiresOptions() const override
bool Setup(CURL *curl, CurlWorker &) override
RedirectAction Redirect(std::string &target) override
std::pair< int64_t, bool > GetStatInfo()
CurlStatOp(XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, XrdCl::Log *log, bool response_info, CreateConnCalloutType callout, HeaderCallout *header_callout)
virtual HttpVerb GetVerb() const override
virtual void OptionsDone() override
std::string m_response_headers
size_t Write(char *buffer, size_t size)
CurlVectorReadOp(XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, const XrdCl::ChunkList &op_list, XrdCl::Log *logger, CreateConnCalloutType callout, HeaderCallout *header_callout)
void SetStatusCode(int sc)
void SetSeparator(const std::string &sep)
void ReleaseHandle() override
XrdCl::ChunkList m_chunk_list
virtual HttpVerb GetVerb() const override
std::pair< off_t, off_t > m_current_op
std::unique_ptr< XrdCl::VectorReadInfo > m_vr
bool Setup(CURL *curl, CurlWorker &) override
virtual ~CurlVectorReadOp()
void Fail(uint16_t errCode, uint32_t errNum, const std::string &msg) override
Binary blob representation.
Handle an async response.
ConnectionCallout *(*)(const std::string &, const ResponseInfo &) CreateConnCalloutType
std::vector< ChunkInfo > ChunkList
List of chunks.