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