XRootD
Loading...
Searching...
No Matches
XrdClHttpOpChecksum.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* Copyright (C) 2025, Pelican Project, Morgridge Institute for Research */
3/* */
4/* This file is part of the XrdClHttp client plugin for XRootD. */
5/* */
6/* XRootD is free software: you can redistribute it and/or modify it under */
7/* the terms of the GNU Lesser General Public License as published by the */
8/* Free Software Foundation, either version 3 of the License, or (at your */
9/* option) any later version. */
10/* */
11/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
12/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
13/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
14/* License for more details. */
15/* */
16/* The copyright holder's institutional names and contributor's names may not */
17/* be used to endorse or promote products derived from this software without */
18/* specific prior written permission of the institution or contributor. */
19/******************************************************************************/
20
21#include "XrdClHttpOps.hh"
22#include "XrdClHttpResponses.hh"
23#include "XrdClHttpUtil.hh"
24
25#include <XrdCl/XrdClLog.hh>
27
28#include <iomanip>
29#include <sstream>
30
31using namespace XrdClHttp;
32
34 struct timespec timeout, XrdCl::Log *logger, bool response_info, CreateConnCalloutType callout,
35 HeaderCallout *header_callout)
36:
37 CurlStatOp(handler, url, timeout, logger, response_info, callout, header_callout),
38 m_preferred_cksum(preferred)
39{}
40
41// Override to prevent the parent CurlStatOp from switching verb to PROPFIND
42void
45
46bool
48{
49 auto rv = CurlStatOp::Setup(curl, worker);
50 if (!rv) return false;
51
52 curl_easy_setopt(m_curl.get(), CURLOPT_NOBODY, 1L);
53 curl_easy_setopt(m_curl.get(), CURLOPT_CUSTOMREQUEST, nullptr);
54
55 m_headers_list.emplace_back("Want-Digest", XrdClHttp::HeaderParser::ChecksumTypeToDigestName(m_preferred_cksum));
56
57 return true;
58}
59
61CurlChecksumOp::Redirect(std::string &target)
62{
63 auto result = CurlOperation::Redirect(target);
64 curl_easy_setopt(m_curl.get(), CURLOPT_NOBODY, 1L);
65 curl_easy_setopt(m_curl.get(), CURLOPT_CUSTOMREQUEST, nullptr);
66 return result;
67}
68
69void
71{
72 if (m_curl == nullptr) return;
73 curl_easy_setopt(m_curl.get(), CURLOPT_HTTPHEADER, nullptr);
74
76}
77
78void
80{
81 SetDone(false);
82 auto checksums = m_headers.GetChecksums();
83
84 std::array<unsigned char, XrdClHttp::g_max_checksum_length> value;
86 if (checksums.IsSet(m_preferred_cksum)) {
87 value = checksums.Get(m_preferred_cksum);
88 type = m_preferred_cksum;
89 } else {
90 bool isset;
91 std::tie(type, value, isset) = checksums.GetFirst();
92 if (!isset) {
93 m_logger->Error(kLogXrdClHttp, "Checksums not found in response for %s", m_url.c_str());
94 auto handle = m_handler;
95 m_handler = nullptr;
96 handle->HandleResponse(new XrdCl::XRootDStatus(XrdCl::stError, XrdCl::errCheckSumError), nullptr);
97 return;
98 }
99 }
100 std::stringstream ss;
101 for (size_t idx = 0; idx < XrdClHttp::GetChecksumLength(type); ++idx) {
102 ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(value[idx]);
103 }
104
105 std::string response = XrdClHttp::GetTypeString(type) + " " + ss.str();
106 auto buf = new XrdClHttp::QueryResponse();
107 buf->FromString(response);
108 buf->SetResponseInfo(MoveResponseInfo());
109
110 auto obj = new XrdCl::AnyObject();
111 obj->Set(static_cast<XrdCl::Buffer*>(buf));
112
113 auto handle = m_handler;
114 m_handler = nullptr;
115 handle->HandleResponse(new XrdCl::XRootDStatus(), obj);
116 // Does not call CurlStatOp::Success() as we don't need to invoke a stat info callback
117}
void CURL
virtual void OptionsDone() override
RedirectAction Redirect(std::string &target) 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)
bool Setup(CURL *curl, CurlWorker &) override
void SetDone(bool has_failed)
std::unique_ptr< ResponseInfo > MoveResponseInfo()
const std::string m_url
std::unique_ptr< CURL, void(*)(CURL *)> m_curl
std::vector< std::pair< std::string, std::string > > m_headers_list
virtual RedirectAction Redirect(std::string &target)
XrdCl::ResponseHandler * m_handler
void ReleaseHandle() override
bool Setup(CURL *curl, CurlWorker &) override
CurlStatOp(XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, XrdCl::Log *log, bool response_info, CreateConnCalloutType callout, HeaderCallout *header_callout)
static std::string ChecksumTypeToDigestName(XrdClHttp::ChecksumType type)
Binary blob representation.
Handle diagnostics.
Definition XrdClLog.hh:101
Handle an async response.
ConnectionCallout *(*)(const std::string &, const ResponseInfo &) CreateConnCalloutType
size_t GetChecksumLength(ChecksumType ctype)
const std::string GetTypeString(ChecksumType ctype)
const uint64_t kLogXrdClHttp
const uint16_t stError
An error occurred that could potentially be retried.
const uint16_t errCheckSumError