19bool TPCHandler::Configure(
const char *configfn,
XrdOucEnv *myEnv)
22 XrdOucStream
Config(&m_log, getenv(
"XRDINSTANCE"), &cfgEnv,
"=====> ");
27 usingEC = getenv(
"XRDCL_EC")? true :
false;
29 allowMissingCRL = (bool) myEnv->
GetInt(
"http.allowmissingcrl");
31 std::string authLibParms;
32 int cfgFD =
open(configfn, O_RDONLY, 0);
34 m_log.Emsg(
"Config", errno,
"open config file", configfn);
38 static const char *cvec[] = {
"*** http tpc plugin config:", 0 };
41 while ((val =
Config.GetMyFirstWord())) {
42 if (!strcmp(
"http.desthttps", val)) {
43 if (!(val =
Config.GetWord())) {
45 m_log.Emsg(
"Config",
"http.desthttps value not specified");
48 if (!strcmp(
"1", val) || !strcasecmp(
"yes", val) || !strcasecmp(
"true", val)) {
50 }
else if (!strcmp(
"0", val) || !strcasecmp(
"no", val) || !strcasecmp(
"false", val)) {
54 m_log.Emsg(
"Config",
"https.desthttps value is invalid", val);
57 }
else if (!strcmp(
"tpc.allow", val)) {
58 if (!(val =
Config.GetWord())) {
60 m_log.Emsg(
"Config",
"tpc.allow value not specified");
63 if (strcmp(val,
"local") == 0) {
65 }
else if (strcmp(val,
"private") == 0) {
66 m_allow_private =
true;
69 m_log.Emsg(
"Config",
"tpc.allow value is invalid", val);
72 }
else if (!strcmp(
"tpc.deny", val)) {
73 if (!(val =
Config.GetWord())) {
75 m_log.Emsg(
"Config",
"tpc.deny value not specified");
78 if (strcmp(val,
"local") == 0) {
79 m_allow_local =
false;
80 }
else if (strcmp(val,
"private") == 0) {
81 m_allow_private =
false;
84 m_log.Emsg(
"Config",
"tpc.deny value is invalid", val);
87 }
else if (!strcmp(
"tpc.trace", val)) {
88 if (!ConfigureLogger(Config)) {
92 }
else if (!strcmp(
"tpc.fixed_route", val)) {
93 if (!(val =
Config.GetWord())) {
95 m_log.Emsg(
"Config",
"tpc.fixed_route value not specified");
98 if (!strcmp(
"1", val) || !strcasecmp(
"yes", val) || !strcasecmp(
"true", val)) {
100 }
else if (!strcmp(
"0", val) || !strcasecmp(
"no", val) || !strcasecmp(
"false", val)) {
101 m_fixed_route=
false;
104 m_log.Emsg(
"Config",
"tpc.fixed_route value is invalid", val);
107 }
else if (!strcmp(
"tpc.header2cgi",val)) {
116 if(authHdr != hdr2cgimap.end()) {
117 hdr2cgimap.erase(authHdr);
119 }
else if (!strcmp(
"tpc.low_speed", val)) {
120 if (!(val =
Config.GetWord())) {
122 m_log.Emsg(
"Config",
"tpc.low_speed rate not specified.");
126 long long low_speed_limit;
127 if (
XrdOuca2x::a2sz(m_log,
"low speed rate", val, &low_speed_limit, 0, LONG_MAX)) {
130 m_low_speed_limit =
static_cast<long>(low_speed_limit);
132 if ((val =
Config.GetWord())) {
134 if (
XrdOuca2x::a2tm(m_log,
"low speed time", val, &low_speed_time, 1)) {
137 m_low_speed_time = low_speed_time;
139 }
else if (!strcmp(
"tpc.timeout", val)) {
140 if (!(val =
Config.GetWord())) {
142 m_log.Emsg(
"Config",
"tpc.timeout value not specified.");
return false;
144 if (
XrdOuca2x::a2tm(m_log,
"timeout value", val, &m_timeout, 0))
return false;
146 if ((val =
Config.GetWord())) {
147 if (
XrdOuca2x::a2tm(m_log,
"first byte timeout value", val, &m_first_timeout, 0))
return false;
149 m_first_timeout = 2*m_timeout;
159 auto env_cadir = getenv(
"XRDTPC_CADIR");
160 if (env_cadir) m_cadir = env_cadir;
170 m_sslctx_supported = probe &&
171 curl_easy_setopt(probe.get(), CURLOPT_SSL_CTX_FUNCTION,
172 ssl_ctx_callback) == CURLE_OK;
173 if (!m_sslctx_supported) {
174 m_log.Emsg(
"Config",
"libcurl does not support CURLOPT_SSL_CTX_FUNCTION; "
175 "each transfer will parse the CA and CRL bundles for itself, "
176 "which costs significant memory per concurrent transfer.");
180 const char *cadir =
nullptr, *cafile =
nullptr;
181 if ((cadir = env_cadir ? env_cadir : myEnv->
Get(
"http.cadir"))) {
186 m_ca_file.reset(
new XrdTlsTempCA(&m_log, m_cadir, m_sslctx_supported));
187 if (!m_ca_file->IsValid()) {
188 m_log.Emsg(
"Config",
"CAs / CRL generation for libcurl failed.");
193 if ((cafile = myEnv->
Get(
"http.cafile"))) {
197 if (!cadir && !cafile) {
199 m_log.Emsg(
"Config",
"neither xrd.tls cadir nor certfile value specified; is TLS enabled?");
203 if ((sfs_raw_ptr = myEnv->
GetPtr(
"XrdSfsFileSystem*"))) {
204 m_sfs =
static_cast<XrdSfsFileSystem*
>(sfs_raw_ptr);
205 m_log.Emsg(
"Config",
"Using filesystem object from the framework.");
208 m_log.Emsg(
"Config",
"No filesystem object available to HTTP-TPC subsystem. Internal error.");
214bool TPCHandler::ConfigureLogger(XrdOucStream &config_obj)
216 char *val = config_obj.
GetWord();
219 m_log.Emsg(
"Config",
"tpc.trace requires at least one directive [all | error | warning | info | debug | none]");
226 if (!strcasecmp(val,
"all"))
230 else if (!strcasecmp(val,
"error"))
234 else if (!strcasecmp(val,
"warning"))
238 else if (!strcasecmp(val,
"info"))
242 else if (!strcasecmp(val,
"debug"))
246 else if (!strcasecmp(val,
"none"))
252 m_log.Emsg(
"Config",
"tpc.trace encountered an unknown directive (valid values: [all | error | warning | info | debug | none]):", val);
A pragmatic implementation of the HTTP/DAV protocol for the Xrd framework.
static int parseHeader2CGI(XrdOucStream &Config, XrdSysError &err, std::map< std::string, std::string > &header2cgi)
Use this function to parse header2cgi configurations.
long GetInt(const char *varname)
char * Get(const char *varname)
void * GetPtr(const char *varname)
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 a2sz(XrdSysError &, const char *emsg, const char *item, long long *val, long long minv=-1, long long maxv=-1)
static int a2tm(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
std::unique_ptr< CURL, CurlDeleter > ManagedCurlHandle