26using namespace std::string_literals;
46 std::copy(connection_hdrs.begin(), connection_hdrs.end(), std::back_inserter(
m_headers_list));
47 std::copy(regular_hdrs.begin(), regular_hdrs.end(), std::back_inserter(
m_headers_list));
49 for (
const auto &info : transfer_hdrs) {
50 m_headers_list.emplace_back(
"TransferHeader"s + info.first, info.second);
58 if (!rv)
return false;
60 curl_easy_setopt(
m_curl.get(), CURLOPT_WRITEFUNCTION, CurlCopyOp::WriteCallback);
61 curl_easy_setopt(
m_curl.get(), CURLOPT_WRITEDATA,
this);
62 curl_easy_setopt(
m_curl.get(), CURLOPT_CUSTOMREQUEST,
"COPY");
82 if (
m_curl ==
nullptr)
return;
83 curl_easy_setopt(
m_curl.get(), CURLOPT_WRITEFUNCTION,
nullptr);
84 curl_easy_setopt(
m_curl.get(), CURLOPT_WRITEDATA,
nullptr);
85 curl_easy_setopt(
m_curl.get(), CURLOPT_CUSTOMREQUEST,
nullptr);
86 curl_easy_setopt(
m_curl.get(), CURLOPT_HTTPHEADER,
nullptr);
87 curl_easy_setopt(
m_curl.get(), CURLOPT_XFERINFOFUNCTION,
nullptr);
94 m_progress_handler = handler;
98 CurlCopyOp::WriteCallback(
char *buffer,
size_t size,
size_t nitems,
void *this_ptr)
100 auto me =
reinterpret_cast<CurlCopyOp*
>(this_ptr);
102 std::string_view str_data(buffer, size * nitems);
104 while ((end_line = std::min(str_data.size(), str_data.find(
'\n'))) > 0) {
106 auto cur_line = str_data.substr(0, end_line);
108 if (me->m_line_buffer.empty()) {
109 me->HandleLine(cur_line);
111 me->m_line_buffer += cur_line;
112 me->HandleLine(me->m_line_buffer);
113 me->m_line_buffer.clear();
116 if (end_line == str_data.size())
119 str_data = str_data.substr(end_line + 1);
121 me->m_line_buffer = str_data;
123 return size * nitems;
127 CurlCopyOp::HandleLine(std::string_view line)
129 if (line ==
"Perf Marker") {
131 }
else if (line ==
"End") {
132 if (m_bytemark > -1 && m_progress_handler) {
133 m_progress_handler->HandleProgress(
static_cast<std::size_t
>(m_bytemark));
136 auto key_end_pos = line.find(
':');
137 if (key_end_pos == line.npos) {
140 auto key = line.substr(0, key_end_pos);
141 auto value =
ltrim_view(line.substr(key_end_pos + 1));
142 if (key ==
"Stripe Bytes Transferred") {
144 m_bytemark = std::stoll(std::string(value));
148 }
else if (key ==
"success") {
149 m_sent_success =
true;
150 }
else if (key ==
"failure") {
std::vector< std::pair< std::string, std::string > > Headers
void ReleaseHandle() override
void SetProgressHandler(XrdCl::ProgressHandler *handler) noexcept
bool Setup(CURL *curl, CurlWorker &) override
CurlCopyOp(XrdCl::ResponseHandler *handler, const std::string &source_url, const Headers &source_hdrs, const std::string &dest_url, const Headers &dest_hdrs, const Headers &connection_hdrs, TpcMode mode, struct timespec timeout, XrdCl::Log *logger, CreateConnCalloutType callout)
void SetDone(bool has_failed)
std::unique_ptr< CURL, void(*)(CURL *)> m_curl
virtual void ReleaseHandle()
void UpdateBytes(uint64_t bytes)
std::vector< std::pair< std::string, std::string > > m_headers_list
XrdCl::ResponseHandler * m_handler
CurlOperation(XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, XrdCl::Log *log, CreateConnCalloutType, HeaderCallout *header_callout)
virtual bool Setup(CURL *curl, CurlWorker &)
Handle the progress of an asynchronous operation.
Handle an async response.
virtual void HandleResponse(XRootDStatus *status, AnyObject *response)
ConnectionCallout *(*)(const std::string &, const ResponseInfo &) CreateConnCalloutType
std::string_view ltrim_view(const std::string_view &input_view)