XRootD
Loading...
Searching...
No Matches
XrdHttpTpcConfigure.cc
Go to the documentation of this file.
1
2#include "XrdHttpTpcTPC.hh"
3
4#include <dlfcn.h>
5#include <fcntl.h>
6
7#include "XrdOuc/XrdOuca2x.hh"
8#include "XrdOuc/XrdOucEnv.hh"
14
15using namespace TPC;
16
17
18bool TPCHandler::Configure(const char *configfn, XrdOucEnv *myEnv)
19{
20 XrdOucEnv cfgEnv;
21 XrdOucStream Config(&m_log, getenv("XRDINSTANCE"), &cfgEnv, "=====> ");
22
23 m_log.setMsgMask(LogMask::Warning | LogMask::Error);
24
25 // test if XrdEC is used
26 usingEC = getenv("XRDCL_EC")? true : false;
27
28 std::string authLib;
29 std::string authLibParms;
30 int cfgFD = open(configfn, O_RDONLY, 0);
31 if (cfgFD < 0) {
32 m_log.Emsg("Config", errno, "open config file", configfn);
33 return false;
34 }
35 Config.Attach(cfgFD);
36 static const char *cvec[] = { "*** http tpc plugin config:", 0 };
37 Config.Capture(cvec);
38 const char *val;
39 while ((val = Config.GetMyFirstWord())) {
40 if (!strcmp("http.desthttps", val)) {
41 if (!(val = Config.GetWord())) {
42 Config.Close();
43 m_log.Emsg("Config", "http.desthttps value not specified");
44 return false;
45 }
46 if (!strcmp("1", val) || !strcasecmp("yes", val) || !strcasecmp("true", val)) {
47 m_desthttps = true;
48 } else if (!strcmp("0", val) || !strcasecmp("no", val) || !strcasecmp("false", val)) {
49 m_desthttps = false;
50 } else {
51 Config.Close();
52 m_log.Emsg("Config", "https.desthttps value is invalid", val);
53 return false;
54 }
55 } else if (!strcmp("tpc.trace", val)) {
56 if (!ConfigureLogger(Config)) {
57 Config.Close();
58 return false;
59 }
60 } else if (!strcmp("tpc.fixed_route", val)) {
61 if (!(val = Config.GetWord())) {
62 Config.Close();
63 m_log.Emsg("Config", "tpc.fixed_route value not specified");
64 return false;
65 }
66 if (!strcmp("1", val) || !strcasecmp("yes", val) || !strcasecmp("true", val)) {
67 m_fixed_route= true;
68 } else if (!strcmp("0", val) || !strcasecmp("no", val) || !strcasecmp("false", val)) {
69 m_fixed_route= false;
70 } else {
71 Config.Close();
72 m_log.Emsg("Config", "tpc.fixed_route value is invalid", val);
73 return false;
74 }
75 } else if (!strcmp("tpc.header2cgi",val)) {
76 // header2cgi parsing
77 if(XrdHttpProtocol::parseHeader2CGI(Config,m_log,hdr2cgimap)){
78 Config.Close();
79 return false;
80 }
81 // remove authorization header2cgi parsing as it will anyway be added to the CGI before the file open
82 // by the HTTP/TPC logic
83 auto authHdr = XrdOucTUtils::caseInsensitiveFind(hdr2cgimap,"authorization");
84 if(authHdr != hdr2cgimap.end()) {
85 hdr2cgimap.erase(authHdr);
86 }
87 } else if (!strcmp("tpc.timeout", val)) {
88 if (!(val = Config.GetWord())) {
89 Config.Close();
90 m_log.Emsg("Config","tpc.timeout value not specified."); return false;
91 }
92 if (XrdOuca2x::a2tm(m_log, "timeout value", val, &m_timeout, 0)) return false;
93 // First byte timeout can be set separately from the continuous timeout.
94 if ((val = Config.GetWord())) {
95 if (XrdOuca2x::a2tm(m_log, "first byte timeout value", val, &m_first_timeout, 0)) return false;
96 } else {
97 m_first_timeout = 2*m_timeout;
98 }
99 } else if (!strcmp("tpc.max_active_transfers_per_queue", val)) {
100 if (!(val = Config.GetWord())) {
101 Config.Close();
102 m_log.Emsg("Config", "tpc.max_active_transfers_per_queue value not specified.");
103 return false;
104 }
105 int max_workers;
106 if (XrdOuca2x::a2i(m_log, "tpc.max_active_transfers_per_queue", val, &max_workers, 1, 1000)) return false;
107 m_request_manager.SetMaxWorkers(static_cast<unsigned>(max_workers));
108 } else if (!strcmp("tpc.max_waiting_transfers_per_queue", val)) {
109 if (!(val = Config.GetWord())) {
110 Config.Close();
111 m_log.Emsg("Config", "tpc.max_waiting_transfers_per_queue value not specified.");
112 return false;
113 }
114 int max_pending_ops;
115 if (XrdOuca2x::a2i(m_log, "tpc.max_waiting_transfers_per_queue", val, &max_pending_ops, 1, 1000)) return false;
116 m_request_manager.SetMaxIdleRequests(static_cast<unsigned>(max_pending_ops));
117 }
118 }
119 Config.Close();
120
121 // Internal override: allow xrdtpc to use a different ca dir from the one prepared by the xrootd
122 // framework. meant for exceptional situations where the site might need a specially-prepared set
123 // of cas only for tpc (such as trying out various workarounds for libnss). Explicitly disables
124 // the NSS hack below.
125 auto env_cadir = getenv("XRDTPC_CADIR");
126 if (env_cadir) m_cadir = env_cadir;
127
128 const char *cadir = nullptr, *cafile = nullptr;
129 if ((cadir = env_cadir ? env_cadir : myEnv->Get("http.cadir"))) {
130 m_cadir = cadir;
131 if (!env_cadir) {
132 m_ca_file.reset(new XrdTlsTempCA(&m_log, m_cadir));
133 if (!m_ca_file->IsValid()) {
134 m_log.Emsg("Config", "CAs / CRL generation for libcurl failed.");
135 return false;
136 }
137 }
138 }
139 if ((cafile = myEnv->Get("http.cafile"))) {
140 m_cafile = cafile;
141 }
142
143 if (!cadir && !cafile) {
144 // We do not necessary need TLS to perform HTTP TPC transfers, just log that these values were not specified
145 m_log.Emsg("Config", "neither xrd.tls cadir nor certfile value specified; is TLS enabled?");
146 }
147
148 void *sfs_raw_ptr;
149 if ((sfs_raw_ptr = myEnv->GetPtr("XrdSfsFileSystem*"))) {
150 m_sfs = static_cast<XrdSfsFileSystem*>(sfs_raw_ptr);
151 m_log.Emsg("Config", "Using filesystem object from the framework.");
152 return true;
153 } else {
154 m_log.Emsg("Config", "No filesystem object available to HTTP-TPC subsystem. Internal error.");
155 return false;
156 }
157 return true;
158}
159
160bool TPCHandler::ConfigureLogger(XrdOucStream &config_obj)
161{
162 char *val = config_obj.GetWord();
163 if (!val || !val[0])
164 {
165 m_log.Emsg("Config", "tpc.trace requires at least one directive [all | error | warning | info | debug | none]");
166 return false;
167 }
168 // If the config option is given, reset the log mask.
169 m_log.setMsgMask(0);
170
171 do {
172 if (!strcasecmp(val, "all"))
173 {
174 m_log.setMsgMask(m_log.getMsgMask() | LogMask::All);
175 }
176 else if (!strcasecmp(val, "error"))
177 {
178 m_log.setMsgMask(m_log.getMsgMask() | LogMask::Error);
179 }
180 else if (!strcasecmp(val, "warning"))
181 {
182 m_log.setMsgMask(m_log.getMsgMask() | LogMask::Warning);
183 }
184 else if (!strcasecmp(val, "info"))
185 {
186 m_log.setMsgMask(m_log.getMsgMask() | LogMask::Info);
187 }
188 else if (!strcasecmp(val, "debug"))
189 {
190 m_log.setMsgMask(m_log.getMsgMask() | LogMask::Debug);
191 }
192 else if (!strcasecmp(val, "none"))
193 {
194 m_log.setMsgMask(0);
195 }
196 else
197 {
198 m_log.Emsg("Config", "tpc.trace encountered an unknown directive (valid values: [all | error | warning | info | debug | none]):", val);
199 return false;
200 }
201 val = config_obj.GetWord();
202 } while (val);
203
204 return true;
205}
A pragmatic implementation of the HTTP/DAV protocol for the Xrd framework.
#define open
Definition XrdPosix.hh:76
static int parseHeader2CGI(XrdOucStream &Config, XrdSysError &err, std::map< std::string, std::string > &header2cgi)
Use this function to parse header2cgi configurations.
char * Get(const char *varname)
Definition XrdOucEnv.hh:69
void * GetPtr(const char *varname)
Definition XrdOucEnv.cc:281
char * GetWord(int lowcase=0)
static std::map< std::string, T >::const_iterator caseInsensitiveFind(const std::map< std::string, T > &m, const std::string &lowerCaseSearchKey)
static int a2i(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
Definition XrdOuca2x.cc:45
static int a2tm(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
Definition XrdOuca2x.cc:288
XrdCmsConfig Config