XRootD
XrdHttpTpcTPC.hh
Go to the documentation of this file.
1 
2 #include <memory>
3 #include <string>
4 #include <vector>
5 #include <sys/time.h>
6 
8 
10 #include "XrdHttp/XrdHttpUtils.hh"
11 
12 #include "XrdTls/XrdTlsTempCA.hh"
14 #include "XrdHttpTpcPool.hh"
15 
16 #include <curl/curl.h>
17 
18 class XrdOucErrInfo;
19 class XrdOucStream;
20 class XrdSfsFile;
21 class XrdSfsFileSystem;
22 class XrdXrootdTpcMon;
23 typedef void CURL;
24 
25 namespace TPC {
26 class State;
27 
28 enum LogMask {
29  Debug = 0x01,
30  Info = 0x02,
31  Warning = 0x04,
32  Error = 0x08,
33  All = 0xff
34 };
35 
36 enum class TpcType {
37  Pull,
38  Push
39 };
40 
41 struct CurlDeleter {
42  void operator()(CURL *curl);
43 };
44 using ManagedCurlHandle = std::unique_ptr<CURL, CurlDeleter>;
45 
46 
47 class TPCHandler : public XrdHttpExtHandler {
48 public:
49  TPCHandler(XrdSysError *log, const char *config, XrdOucEnv *myEnv);
50  virtual ~TPCHandler();
51 
52  virtual bool MatchesPath(const char *verb, const char *path);
53  virtual int ProcessReq(XrdHttpExtReq &req);
54  // Abstract method in the base class, but does not seem to be used
55  virtual int Init(const char *cfgfile) {return 0;}
56  static constexpr std::string_view OSS_TASK_OPAQUE = "oss.task=httptpc";
57 private:
58 
59 
60  struct TPCLogRecord {
61 
62  TPCLogRecord(XrdHttpExtReq & req, const TpcType tpcType) : bytes_transferred( -1 ), status( -1 ),
63  tpc_status(-1), streams( 1 ), isIPv6(false), mReq(req), pmarkManager(mReq,tpcType), mTpcType(tpcType)
64  {
65  gettimeofday(&begT, 0); // Set effective start time
66  }
67  ~TPCLogRecord();
68 
69  std::string log_prefix;
70  std::string local;
71  std::string remote;
72  std::string name;
73  std::string clID;
74  static XrdXrootdTpcMon* tpcMonitor;
75  timeval begT;
76  off_t bytes_transferred;
77  int status;
78  int tpc_status;
79  unsigned int streams;
80  bool isIPv6;
81  XrdHttpExtReq & mReq;
82  XrdHttpTpc::PMarkManager pmarkManager;
83  XrdSysError * m_log;
84  TpcType mTpcType;
85  };
86 
87  int ProcessOptionsReq(XrdHttpExtReq &req);
88 
89  static std::string GetAuthz(XrdHttpExtReq &req);
90 
91  // Configure curl handle's CA settings. The CA files present here should
92  // be valid for the lifetime of the process.
93  void ConfigureCurlCA(CURL *curl);
94 
95  // Redirect the transfer according to the contents of an XrdOucErrInfo object.
96  int RedirectTransfer(CURL *curl, const std::string &redirect_resource, XrdHttpExtReq &req,
97  XrdOucErrInfo &error, TPCLogRecord &);
98 
99  int OpenWaitStall(XrdSfsFile &fh, const std::string &resource, int mode,
100  int openMode, const XrdSecEntity &sec,
101  const std::string &authz);
102 
103  int DetermineXferSize(CURL *curl, XrdHttpExtReq &req, TPC::State &state,
104  bool &success, TPCLogRecord &, bool shouldReturnErrorToClient = true);
105 
106  int GetContentLengthTPCPull(CURL *curl, XrdHttpExtReq &req, uint64_t & contentLength, bool & success, TPCLogRecord &rec);
107 
108  // Send a 'performance marker' back to the TPC client, informing it of our
109  // progress. The TPC client will use this information to determine whether
110  // the transfer is making sufficient progress and/or other monitoring info
111  // (such as whether the transfer is happening over IPv4, IPv6, or both).
112  int SendPerfMarker(XrdHttpExtReq &req, TPCLogRecord &rec, TPC::State &state);
113  int SendPerfMarker(XrdHttpExtReq &req, TPCLogRecord &rec, std::vector<State*> &state,
114  off_t bytes_transferred);
115  int SendPerfMarker(XrdHttpExtReq &req, TPCLogRecord &rec, TPC::State &state, std::string desc);
116 
117  // Perform the libcurl transfer, periodically sending back chunked updates.
118  int RunCurlWithUpdates(CURL *curl, XrdHttpExtReq &req, TPC::State &state,
119  TPCLogRecord &rec);
120 
121  // Experimental multi-stream version of RunCurlWithUpdates
122  int RunCurlWithStreams(XrdHttpExtReq &req, TPC::State &state,
123  size_t streams, TPCLogRecord &rec);
124  int RunCurlWithStreamsImpl(XrdHttpExtReq &req, TPC::State &state,
125  size_t streams, std::vector<TPC::State*> &streams_handles,
126  std::vector<ManagedCurlHandle> &curl_handles,
127  TPCLogRecord &rec);
128 
129  int ProcessPushReq(const std::string & resource, XrdHttpExtReq &req);
130  int ProcessPullReq(const std::string &resource, XrdHttpExtReq &req);
131 
132  bool ConfigureFSLib(XrdOucStream &Config, std::string &path1, bool &path1_alt,
133  std::string &path2, bool &path2_alt);
134  bool Configure(const char *configfn, XrdOucEnv *myEnv);
135  bool ConfigureLogger(XrdOucStream &Config);
136 
137  // Generate a consistently-formatted log message.
138  void logTransferEvent(LogMask lvl, const TPCLogRecord &record,
139  const std::string &event, const std::string &message="");
140 
141  std::string generateClientErr(std::stringstream &err_ss, const TPCLogRecord &rec, CURLcode cCode = CURLcode::CURLE_OK);
142 
143  std::string prepareURL(XrdHttpExtReq &req);
144 
145  static int m_marker_period;
146  static size_t m_block_size;
147  static size_t m_small_block_size;
148  bool m_desthttps;
149  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
150  // when 'false' any IP available can be selected
151  int m_timeout; // the 'timeout interval'; if no bytes have been received during this time period, abort the transfer.
152  int m_first_timeout; // the 'first timeout interval'; the amount of time we're willing to wait to get the first byte.
153  // Unless explicitly specified, this is 2x the timeout interval.
154  std::string m_cadir; // The directory to use for CAs.
155  std::string m_cafile; // The file to use for CAs in libcurl
156  static XrdSysMutex m_monid_mutex;
157  static uint64_t m_monid;
158  XrdSysError m_log;
159  XrdSfsFileSystem *m_sfs;
160  std::shared_ptr<XrdTlsTempCA> m_ca_file;
161  TPCRequestManager m_request_manager; // Manager of the request & worker pools for executing TPC transfers
162 
163  // 16 blocks in flight at 16 MB each, meaning that there will be up to 256MB
164  // in flight; this is equal to the bandwidth delay product of a 200ms transcontinental
165  // connection at 10Gbps.
166  static const int m_pipelining_multiplier = 16;
167 
168  bool usingEC; // indicate if XrdEC is used
169 
170  // Time to connect the curl socket to the remote server uses the linux's default value
171  // of 60 seconds
172  static const long CONNECT_TIMEOUT = 60;
173 
174  // hdr2cgimap
175  std::map<std::string,std::string> hdr2cgimap;
176 };
177 }
void CURL
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.
std::unique_ptr< CURL, CurlDeleter > ManagedCurlHandle
@ Warning
XrdCmsConfig Config
void operator()(CURL *curl)