38 const std::string &url, std::unique_ptr<TapeOperation> tape,
42 CurlOperation(handler, url, timeout, logger, callout, header_callout),
43 m_tape(std::move(tape))
48 const std::string &url,
const std::vector<std::string> &file_list,
54 std::make_unique<
TapeOperation>(url, file_list, flags), timeout,
55 logger, callout, header_callout)
66 std::make_unique<
TapeOperation>(url, query_code, arg), timeout,
67 logger, callout, header_callout)
76 const auto failure = [&](uint16_t code, uint32_t error,
77 const std::string &message) {
79 Fail(code, error, message);
85 const auto status = m_tape->Start(m_request);
88 return failure(status.code, status.errNo,
89 status.GetErrorMessage());
95 throw std::runtime_error(
96 "failed to initialize " + RequestDescription());
99 if(!ConfigureRequest())
101 throw std::runtime_error(
102 "failed to configure " + RequestDescription());
106 catch(
const std::exception &ex)
113CurlTapeOp::ConfigureRequest()
120 if(curl_easy_setopt(
m_curl.get(), CURLOPT_WRITEFUNCTION,
121 CurlTapeOp::WriteCallback) != CURLE_OK
122 || curl_easy_setopt(
m_curl.get(), CURLOPT_WRITEDATA,
this) != CURLE_OK)
126#if CURL_AT_LEAST_VERSION(7, 85, 0)
127 if(curl_easy_setopt(
m_curl.get(), CURLOPT_PROTOCOLS_STR,
"https,http")
129 || curl_easy_setopt(
m_curl.get(), CURLOPT_REDIR_PROTOCOLS_STR,
130 "https,http") != CURLE_OK)
135 const long protocols = CURLPROTO_HTTP | CURLPROTO_HTTPS;
136 if(curl_easy_setopt(
m_curl.get(), CURLOPT_PROTOCOLS, protocols) != CURLE_OK
137 || curl_easy_setopt(
m_curl.get(), CURLOPT_REDIR_PROTOCOLS, protocols)
144 switch(m_request.method)
147 if(curl_easy_setopt(
m_curl.get(), CURLOPT_HTTPGET, 1L) != CURLE_OK)
152 if(curl_easy_setopt(
m_curl.get(), CURLOPT_POST, 1L) != CURLE_OK
153 || curl_easy_setopt(
m_curl.get(), CURLOPT_POSTFIELDS,
154 m_request.body.c_str()) != CURLE_OK
155 || curl_easy_setopt(
m_curl.get(), CURLOPT_POSTFIELDSIZE_LARGE,
156 static_cast<curl_off_t
>(m_request.body.size())) != CURLE_OK)
162 if(curl_easy_setopt(
m_curl.get(), CURLOPT_CUSTOMREQUEST,
"DELETE")
178 std::string response;
179 bool complete =
false;
180 const auto status = m_tape->Advance(
182 nextRequest, response, complete);
185 Fail(status.code, status.errNo, status.GetErrorMessage());
194 m_request = std::move(nextRequest);
197 throw std::runtime_error(
198 "worker unavailable before starting " + RequestDescription());
202 throw std::runtime_error(
203 "failed to reset the curl handle for " + RequestDescription());
205 if(!ConfigureRequest())
207 throw std::runtime_error(
208 "failed to configure " + RequestDescription());
212 throw std::runtime_error(
213 "failed to configure headers for " + RequestDescription());
216 catch(
const std::exception &ex)
224 const std::string &message)
226 std::string detail = message;
229 detail = RequestDescription() +
" failed: "
238 return m_request.method;
242CurlTapeOp::RequestDescription()
const
250 if(
m_curl ==
nullptr)
return;
252 curl_easy_setopt(
m_curl.get(), CURLOPT_ERRORBUFFER,
nullptr);
253 curl_easy_setopt(
m_curl.get(), CURLOPT_WRITEFUNCTION,
nullptr);
254 curl_easy_setopt(
m_curl.get(), CURLOPT_WRITEDATA,
nullptr);
255 curl_easy_setopt(
m_curl.get(), CURLOPT_HTTPHEADER,
nullptr);
256 curl_easy_setopt(
m_curl.get(), CURLOPT_POST, 0L);
257 curl_easy_setopt(
m_curl.get(), CURLOPT_POSTFIELDS,
nullptr);
258 curl_easy_setopt(
m_curl.get(), CURLOPT_POSTFIELDSIZE_LARGE,
259 static_cast<curl_off_t
>(0));
260 curl_easy_setopt(
m_curl.get(), CURLOPT_CUSTOMREQUEST,
nullptr);
265CurlTapeOp::WriteCallback(
char *buffer,
size_t size,
size_t nitems,
void *data)
267 return static_cast<CurlTapeOp *
>(data)->Write(buffer, size * nitems);
271CurlTapeOp::Write(
char *buffer,
size_t size)
275 m_response.append(buffer, size);
279 catch(
const std::exception &ex)
282 std::string(
"while buffering a Tape REST response: ") + ex.what());
287 "unknown exception while buffering a Tape REST response");
292CurlTapeOp::Complete(
const std::string &response)
300 auto buffer = std::make_unique<XrdCl::Buffer>();
301 buffer->FromString(response);
303 auto obj = std::make_unique<XrdCl::AnyObject>();
304 auto status = std::make_unique<XrdCl::XRootDStatus>();
305 obj->Set(buffer.release());
void SetDone(bool has_failed)
int FailCallback(XErrorCode ecode, const std::string &emsg)
int GetStatusCode() const
bool FinishSetup(CURL *curl)
std::unique_ptr< CURL, void(*)(CURL *)> m_curl
static const std::string GetVerbString(HttpVerb)
virtual void ReleaseHandle()
void UpdateBytes(uint64_t bytes)
bool SetupNextRequest(const std::string &url, CurlWorker &worker)
std::vector< std::pair< std::string, std::string > > m_headers_list
XrdClHttp::HttpVerb HttpVerb
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 &)
std::string m_request_url
HttpVerb GetVerb() const override
bool Setup(CURL *curl, CurlWorker &worker) override
CurlTapeOp(XrdCl::ResponseHandler *handler, const std::string &url, std::unique_ptr< TapeOperation > tape, struct timespec timeout, XrdCl::Log *logger, CreateConnCalloutType callout, HeaderCallout *header_callout)
void Fail(uint16_t errCode, uint32_t errNum, const std::string &message) override
void ReleaseHandle() override
CurlTapePrepareOp(XrdCl::ResponseHandler *handler, const std::string &url, const std::vector< std::string > &file_list, XrdCl::PrepareFlags::Flags flags, struct timespec timeout, XrdCl::Log *logger, CreateConnCalloutType callout, HeaderCallout *header_callout)
CurlTapeQueryOp(XrdCl::ResponseHandler *handler, const std::string &url, XrdCl::QueryCode::Code query_code, const XrdCl::Buffer &arg, struct timespec timeout, XrdCl::Log *logger, CreateConnCalloutType callout, HeaderCallout *header_callout)
Binary blob representation.
Handle an async response.
virtual void HandleResponse(XRootDStatus *status, AnyObject *response)
ConnectionCallout *(*)(const std::string &, const ResponseInfo &) CreateConnCalloutType
std::string TapeProblemResponse(long statusCode, const std::string &body)
const uint16_t errInternal
Internal error.
Code
XRootD query request codes.