XRootD
Loading...
Searching...
No Matches
XrdHttpTpcTPC.hh
Go to the documentation of this file.
1#ifndef XRD_HTTP_TPC_TPC_HH
2#define XRD_HTTP_TPC_TPC_HH
3#include <memory>
4#include <string>
5#include <vector>
6#include <sys/time.h>
7
9
12
15
16#include <curl/curl.h>
17#include <openssl/ssl.h>
18
19class XrdOucErrInfo;
20class XrdOucStream;
21class XrdSfsFile;
23class XrdXrootdTpcMon;
24typedef void CURL;
25
26namespace TPC {
27class State;
28
29enum LogMask {
30 Debug = 0x01,
31 Info = 0x02,
32 Warning = 0x04,
33 Error = 0x08,
34 All = 0xff
35};
36
37enum class TpcType {
40};
41
43 void operator()(CURL *curl);
44};
45using ManagedCurlHandle = std::unique_ptr<CURL, CurlDeleter>;
46
47
49public:
50 TPCHandler(XrdSysError *log, const char *config, XrdOucEnv *myEnv);
51 virtual ~TPCHandler();
52
53 virtual bool MatchesPath(const char *verb, const char *path);
54 virtual int ProcessReq(XrdHttpExtReq &req);
55 // Abstract method in the base class, but does not seem to be used
56 virtual int Init(const char *cfgfile) {return 0;}
57 static constexpr std::string_view OSS_TASK_OPAQUE = "oss.task=httptpc";
58private:
59
60 static int sockopt_callback(void * clientp, curl_socket_t curlfd, curlsocktype purpose);
61 static int opensocket_callback(void *clientp,
62 curlsocktype purpose,
63 struct curl_sockaddr *address);
64
65 static int closesocket_callback(void *clientp, curl_socket_t fd);
66 static int ssl_ctx_callback(CURL *curl, void *ssl_ctx, void *clientp);
67 static int verify_callback(int preverify_ok, X509_STORE_CTX* ctx);
68
69 struct TPCLogRecord {
70
71 TPCLogRecord(XrdHttpExtReq &req, const TpcType tpcType)
72 : bytes_transferred(-1), status(-1), tpc_status(-1), streams(1), isIPv6(false),
73 allow_local(false), allow_private(false), mReq(req), pmarkManager(mReq, tpcType), mTpcType(tpcType)
74 {
75 gettimeofday(&begT, 0); // Set effective start time
76 }
77
78 ~TPCLogRecord();
79
80 std::string log_prefix;
81 std::string local;
82 std::string remote;
83 std::string name;
84 std::string clID;
85 // Keeps the shared CA/CRL store alive for the duration of the transfer.
86 // Declared here, rather than alongside the curl handle, so that it outlives
87 // every handle the request creates -- including the duplicates that
88 // multi-stream transfers make, which inherit the pointer to this record.
89 std::shared_ptr<X509_STORE> ca_store;
90 static XrdXrootdTpcMon* tpcMonitor;
91 timeval begT;
92 off_t bytes_transferred;
93 int status;
94 int tpc_status;
95 unsigned int streams;
96 bool isIPv6;
97 bool allow_local;
98 bool allow_private;
99 XrdHttpExtReq & mReq;
100 XrdHttpTpc::PMarkManager pmarkManager;
101 XrdSysError * m_log;
102 TpcType mTpcType;
103 };
104
105 int ProcessOptionsReq(XrdHttpExtReq &req);
106
107 static std::string GetAuthz(XrdHttpExtReq &req);
108
109 // Configure curl handle's CA settings. The CA files present here should
110 // be valid for the lifetime of the process. The record takes a reference to
111 // the shared CA store, so it must outlive the curl handle.
112 //
113 // Returns false if no trust anchors could be configured, in which case the
114 // transfer must be failed: letting it proceed would leave libcurl verifying
115 // against its built-in default CA bundle instead of the configured one.
116 bool ConfigureCurlCA(CURL *curl, TPCLogRecord &rec);
117
118 // Configure the minimum transfer rate and the permitted time below it.
119 void ConfigureCurlLowSpeed(CURL *curl);
120
121 // Redirect the transfer according to the contents of an XrdOucErrInfo object.
122 int RedirectTransfer(CURL *curl, const std::string &redirect_resource, XrdHttpExtReq &req,
123 XrdOucErrInfo &error, TPCLogRecord &);
124
125 int OpenWaitStall(XrdSfsFile &fh, const std::string &resource, int mode,
126 int openMode, const XrdSecEntity &sec,
127 const std::string &authz);
128
129 int DetermineXferSize(CURL *curl, XrdHttpExtReq &req, TPC::State &state,
130 bool &success, TPCLogRecord &, bool shouldReturnErrorToClient = true);
131
132 int GetContentLengthTPCPull(CURL *curl, XrdHttpExtReq &req, uint64_t & contentLength, bool & success, TPCLogRecord &rec);
133
134 // Send a 'performance marker' back to the TPC client, informing it of our
135 // progress. The TPC client will use this information to determine whether
136 // the transfer is making sufficient progress and/or other monitoring info
137 // (such as whether the transfer is happening over IPv4, IPv6, or both).
138 int SendPerfMarker(XrdHttpExtReq &req, TPCLogRecord &rec, TPC::State &state);
139 int SendPerfMarker(XrdHttpExtReq &req, TPCLogRecord &rec, std::vector<State*> &state,
140 off_t bytes_transferred);
141
142 // Perform the libcurl transfer, periodically sending back chunked updates.
143 int RunCurlWithUpdates(CURL *curl, XrdHttpExtReq &req, TPC::State &state,
144 TPCLogRecord &rec);
145
146 // Experimental multi-stream version of RunCurlWithUpdates
147 int RunCurlWithStreams(XrdHttpExtReq &req, TPC::State &state,
148 size_t streams, TPCLogRecord &rec);
149 int RunCurlWithStreamsImpl(XrdHttpExtReq &req, TPC::State &state,
150 size_t streams, std::vector<TPC::State*> &streams_handles,
151 std::vector<ManagedCurlHandle> &curl_handles,
152 TPCLogRecord &rec);
153
154 int ProcessPushReq(const std::string & resource, XrdHttpExtReq &req);
155 int ProcessPullReq(const std::string &resource, XrdHttpExtReq &req);
156
157 bool ConfigureFSLib(XrdOucStream &Config, std::string &path1, bool &path1_alt,
158 std::string &path2, bool &path2_alt);
159 bool Configure(const char *configfn, XrdOucEnv *myEnv);
160 bool ConfigureLogger(XrdOucStream &Config);
161
162 // Generate a consistently-formatted log message.
163 void logTransferEvent(LogMask lvl, const TPCLogRecord &record,
164 const std::string &event, const std::string &message="");
165
166 std::string generateClientErr(std::stringstream &err_ss, const TPCLogRecord &rec, CURLcode cCode = CURLcode::CURLE_OK);
167
168 std::string prepareURL(XrdHttpExtReq &req);
169
170 static int m_marker_period;
171 static size_t m_block_size;
172 static size_t m_small_block_size;
173 bool m_allow_local;
174 bool m_allow_private;
175 bool m_desthttps;
176 bool m_fixed_route; // If 'true' the Destination IP in an HTTP-TPC is forced to be the same as the IP used to contact the server
177 // when 'false' any IP available can be selected
178 long m_low_speed_limit; // Minimum transfer rate in bytes per second; zero disables the check.
179 long m_low_speed_time; // Time the transfer may remain below m_low_speed_limit before it is aborted.
180 int m_timeout; // the 'timeout interval'; if no bytes have been received during this time period, abort the transfer.
181 int m_first_timeout; // the 'first timeout interval'; the amount of time we're willing to wait to get the first byte.
182 // Unless explicitly specified, this is 2x the timeout interval.
183 std::string m_cadir; // The directory to use for CAs.
184 std::string m_cafile; // The file to use for CAs in libcurl
185 static XrdSysMutex m_monid_mutex;
186 static uint64_t m_monid;
187 XrdSysError m_log;
188 XrdSfsFileSystem *m_sfs;
189 std::shared_ptr<XrdTlsTempCA> m_ca_file;
190
191 // 16 blocks in flight at 16 MB each, meaning that there will be up to 256MB
192 // in flight; this is equal to the bandwidth delay product of a 200ms transcontinental
193 // connection at 10Gbps.
194 static const int m_pipelining_multiplier = 16;
195
196 bool usingEC; // indicate if XrdEC is used
197
198 static bool allowMissingCRL;
199
200 // Whether the libcurl we are linked against supports CURLOPT_SSL_CTX_FUNCTION,
201 // which only its OpenSSL-family TLS backends do. Probed once at configuration
202 // time because without it the shared CA store cannot be installed.
203 bool m_sslctx_supported{false};
204
205 // Time to connect the curl socket to the remote server uses the linux's default value
206 // of 60 seconds
207 static const long CONNECT_TIMEOUT = 60;
208
209 // hdr2cgimap
210 std::map<std::string,std::string> hdr2cgimap;
211};
212}
213#endif
bool usingEC
void CURL
Utility functions for XrdHTTP.
TPCHandler(XrdSysError *log, const char *config, XrdOucEnv *myEnv)
virtual int ProcessReq(XrdHttpExtReq &req)
virtual ~TPCHandler()
static constexpr std::string_view OSS_TASK_OPAQUE
virtual int Init(const char *cfgfile)
Initializes the external request handler.
virtual bool MatchesPath(const char *verb, const char *path)
Tells if the incoming path is recognized as one of the paths that have to be processed.
XrdHttpExtHandler()
Constructor.
std::unique_ptr< CURL, CurlDeleter > ManagedCurlHandle
void operator()(CURL *curl)