Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
RCurlConnection.hxx
Go to the documentation of this file.
1// @(#)root/net:$Id$
2// Author: Jakob Blomer
3
4/*************************************************************************
5 * Copyright (C) 1995-2025, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#ifndef ROOT_RCurlConnection
13#define ROOT_RCurlConnection
14
15#include <ROOT/RError.hxx>
16
17#include <cstdint>
18#include <memory>
19#include <string>
20#include <variant>
21#include <vector>
22
23namespace ROOT {
24namespace Internal {
25
30
31struct RS3Credentials final {
32 std::string fAccessKey;
33 std::string fSecretKey;
34 std::string fRegion;
35};
36
41
42/// Encapsulates a curl easy handle and provides an interface to send HTTP HEAD and (multi-)range queries.
44public:
45 /// Return value for both HEAD and GET requests. In case of errors, provides the reason for the failure as code
46 /// and as message.
47 struct RStatus {
50 kTooManyRanges, ///< should not get to the user; number of request ranges is automatically reduced as needed
55 };
56
58 std::string fStatusMsg;
59
60 RStatus() = default;
61 explicit RStatus(EStatusCode code) : fStatusCode(code) {}
62
63 explicit operator bool() const { return fStatusCode == kSuccess; }
64 };
65
66private:
67 std::unique_ptr<RHTTPCredentials> fCredentials;
68 void *fHandle = nullptr; ///< the CURL easy handle corresponding to this connection
69 /// If set to zero, automatically adjust: try with all given ranges and as long as the number of ranges is too large,
70 /// half it. If set to zero and automatic reduction of the number of requests is necessary, the number of requests
71 /// that works will be saved for further requests with this object.
72 std::size_t fMaxNRangesPerReqest = 0;
73 std::string fEscapedUrl; ///< The URL provided in the constructor escaped according to standard rules
74 std::unique_ptr<char[]> fErrorBuffer; ///< For use by libcurl
75
76 void SetupErrorBuffer();
77 void SetOptions();
78 RResult<void> SetUrl(const std::string &url);
79 void Perform(RStatus &status);
80
81public:
82 /// Returned by SendHeadReq() if the HTTP response contains no content-length header
83 static constexpr std::uint64_t kUnknownSize = static_cast<std::uint64_t>(-1);
84
85 /// Caller-provided byte-range of the remote resource together with a pointer to a buffer.
86 struct RUserRange {
87 unsigned char *fDestination = nullptr;
88 std::uint64_t fOffset = 0;
89 std::size_t fLength = 0;
90 /// Usually equal to fLength for a successful call unless range goes out of the size of the remote resource
91 std::size_t fNBytesRecv = 0;
92
93 bool operator<(const RUserRange &other) const { return fOffset < other.fOffset; }
94 };
95
96 explicit RCurlConnection(const std::string &url);
98 RCurlConnection(const RCurlConnection &other) = delete;
99 RCurlConnection &operator=(const RCurlConnection &other) = delete;
102
103 /// Used for testing
104 static int GetCurlVersion();
105
107 void SetCredentials(const RS3Credentials &credentials);
108 void ClearCredentials();
110
111 /// Checks if the resource exists and if it does, return the value of the content-length header as size
112 RStatus SendHeadReq(std::uint64_t &remoteSize);
113 /// Reads the given ranges from the remote resource. The ranges can be in any order and also overlapping. They
114 /// will be transformed in optimized HTTP ranges for a multi-range request. Ranges past the resource size are
115 /// valid (but won't receive any data). No limit on the number of ranges; if fMaxNRangesPerReqest is zero,
116 /// a valid batching of requests into multiple multi-range requests takes place automatically.
117 /// The fNBytesRecv member of the ranges is only well-defined on success.
118 RStatus SendRangesReq(std::size_t N, RUserRange *ranges);
119
120 const std::string &GetEscapedUrl() const { return fEscapedUrl; }
121
122 void SetMaxNRangesPerRequest(std::size_t val) { fMaxNRangesPerReqest = val; }
123 std::size_t GetMaxNRangesPerRequest() const { return fMaxNRangesPerReqest; }
124};
125
126} // namespace Internal
127} // namespace ROOT
128
129#endif
const Handle_t kNone
Definition GuiTypes.h:89
#define N
RCurlConnection(const RCurlConnection &other)=delete
void SetCredentials(const RS3Credentials &credentials)
void * fHandle
the CURL easy handle corresponding to this connection
std::string fEscapedUrl
The URL provided in the constructor escaped according to standard rules.
RCurlConnection & operator=(const RCurlConnection &other)=delete
std::unique_ptr< char[]> fErrorBuffer
For use by libcurl.
RStatus SendRangesReq(std::size_t N, RUserRange *ranges)
Reads the given ranges from the remote resource.
const std::string & GetEscapedUrl() const
static constexpr std::uint64_t kUnknownSize
Returned by SendHeadReq() if the HTTP response contains no content-length header.
std::size_t fMaxNRangesPerReqest
If set to zero, automatically adjust: try with all given ranges and as long as the number of ranges i...
RCurlConnection(const std::string &url)
void SetMaxNRangesPerRequest(std::size_t val)
RStatus SendHeadReq(std::uint64_t &remoteSize)
Checks if the resource exists and if it does, return the value of the content-length header as size.
std::size_t GetMaxNRangesPerRequest() const
static int GetCurlVersion()
Used for testing.
void SetCredentialsFromEnvironment()
Sets the credentials from process environment variables.
RResult< void > SetUrl(const std::string &url)
RCurlConnection & operator=(RCurlConnection &&other)
std::unique_ptr< RHTTPCredentials > fCredentials
EHTTPCredentialsType GetCredentialsType() const
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
Definition RError.hxx:197
These are definitions of various free functions for the C-style compression routines in ROOT.
Definition TPython.h:26
Small utility to parse cmdline options.
Definition RExports.h:71
Return value for both HEAD and GET requests.
@ kTooManyRanges
should not get to the user; number of request ranges is automatically reduced as needed
Caller-provided byte-range of the remote resource together with a pointer to a buffer.
bool operator<(const RUserRange &other) const
std::size_t fNBytesRecv
Usually equal to fLength for a successful call unless range goes out of the size of the remote resour...
std::variant< RS3Credentials > fData