991 {
994 std::vector<extHInfo> extHIVec;
995 char *var;
996 int cfgFD, GoNo, NoGo = 0, ismine;
997
998 var = nullptr;
1001
1002 pmarkHandle = (
XrdNetPMark* ) myEnv->GetPtr(
"XrdNetPMark*");
1003
1004 cksumHandler.configure(xrd_cslist);
1005 auto nonIanaChecksums = cksumHandler.getNonIANAConfiguredCksums();
1006 if(nonIanaChecksums.size()) {
1007 std::stringstream warningMsgSS;
1008 warningMsgSS << "Config warning: the following checksum algorithms are not IANA compliant: [";
1009 std::string unknownCksumString;
1010 for(auto unknownCksum: nonIanaChecksums) {
1011 unknownCksumString += unknownCksum + ",";
1012 }
1013 unknownCksumString.erase(unknownCksumString.size() - 1);
1014 warningMsgSS << unknownCksumString << "]" << ". They therefore cannot be queried by a user via HTTP." ;
1015 eDest.
Say(warningMsgSS.str().c_str());
1016 }
1017
1018
1019 if (!m_bio_type) {
1020
1021 #if OPENSSL_VERSION_NUMBER < 0x10100000L
1022 m_bio_type = (26|0x0400|0x0100);
1023 m_bio_method = static_cast<BIO_METHOD*>(OPENSSL_malloc(sizeof(BIO_METHOD)));
1024
1025 if (m_bio_method) {
1026 memset(m_bio_method, '\0', sizeof(BIO_METHOD));
1027 m_bio_method->type = m_bio_type;
1033 }
1034 #else
1035
1036
1037 m_bio_type = BIO_get_new_index();
1038 m_bio_method = BIO_meth_new(m_bio_type, "xrdhttp-bio-method");
1039
1040 if (m_bio_method) {
1046 }
1047
1048 #endif
1049 }
1050
1051
1052
1053
1055
1056
1057
1058 if ((cfgFD =
open(ConfigFN, O_RDONLY, 0)) < 0)
1059 return eDest.
Emsg(
"Config", errno,
"open config file", ConfigFN);
1061 static const char *cvec[] = { "*** http protocol config:", 0 };
1063
1064
1065
1066 while ((var =
Config.GetMyFirstWord())) {
1067 if ((ismine = !strncmp("http.", var, 5)) && var[5]) var += 5;
1068
1069 if (ismine) {
1070 if TS_Xeq(
"trace", xtrace);
1071 else if TS_Xeq(
"cert", xsslcert);
1072 else if TS_Xeq(
"key", xsslkey);
1073 else if TS_Xeq(
"cadir", xsslcadir);
1074 else if TS_Xeq(
"cipherfilter", xsslcipherfilter);
1075 else if TS_Xeq(
"gridmap", xgmap);
1076 else if TS_Xeq(
"cafile", xsslcafile);
1077 else if TS_Xeq(
"secretkey", xsecretkey);
1078 else if TS_Xeq(
"desthttps", xdesthttps);
1079 else if TS_Xeq(
"secxtractor", xsecxtractor);
1080 else if TS_Xeq(
"cors", xcors);
1081 else if TS_Xeq3(
"exthandler", xexthandler);
1082 else if TS_Xeq(
"selfhttps2http", xselfhttps2http);
1083 else if TS_Xeq(
"embeddedstatic", xembeddedstatic);
1084 else if TS_Xeq(
"listingredir", xlistredir);
1085 else if TS_Xeq(
"staticredir", xstaticredir);
1086 else if TS_Xeq(
"staticpreload", xstaticpreload);
1087 else if TS_Xeq(
"staticheader", xstaticheader);
1088 else if TS_Xeq(
"listingdeny", xlistdeny);
1089 else if TS_Xeq(
"header2cgi", xheader2cgi);
1090 else if TS_Xeq(
"httpsmode", xhttpsmode);
1091 else if TS_Xeq(
"tlsreuse", xtlsreuse);
1092 else if TS_Xeq(
"auth", xauth);
1093 else if TS_Xeq(
"tlsclientauth", xtlsclientauth);
1094 else if TS_Xeq(
"maxdelay", xmaxdelay);
1095 else {
1096 eDest.
Say(
"Config warning: ignoring unknown directive '", var,
"'.");
1098 continue;
1099 }
1100 if (GoNo) {
1102 NoGo = 1;
1103 }
1104 }
1105 }
1106
1107
1108
1109
1110 if (NoGo)
1111 {
eDest.
Say(
"Config failure: one or more directives are flawed!");
1112 return 1;
1113 }
1114
1115
1116
1117 hdr2cgimap["Cache-Control"] = "cache-control";
1118
1119
1120 if (getenv(
"XRDCL_EC"))
usingEC =
true;
1121
1122
1123
1124 const auto default_verb = m_staticheader_map.find("");
1125 std::string default_static_headers;
1126 if (default_verb != m_staticheader_map.end()) {
1127 for (const auto &header_entry : default_verb->second) {
1128 default_static_headers += header_entry.first + ": " + header_entry.second + "\r\n";
1129 }
1130 }
1131 m_staticheaders[""] = default_static_headers;
1132 for (const auto &item : m_staticheader_map) {
1133 if (item.first.empty()) {
1134 continue;
1135 }
1136 auto headers = default_static_headers;
1137 for (const auto &header_entry : item.second) {
1138 headers += header_entry.first + ": " + header_entry.second + "\r\n";
1139 }
1140
1141 m_staticheaders[item.first] = headers;
1142 }
1143
1144
1145
1146 if (myEnv->Get("XrdCache")) hasCache = true;
1147
1148
1149 if(xrdcorsLibPath.size()) {
1150 if(LoadCorsHandler(&
eDest, xrdcorsLibPath.c_str()) != 0) {
1151 return 1;
1152 }
1153 if (xrdcors->Configure(ConfigFN, &
eDest) != 0) {
1154 return 1;
1155 }
1156 }
1157
1158
1159
1160
1161
1162
1165 : "was not configured.");
1166 const char *what = Configed();
1167
1168 eDest.
Say(
"Config warning: HTTPS functionality ", why);
1170
1171 LoadExtHandlerNoTls(extHIVec, ConfigFN, *myEnv);
1172 if (what)
1173 {
eDest.
Say(
"Config failure: ", what,
" HTTPS but it ", why);
1174 NoGo = 1;
1175 }
1176 return NoGo;
1177 }
1178
1179
1180
1181
1182 if (sslkey && !sslcert)
1183 {
eDest.
Say(
"Config warning: specifying http.key without http.cert "
1184 "is meaningless; ignoring key!");
1185 free(sslkey); sslkey = 0;
1186 }
1187
1188
1189
1191 {if (!sslcert)
1192 {
eDest.
Say(
"Config failure: 'httpsmode manual' requires atleast a "
1193 "a cert specification!");
1194 return 1;
1195 }
1196 }
1197
1198
1199
1200
1201
1204 const char *what1 = 0, *what2 = 0, *what3 = 0;
1205
1206 if (!sslcert && cP->
cert.size())
1207 {sslcert = strdup(cP->
cert.c_str());
1208 if (cP->
pkey.size()) sslkey = strdup(cP->
pkey.c_str());
1209 what1 = "xrd.tls to supply 'cert' and 'key'.";
1210 }
1211 if (!sslcadir && cP->
cadir.size())
1212 {sslcadir = strdup(cP->
cadir.c_str());
1213 what2 = "xrd.tlsca to supply 'cadir'.";
1214 }
1215 if (!sslcafile && cP->
cafile.size())
1216 {sslcafile = strdup(cP->
cafile.c_str());
1217 what2 = (what2 ? "xrd.tlsca to supply 'cadir' and 'cafile'."
1218 : "xrd.tlsca to supply 'cafile'.");
1219 }
1221 crlRefIntervalSec = cP->
crlRT;
1222 what3 = "xrd.tlsca to supply 'refresh' interval.";
1223 }
1227 }
1228
1229
1230
1231 if (!(sslcadir || sslcafile))
1232 {const char *what = Configed();
1233 const char *why = (
httpsspec ?
"a cadir or cafile was not specified!"
1234 : "'xrd.tlsca noverify' was specified!");
1235 if (what)
1236 {
eDest.
Say(
"Config failure: ", what,
" cert verification but ", why);
1237 return 1;
1238 }
1239 }
1241
1242
1243
1244 sslbio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
1245
1246
1247
1248
1249 const char *how = "completed.";
1250 eDest.
Say(
"++++++ HTTPS initialization started.");
1251 if (!InitTLS()) {NoGo = 1; how = "failed.";}
1252 eDest.
Say(
"------ HTTPS initialization ", how);
1253 if (NoGo) return NoGo;
1254
1255
1256
1257 if (LoadExtHandler(extHIVec, ConfigFN, *myEnv)) return 1;
1258
1259
1260
1261 return (InitSecurity() ? NoGo : 1);
1262}
1263
1264
1265
1266
1267
1268const char *XrdHttpProtocol::Configed()
1269{
1270 if (secxtractor &&
gridmap)
return "gridmap and secxtractor require";
1271 if (secxtractor) return "secxtractor requires";
1272 if (
gridmap)
return "gridmap requires";
1273 return 0;
1274}
1275
1276
1277
1278
1279
1281
1283
1284 dest = "";
1285 char save;
1286
1287
1288 if (myBuffEnd >= myBuffStart) {
1289 int l = 0;
1290 for (char *p = myBuffStart; p < myBuffEnd; p++) {
1291 l++;
1292 if (*p == '\n') {
1293 save = *(p+1);
1294 *(p+1) = '\0';
1295 dest.
assign(myBuffStart, 0, l-1);
1296 *(p+1) = save;
1297
1298
1299
1300 BuffConsume(l);
1301
1302
1303 return l;
1304 }
1305
1306 }
1307
1308 return 0;
1309 } else {
1310
1311
1312
1313 int l = 0;
1314 for (
char *p = myBuffStart; p < myBuff->
buff + myBuff->
bsize; p++) {
1315 l++;
1316 if ((*p == '\n') || (*p == '\0')) {
1317 save = *(p+1);
1318 *(p+1) = '\0';
1319 dest.
assign(myBuffStart, 0, l-1);
1320 *(p+1) = save;
1321
1322
1323
1324 BuffConsume(l);
1325
1326
1327 return l;
1328 }
1329
1330 }
1331
1332
1333
1334 l = 0;
1335 for (
char *p = myBuff->
buff; p < myBuffEnd; p++) {
1336 l++;
1337 if ((*p == '\n') || (*p == '\0')) {
1338 save = *(p+1);
1339 *(p+1) = '\0';
1340
1341 int l1 = myBuff->
buff + myBuff->
bsize - myBuffStart;
1342
1343 dest.
assign(myBuffStart, 0, l1-1);
1344
1345 BuffConsume(l1);
1346
1347 dest.
insert(myBuffStart, l1, l-1);
1348
1349
1350 BuffConsume(l);
1351
1352 *(p+1) = save;
1353
1354
1355 return l + l1;
1356 }
1357
1358 }
1359
1360
1361
1362 }
1363
1364 return 0;
1365}
1366
1367
1368
1369
1370
1371int XrdHttpProtocol::getDataOneShot(int blen, bool wait) {
1372 int rlen, maxread;
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386 maxread = std::min(blen, BuffAvailable());
1387 TRACE(
DEBUG,
"getDataOneShot BuffAvailable: " << BuffAvailable() <<
" maxread: " << maxread);
1388
1389 if (!maxread)
1390 return 2;
1391
1392 if (ishttps) {
1393 int sslavail = maxread;
1394
1395 if (!wait) {
1396 int l = SSL_pending(ssl);
1397 if (l > 0)
1398 sslavail = std::min(maxread, SSL_pending(ssl));
1399 }
1400
1401 if (sslavail < 0) {
1403 ERR_print_errors(sslbio_err);
1404 return -1;
1405 }
1406
1407 TRACE(
DEBUG,
"getDataOneShot sslavail: " << sslavail);
1408 if (sslavail <= 0) return 0;
1409
1410 if (myBuffEnd - myBuff->
buff >= myBuff->
bsize) {
1412 myBuffEnd = myBuff->
buff;
1413 }
1414
1415 rlen = SSL_read(ssl, myBuffEnd, sslavail);
1416 if (rlen <= 0) {
1418 ERR_print_errors(sslbio_err);
1419 return -1;
1420 }
1421
1422
1423 } else {
1424
1425 if (myBuffEnd - myBuff->
buff >= myBuff->
bsize) {
1427 myBuffEnd = myBuff->
buff;
1428 }
1429
1430 if (wait)
1432 else
1433 rlen =
Link->
Recv(myBuffEnd, maxread);
1434
1435
1436 if (rlen == 0) {
1438 return -1;
1439 }
1440
1441 if (rlen < 0) {
1443 return -1;
1444 }
1445 }
1446
1447 myBuffEnd += rlen;
1448
1449 TRACE(REQ,
"read " << rlen <<
" of " << blen <<
" bytes");
1450
1451 return 0;
1452}
1453
1455
1456int XrdHttpProtocol::BuffAvailable() {
1457 int r;
1458
1459 if (myBuffEnd >= myBuffStart)
1460 r = myBuff->
buff + myBuff->
bsize - myBuffEnd;
1461 else
1462 r = myBuffStart - myBuffEnd;
1463
1464 if ((r < 0) || (r > myBuff->
bsize)) {
1465 TRACE(REQ,
"internal error, myBuffAvailable: " << r <<
" myBuff->bsize " << myBuff->
bsize);
1466 abort();
1467 }
1468
1469 return r;
1470}
1471
1472
1473
1474
1475
1477
1478int XrdHttpProtocol::BuffUsed() {
1479 int r;
1480
1481 if (myBuffEnd >= myBuffStart)
1482 r = myBuffEnd - myBuffStart;
1483 else
1484
1485 r = myBuff->
bsize - (myBuffStart - myBuffEnd);
1486
1487 if ((r < 0) || (r > myBuff->
bsize)) {
1488 TRACE(REQ,
"internal error, myBuffUsed: " << r <<
" myBuff->bsize " << myBuff->
bsize);
1489 abort();
1490 }
1491
1492 return r;
1493}
1494
1495
1496
1497
1498
1500
1501int XrdHttpProtocol::BuffFree() {
1502 return (myBuff->
bsize - BuffUsed());
1503}
1504
1505
1506
1507
1508
1509void XrdHttpProtocol::BuffConsume(int blen) {
1510
1511 if (blen > myBuff->
bsize) {
1512 TRACE(REQ,
"internal error, BuffConsume(" << blen <<
") smaller than buffsize");
1513 abort();
1514 }
1515
1516 if (blen > BuffUsed()) {
1517 TRACE(REQ,
"internal error, BuffConsume(" << blen <<
") larger than BuffUsed:" << BuffUsed());
1518 abort();
1519 }
1520
1521 myBuffStart = myBuffStart + blen;
1522
1523 if (myBuffStart >= myBuff->
buff + myBuff->
bsize)
1524 myBuffStart -= myBuff->
bsize;
1525
1526 if (myBuffEnd >= myBuff->
buff + myBuff->
bsize)
1527 myBuffEnd -= myBuff->
bsize;
1528
1529 if (BuffUsed() == 0)
1530 myBuffStart = myBuffEnd = myBuff->
buff;
1531}
1532
1533
1534
1535
1536
1545int XrdHttpProtocol::BuffgetData(int blen, char **data, bool wait) {
1546 int rlen;
1547
1548 TRACE(
DEBUG,
"BuffgetData: requested " << blen <<
" bytes");
1549
1550
1551 if (wait) {
1552
1553 if (blen > BuffUsed()) {
1554 TRACE(REQ,
"BuffgetData: need to read " << blen - BuffUsed() <<
" bytes");
1555 if ( getDataOneShot(blen - BuffUsed(), true) )
1556
1557 return 0;
1558 }
1559 } else {
1560
1561 if ( !BuffUsed() ) {
1562 if ( getDataOneShot(blen, false) )
1563
1564 return -1;
1565 }
1566 }
1567
1568
1569
1570 if (myBuffStart <= myBuffEnd) {
1571 rlen = std::min( (long) blen, (long)(myBuffEnd - myBuffStart) );
1572
1573 } else
1574 rlen = std::min( (
long) blen, (
long)(myBuff->
buff + myBuff->
bsize - myBuffStart) );
1575
1576 *data = myBuffStart;
1577 BuffConsume(rlen);
1578 return rlen;
1579}
1580
1581
1582
1583
1584
1586
1587int XrdHttpProtocol::SendData(const char *body, int bodylen) {
1588
1589 int r;
1590
1591 if (body && bodylen) {
1592 TRACE(REQ,
"Sending " << bodylen <<
" bytes");
1593 if (ishttps) {
1594 r = SSL_write(ssl, body, bodylen);
1595 if (r <= 0) {
1596 ERR_print_errors(sslbio_err);
1597 return -1;
1598 }
1599
1600 } else {
1602 if (r <= 0) return -1;
1603 }
1604 }
1605
1606 return 0;
1607}
1608
1609
1610
1611
1612
1613int XrdHttpProtocol::StartSimpleResp(int code, const char *desc,
1614 const char *header_to_add,
1615 long long bodylen, bool keepalive) {
1616 std::stringstream ss;
1617 const std::string crlf = "\r\n";
1618
1619 ss << "HTTP/1.1 " << code << " ";
1620
1621 if (desc) {
1622 ss << desc;
1623 } else {
1625 }
1626 ss << crlf;
1627
1628 if (keepalive && (code != 100))
1629 ss << "Connection: Keep-Alive" << crlf;
1630 else
1631 ss << "Connection: Close" << crlf;
1632
1633 ss << "Server: XrootD/" << XrdVSTRING << crlf;
1634
1637 ss << iter->second;
1638 } else {
1640 }
1641
1644 if(corsAllowOrigin) {
1645 ss << *corsAllowOrigin << crlf;
1646 }
1647 }
1648
1649 if ((bodylen >= 0) && (code != 100))
1650 ss << "Content-Length: " << bodylen << crlf;
1651
1652 if (header_to_add && (header_to_add[0] != '\0')) ss << header_to_add << crlf;
1653
1654 ss << crlf;
1655
1656 const std::string &outhdr = ss.str();
1657 TRACEI(RSP,
"Sending resp: " << code <<
" header len:" << outhdr.size());
1658 if (SendData(outhdr.c_str(), outhdr.size()))
1659 return -1;
1660
1661 return 0;
1662}
1663
1664
1665
1666
1667
1668int XrdHttpProtocol::StartChunkedResp(int code, const char *desc, const char *header_to_add, long long bodylen, bool keepalive) {
1669 const std::string crlf = "\r\n";
1670 std::stringstream ss;
1671
1672 if (header_to_add && (header_to_add[0] != '\0')) {
1673 ss << header_to_add << crlf;
1674 }
1675
1676 ss << "Transfer-Encoding: chunked";
1677 TRACEI(RSP,
"Starting chunked response");
1678 return StartSimpleResp(code, desc, ss.str().c_str(), bodylen, keepalive);
1679}
1680
1681
1682
1683
1684
1685int XrdHttpProtocol::ChunkResp(const char *body, long long bodylen) {
1686 long long content_length = (bodylen <= 0) ? (body ? strlen(body) : 0) : bodylen;
1687 if (ChunkRespHeader(content_length))
1688 return -1;
1689
1690 if (body && SendData(body, content_length))
1691 return -1;
1692
1693 return ChunkRespFooter();
1694}
1695
1696
1697
1698
1699
1700int XrdHttpProtocol::ChunkRespHeader(long long bodylen) {
1701 const std::string crlf = "\r\n";
1702 std::stringstream ss;
1703
1704 ss << std::hex << bodylen << std::dec << crlf;
1705
1706 const std::string &chunkhdr = ss.str();
1707 TRACEI(RSP,
"Sending encoded chunk of size " << bodylen);
1708 return (SendData(chunkhdr.c_str(), chunkhdr.size())) ? -1 : 0;
1709}
1710
1711
1712
1713
1714
1715int XrdHttpProtocol::ChunkRespFooter() {
1716 const std::string crlf = "\r\n";
1717 return (SendData(crlf.c_str(), crlf.size())) ? -1 : 0;
1718}
1719
1720
1721
1722
1723
1727
1728int XrdHttpProtocol::SendSimpleResp(int code, const char *desc, const char *header_to_add, const char *body, long long bodylen, bool keepalive) {
1729
1730 long long content_length = bodylen;
1731 if (bodylen <= 0) {
1732 content_length = body ? strlen(body) : 0;
1733 }
1734
1735 if (StartSimpleResp(code, desc, header_to_add, content_length, keepalive) < 0)
1736 return -1;
1737
1738
1739
1740
1741 if (body)
1742 return SendData(body, content_length);
1743
1744 return 0;
1745}
1746
1747
1748
1749
1750
1752
1753
1754
1755
1756
1757
1758
1759
1760 char *rdf;
1761
1762
1763
1766
1770
1772
1773
1774
1776
1777 {
1778 char buf[16];
1779 sprintf(buf,
"%d",
Port);
1781 }
1782
1783
1784
1785 rdf = (parms && *parms ? parms : pi->
ConfigFN);
1786 if (rdf && Config(rdf, pi->
theEnv))
return 0;
1788
1789
1791 if ((rdf = getenv("XRDROLE"))) {
1793
1794 if (!strcasecmp(rdf, "manager") || !strcasecmp(rdf, "supervisor")) {
1796 eDest.
Emsg(
"Config",
"Configured as HTTP(s) redirector.");
1797 } else {
1798
1799 eDest.
Emsg(
"Config",
"Configured as HTTP(s) data server.");
1800 }
1801
1802 } else {
1803 eDest.
Emsg(
"Config",
"No XRDROLE specified.");
1804 }
1805
1806
1807
1811
1812
1813
1814
1815 return 1;
1816}
1817
1818
1819
1820
1822 char *val, keybuf[1024], parmbuf[1024];
1823 char *parm;
1824
1825
1827 if (!val || !val[0]) {
1828 err.
Emsg(
"Config",
"No headerkey specified.");
1829 return 1;
1830 } else {
1831
1832
1833 while ( *val && !isalnum(*val) ) val++;
1834 strcpy(keybuf, val);
1835
1836
1837 char *pp;
1838 pp = keybuf + strlen(keybuf) - 1;
1839 while ( (pp >= keybuf) && (!isalnum(*pp)) ) {
1840 *pp = '\0';
1841 pp--;
1842 }
1843
1845
1846
1847 if(!parm || !parm[0]) {
1848 err.
Emsg(
"Config",
"No header2cgi value specified. key: '", keybuf,
"'");
1849 return 1;
1850 }
1851
1852
1853 while ( *parm && !isalnum(*parm) ) parm++;
1854 strcpy(parmbuf, parm);
1855
1856
1857 pp = parmbuf + strlen(parmbuf) - 1;
1858 while ( (pp >= parmbuf) && (!isalnum(*pp)) ) {
1859 *pp = '\0';
1860 pp--;
1861 }
1862
1863
1864 try {
1865 header2cgi[keybuf] = parmbuf;
1866 } catch ( ... ) {
1867 err.
Emsg(
"Config",
"Can't insert new header2cgi rule. key: '", keybuf,
"'");
1868 return 1;
1869 }
1870
1871 }
1872 return 0;
1873}
1874
1875
1876
1877
1878
1879
1880bool XrdHttpProtocol::InitTLS() {
1881
1885
1886
1887
1890
1893
1894
1895
1898 return false;
1899 }
1900
1901
1902
1903
1904
1905 static const char *sess_ctx_id = "XrdHTTPSessionCtx";
1906 unsigned int n =(unsigned int)(strlen(sess_ctx_id)+1);
1908
1909
1910
1912 {
eDest.
Say(
"Config failure: ",
"Unable to set allowable https ciphers!");
1913 return false;
1914 }
1915
1916
1918
1919
1920
1921 return true;
1922}
1923
1924
1925
1926
1927
1928void XrdHttpProtocol::Cleanup() {
1929
1930 TRACE(ALL,
" Cleanup");
1931
1932 if (
BPool && myBuff) {
1933 BuffConsume(BuffUsed());
1935 myBuff = 0;
1936 }
1937
1938 if (ssl) {
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948 int ret = SSL_shutdown(ssl);
1949 if (ret != 1) {
1950 if(ret == 0) {
1951
1952 ret = SSL_shutdown(ssl);
1953 if (ret != 1) {
1954 TRACE(ALL,
"SSL server failed to receive the SSL shutdown message from the client");
1955 ERR_print_errors(sslbio_err);
1956 }
1957 } else {
1958
1959 TRACE(ALL,
"SSL server failed to send the shutdown message to the client");
1960 ERR_print_errors(sslbio_err);
1961 }
1962 }
1963
1964 if (secxtractor)
1966
1967 SSL_free(ssl);
1968
1969 }
1970
1971
1972 ssl = 0;
1973 sbio = 0;
1974
1983
1985
1988}
1989
1990
1991
1992
1993
1994void XrdHttpProtocol::Reset() {
1995
1996 TRACE(ALL,
" Reset");
2000
2001 if (myBuff) {
2003 myBuff = 0;
2004 }
2005 myBuffStart = myBuffEnd = 0;
2006
2007 DoingLogin = false;
2008 DoneSetInfo = false;
2009
2010 ResumeBytes = 0;
2011 Resume = 0;
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2028 ishttps = false;
2029 ssldone = false;
2030
2032 ssl = 0;
2033 sbio = 0;
2034
2035}
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052int XrdHttpProtocol::xhttpsmode(
XrdOucStream & Config) {
2053 char *val;
2054
2055
2056
2058 if (!val || !val[0]) {
2059 eDest.
Emsg(
"Config",
"httpsmode parameter not specified");
2060 return 1;
2061 }
2062
2063
2064
2068 else {
eDest.
Emsg(
"Config",
"invalid httpsmode parameter - ", val);
2069 return 1;
2070 }
2071 return 0;
2072}
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087int XrdHttpProtocol::xsslverifydepth(
XrdOucStream & Config) {
2088 char *val;
2089
2090
2091
2093 if (!val || !val[0]) {
2094 eDest.
Emsg(
"Config",
"sslverifydepth value not specified");
2095 return 1;
2096 }
2097
2098
2099
2101
2103 return 0;
2104}
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2120 char *val;
2121
2122
2123
2125 if (!val || !val[0]) {
2126 eDest.
Emsg(
"Config",
"HTTP X509 certificate not specified");
2127 return 1;
2128 }
2129
2130
2131
2134
2135
2136
2138 return 0;
2139}
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2155 char *val;
2156
2157
2158
2160 if (!val || !val[0]) {
2161 eDest.
Emsg(
"Config",
"HTTP X509 key not specified");
2162 return 1;
2163 }
2164
2165
2166
2169
2171 return 0;
2172}
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2192 char *val;
2193
2194
2195
2197 if (!val || !val[0]) {
2198 eDest.
Emsg(
"Config",
"HTTP X509 gridmap file location not specified");
2199 return 1;
2200 }
2201
2202
2203
2204 if (!strncmp(val, "required", 8)) {
2207
2208 if (!val || !val[0]) {
2209 eDest.
Emsg(
"Config",
"HTTP X509 gridmap file missing after [required] "
2210 "parameter");
2211 return 1;
2212 }
2213 }
2214
2215
2216
2217 if (!strcmp(val, "compatNameGeneration")) {
2220 if (!val || !val[0]) {
2221 eDest.
Emsg(
"Config",
"HTTP X509 gridmap file missing after "
2222 "[compatNameGeneration] parameter");
2223 return 1;
2224 }
2225 }
2226
2227
2228
2229
2232 return 0;
2233}
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248int XrdHttpProtocol::xsslcafile(
XrdOucStream & Config) {
2249 char *val;
2250
2251
2252
2254 if (!val || !val[0]) {
2255 eDest.
Emsg(
"Config",
"HTTP X509 CAfile not specified");
2256 return 1;
2257 }
2258
2259
2260
2263
2265 return 0;
2266}
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281int XrdHttpProtocol::xsecretkey(
XrdOucStream & Config) {
2282 char *val;
2283 bool inFile = false;
2284
2285
2286
2288 if (!val || !val[0]) {
2289 eDest.
Emsg(
"Config",
"Shared secret key not specified");
2290 return 1;
2291 }
2292
2293
2294
2295
2296
2297 if (val[0] == '/') {
2299 inFile = true;
2300 int fd =
open(val, O_RDONLY);
2301
2302 if ( fd == -1 ) {
2303 eDest.
Emsg(
"Config", errno,
"open shared secret key file", val);
2304 return 1;
2305 }
2306
2307 if (
fstat(fd, &st) != 0 ) {
2308 eDest.
Emsg(
"Config", errno,
"fstat shared secret key file", val);
2310 return 1;
2311 }
2312
2313 if ( st.st_mode & S_IWOTH & S_IWGRP & S_IROTH) {
2315 "For your own security, the shared secret key file cannot be world readable or group writable '", val, "'");
2317 return 1;
2318 }
2319
2320 FILE *fp = fdopen(fd, "r");
2321
2322 if ( fp == nullptr ) {
2323 eDest.
Emsg(
"Config", errno,
"fdopen shared secret key file", val);
2325 return 1;
2326 }
2327
2328 char line[1024];
2329 while( fgets(line, 1024, fp) ) {
2330 char *pp;
2331
2332
2333 pp = line + strlen(line) - 1;
2334 while ( (pp >= line) && (!isalnum(*pp)) ) {
2335 *pp = '\0';
2336 pp--;
2337 }
2338
2339
2340 pp = line;
2341 while ( *pp && !isalnum(*pp) ) pp++;
2342
2343 if ( strlen(pp) >= 32 ) {
2344 eDest.
Say(
"Config",
"Secret key loaded.");
2345
2348
2350 return 0;
2351 }
2352
2353 }
2354
2356 eDest.
Emsg(
"Config",
"Cannot find useful secretkey in file '", val,
"'");
2357 return 1;
2358
2359 }
2360
2361 if ( strlen(val) < 32 ) {
2362 eDest.
Emsg(
"Config",
"Secret key is too short");
2363 return 1;
2364 }
2365
2366
2369 if (!inFile)
Config.noEcho();
2370
2371 return 0;
2372}
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2388 char *val;
2389
2390
2391
2393 if (!val || !val[0]) {
2394 eDest.
Emsg(
"Config",
"listingdeny flag not specified");
2395 return 1;
2396 }
2397
2398
2399
2400 listdeny = (!strcasecmp(val,
"true") || !strcasecmp(val,
"yes") || !strcmp(val,
"1"));
2401
2402
2403 return 0;
2404}
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419int XrdHttpProtocol::xlistredir(
XrdOucStream & Config) {
2420 char *val;
2421
2422
2423
2425 if (!val || !val[0]) {
2426 eDest.
Emsg(
"Config",
"listingredir flag not specified");
2427 return 1;
2428 }
2429
2430
2431
2434
2435
2436 return 0;
2437}
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452int XrdHttpProtocol::xdesthttps(
XrdOucStream & Config) {
2453 char *val;
2454
2455
2456
2458 if (!val || !val[0]) {
2459 eDest.
Emsg(
"Config",
"desthttps flag not specified");
2460 return 1;
2461 }
2462
2463
2464
2465 isdesthttps = (!strcasecmp(val,
"true") || !strcasecmp(val,
"yes") || !strcmp(val,
"1"));
2466
2467
2468 return 0;
2469}
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484int XrdHttpProtocol::xembeddedstatic(
XrdOucStream & Config) {
2485 char *val;
2486
2487
2488
2490 if (!val || !val[0]) {
2491 eDest.
Emsg(
"Config",
"embeddedstatic flag not specified");
2492 return 1;
2493 }
2494
2495
2496
2497 embeddedstatic = (!strcasecmp(val,
"true") || !strcasecmp(val,
"yes") || !strcmp(val,
"1"));
2498
2499
2500 return 0;
2501}
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516int XrdHttpProtocol::xstaticredir(
XrdOucStream & Config) {
2517 char *val;
2518
2519
2520
2522 if (!val || !val[0]) {
2523 eDest.
Emsg(
"Config",
"staticredir url not specified");
2524 return 1;
2525 }
2526
2527
2528
2531
2532 return 0;
2533}
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551int XrdHttpProtocol::xstaticpreload(
XrdOucStream & Config) {
2552 char *val, *k, key[1024];
2553
2554
2555
2557 if (!k || !k[0]) {
2558 eDest.
Emsg(
"Config",
"preloadstatic urlpath not specified");
2559 return 1;
2560 }
2561
2562 strcpy(key, k);
2563
2564
2565
2567 if (!val || !val[0]) {
2568 eDest.
Emsg(
"Config",
"preloadstatic filename not specified");
2569 return 1;
2570 }
2571
2572
2573 int fp =
open(val, O_RDONLY);
2574 if( fp < 0 ) {
2575 eDest.
Emsg(
"Config", errno,
"open preloadstatic filename", val);
2576 return 1;
2577 }
2578
2579 StaticPreloadInfo *nfo = new StaticPreloadInfo;
2580
2581 nfo->data = (char *)malloc(65536);
2582 nfo->len =
read(fp, (
void *)nfo->data, 65536);
2584
2585 if (nfo->len <= 0) {
2586 eDest.
Emsg(
"Config", errno,
"read from preloadstatic filename", val);
2587 return 1;
2588 }
2589
2590 if (nfo->len >= 65536) {
2591 eDest.
Emsg(
"Config",
"Truncated preloadstatic filename. Max is 64 KB '", val,
"'");
2592 return 1;
2593 }
2594
2595
2596
2599
2601 return 0;
2602}
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621int XrdHttpProtocol::xstaticheader(
XrdOucStream & Config) {
2622 auto val =
Config.GetWord();
2623 std::vector<std::string> verbs;
2624 while (true) {
2625 if (!val || !val[0]) {
2626 eDest.
Emsg(
"Config",
"http.staticheader requires the header to be specified");
2627 return 1;
2628 }
2629
2630 std::string match_verb;
2631 std::string_view val_str(val);
2632 if (val_str.substr(0, 6) == "-verb=") {
2633 verbs.emplace_back(val_str.substr(6));
2634 } else if (val_str == "-") {
2635 eDest.
Emsg(
"Config",
"http.staticheader is ignoring unknown flag: ", val_str.data());
2636 } else {
2637 break;
2638 }
2639
2641 }
2642 if (verbs.empty()) {
2643 verbs.emplace_back();
2644 }
2645
2646 std::string header = val;
2647
2649 std::string header_value;
2650 if (val && val[0]) {
2651 header_value = val;
2652 }
2653
2654 for (const auto &verb : verbs) {
2657 if (!header_value.empty())
2659 } else if (header_value.empty()) {
2660 iter->second.clear();
2661 } else {
2662 iter->second.emplace_back(header, header_value);
2663 }
2664 }
2665
2666 return 0;
2667}
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683int XrdHttpProtocol::xselfhttps2http(
XrdOucStream & Config) {
2684 char *val;
2685
2686
2687
2689 if (!val || !val[0]) {
2690 eDest.
Emsg(
"Config",
"selfhttps2http flag not specified");
2691 return 1;
2692 }
2693
2694
2695
2696 selfhttps2http = (!strcasecmp(val,
"true") || !strcasecmp(val,
"yes") || !strcmp(val,
"1"));
2697
2698
2699 return 0;
2700}
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718int XrdHttpProtocol::xsecxtractor(
XrdOucStream& Config) {
2719 char *val;
2720
2721
2722
2724 if (!val || !val[0]) {
2725 eDest.
Emsg(
"Config",
"No security extractor plugin specified.");
2726 return 1;
2727 } else {
2728
2729
2730 if (!strncmp(val, "required", 8)) {
2731 isRequiredXtractor = true;
2733
2734 if (!val || !val[0]) {
2735 eDest.
Emsg(
"Config",
"No security extractor plugin after [required] "
2736 "parameter");
2737 return 1;
2738 }
2739 }
2740
2741 char libName[4096];
2742 strlcpy(libName, val,
sizeof(libName));
2743 libName[sizeof(libName) - 1] = '\0';
2744 char libParms[4096];
2745
2746 if (!
Config.GetRest(libParms, 4095)) {
2747 eDest.
Emsg(
"Config",
"secxtractor config params longer than 4k");
2748 return 1;
2749 }
2750
2751
2752
2753 if (LoadSecXtractor(&
eDest, libName, libParms)) {
2754 return 1;
2755 }
2756 }
2757
2758 return 0;
2759}
2760
2762 char * val;
2763
2765 if (!val || !val[0]) {
2766 eDest.
Emsg(
"Config",
"No CORS plugin specified.");
2767 return 1;
2768 }
2770 return 0;
2771}
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2791 std::vector<extHInfo> &hiVec) {
2792 char *val, path[1024], namebuf[1024];
2793 char *parm;
2794
2795 bool noTlsOK = false;
2796
2797
2798
2800 if (!val || !val[0]) {
2801 eDest.
Emsg(
"Config",
"No instance name specified for an http external handler plugin.");
2802 return 1;
2803 }
2804 if (strlen(val) >= 16) {
2805 eDest.
Emsg(
"Config",
"Instance name too long for an http external handler plugin.");
2806 return 1;
2807 }
2808 strncpy(namebuf, val, sizeof(namebuf));
2809 namebuf[ sizeof(namebuf)-1 ] = '\0';
2810
2811
2813
2814 if(val && !strcmp("+notls",val)) {
2815 noTlsOK = true;
2817 }
2818
2819
2820
2821 if (!val || !val[0]) {
2822 eDest.
Emsg(
"Config",
"No http external handler plugin specified.");
2823 return 1;
2824 }
2825 if (strlen(val) >= (int)sizeof(path)) {
2826 eDest.
Emsg(
"Config",
"Path too long for an http external handler plugin.");
2827 return 1;
2828 }
2829
2830 strcpy(path, val);
2831
2832
2833
2835
2836
2837
2838 for (int i = 0; i < (int)hiVec.size(); i++)
2839 {if (hiVec[i].extHName == namebuf) {
2840 eDest.
Emsg(
"Config",
"Instance name already present for "
2841 "http external handler plugin",
2842 hiVec[i].extHPath.c_str());
2843 return 1;
2844 }
2845 }
2846
2847
2848
2850 eDest.
Emsg(
"Config",
"Cannot load one more exthandler. Max is 4");
2851 return 1;
2852 }
2853
2854
2855
2856 hiVec.push_back(extHInfo(namebuf, path, (parm ? parm : ""), noTlsOK));
2857
2858 return 0;
2859}
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877int XrdHttpProtocol::xheader2cgi(
XrdOucStream & Config) {
2879}
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2895 char *val;
2896
2897
2898
2900 if (!val || !val[0]) {
2901 eDest.
Emsg(
"Config",
"HTTP X509 CAdir not specified");
2902 return 1;
2903 }
2904
2905
2906
2909
2911 return 0;
2912}
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928int XrdHttpProtocol::xsslcipherfilter(
XrdOucStream & Config) {
2929 char *val;
2930
2931
2932
2934 if (!val || !val[0]) {
2935 eDest.
Emsg(
"Config",
"SSL cipherlist filter string not specified");
2936 return 1;
2937 }
2938
2939
2940
2943
2944 return 0;
2945}
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2959
2960 char *val;
2961
2962
2963
2965 if (!val || !val[0])
2966 {
eDest.
Emsg(
"Config",
"tlsreuse argument not specified");
return 1;}
2967
2968
2969
2970 if (!strcmp(val, "off"))
2972 return 0;
2973 }
2974
2975
2976
2977 if (!strcmp(val, "on"))
2979 return 0;
2980 }
2981
2982
2983
2984 eDest.
Emsg(
"config",
"invalid tlsreuse parameter -", val);
2985 return 1;
2986}
2987
2988int XrdHttpProtocol::xtlsclientauth(
XrdOucStream &Config) {
2989 auto val =
Config.GetWord();
2990 if (!val || !val[0])
2991 {
eDest.
Emsg(
"Config",
"tlsclientauth argument not specified");
return 1;}
2992
2993 if (!strcmp(val, "off"))
2995 return 0;
2996 }
2997 if (!strcmp(val, "on"))
2999 return 0;
3000 }
3001
3002 eDest.
Emsg(
"config",
"invalid tlsclientauth parameter -", val);
3003 return 1;
3004}
3005
3007 char *val =
Config.GetWord();
3008 if(val) {
3009 if(!strcmp("tpc",val)) {
3010 if(!(val =
Config.GetWord())) {
3011 eDest.
Emsg(
"Config",
"http.auth tpc value not specified.");
return 1;
3012 } else {
3013 if(!strcmp("fcreds",val)) {
3015 } else {
3016 eDest.
Emsg(
"Config",
"http.auth tpc value is invalid");
return 1;
3017 }
3018 }
3019 } else {
3020 eDest.
Emsg(
"Config",
"http.auth value is invalid");
return 1;
3021 }
3022 }
3023 return 0;
3024}
3025
3027 char *val =
Config.GetWord();
3028 if(val) {
3029 int maxdelay;
3032 } else {
3033 eDest.
Emsg(
"Config",
"http.maxdelay requires an argument in seconds (default is 30). Example: http.maxdelay 30");
3034 return 1;
3035 }
3036 return 0;
3037}
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3054
3055 char *val;
3056
3057 static struct traceopts {
3058 const char *opname;
3059 int opval;
3060 } tropts[] = {
3068 };
3069 int i, neg, trval = 0, numopts = sizeof (tropts) / sizeof (struct traceopts);
3070
3071 if (!(val =
Config.GetWord())) {
3072 eDest.
Emsg(
"config",
"trace option not specified");
3073 return 1;
3074 }
3075 while (val) {
3076 if (!strcmp(val, "off")) trval = 0;
3077 else {
3078 if ((neg = (val[0] == '-' && val[1]))) val++;
3079 for (i = 0; i < numopts; i++) {
3080 if (!strcmp(val, tropts[i].opname)) {
3081 if (neg) trval &= ~tropts[i].opval;
3082 else trval |= tropts[i].opval;
3083 break;
3084 }
3085 }
3086 if (i >= numopts)
3087 eDest.
Emsg(
"config",
"invalid trace option", val);
3088 }
3090 }
3092 return 0;
3093}
3094
3096 int l;
3097 bool b;
3101
3106 l = strlen(fname) + 1;
3108
3111 if (!b) {
3112 return -1;
3113 }
3114
3115
3116 return 0;
3117}
3118
3119
3120
3121
3122
3124 size_t length;
3131 length = fname.
length() + 1;
3133
3135
3137}
3138
3139
3140static XrdVERSIONINFODEF(compiledVer, XrdHttpProtocolTest, XrdVNUMBER, XrdVERSION);
3141
3142
3143int XrdHttpProtocol::LoadSecXtractor(
XrdSysError *myeDest,
const char *libName,
3144 const char *libParms) {
3145
3146
3147
3148 if (secxtractor) return 1;
3149
3150 XrdOucPinLoader myLib(myeDest, &compiledVer,
"secxtractorlib", libName);
3152
3153
3154
3156 if (ep && (secxtractor = ep(myeDest, NULL, libParms))) return 0;
3157 myLib.Unload();
3158 return 1;
3159}
3160
3161
3162
3163
3164int XrdHttpProtocol::LoadExtHandlerNoTls(std::vector<extHInfo> &hiVec,
const char *cFN,
XrdOucEnv &myEnv) {
3165 for (int i = 0; i < (int) hiVec.size(); i++) {
3166 if(hiVec[i].extHNoTlsOK) {
3167
3168 if (LoadExtHandler(&
eDest, hiVec[i].extHPath.c_str(), cFN,
3169 hiVec[i].extHParm.c_str(), &myEnv,
3170 hiVec[i].extHName.c_str()))
3171 return 1;
3172 }
3173 }
3174 return 0;
3175}
3176
3177int XrdHttpProtocol::LoadExtHandler(std::vector<extHInfo> &hiVec,
3179
3180
3181
3186
3187
3188
3189 for (int i = 0; i < (int)hiVec.size(); i++) {
3190
3191
3192 if(!ExtHandlerLoaded(hiVec[i].extHName.c_str())) {
3193 if (LoadExtHandler(&
eDest, hiVec[i].extHPath.c_str(), cFN,
3194 hiVec[i].extHParm.c_str(), &myEnv,
3195 hiVec[i].extHName.c_str())) return 1;
3196 }
3197 }
3198 return 0;
3199}
3200
3201
3202int XrdHttpProtocol::LoadExtHandler(
XrdSysError *myeDest,
const char *libName,
3203 const char *configFN, const char *libParms,
3204 XrdOucEnv *myEnv,
const char *instName) {
3205
3206
3207
3208 if (ExtHandlerLoaded(instName)) {
3209 eDest.
Emsg(
"Config",
"Instance name already present for an http external handler plugin.");
3210 return 1;
3211 }
3213 eDest.
Emsg(
"Config",
"Cannot load one more exthandler. Max is 4");
3214 return 1;
3215 }
3216
3217 XrdOucPinLoader myLib(myeDest, &compiledVer,
"exthandlerlib", libName);
3219
3220
3221
3223
3225 if (ep && (newhandler = ep(myeDest, configFN, libParms, myEnv))) {
3226
3227
3228 strncpy( exthandler[exthandlercnt].name, instName, 16 );
3229 exthandler[exthandlercnt].name[15] = '\0';
3230 exthandler[exthandlercnt++].ptr = newhandler;
3231
3232 return 0;
3233 }
3234
3235 myLib.Unload();
3236 return 1;
3237}
3238
3239
3240int XrdHttpProtocol::LoadCorsHandler(
XrdSysError *
eDest,
const char *libname) {
3245 if(ep && (
xrdcors = ep()))
return 0;
3246 corsLib.Unload();
3247 return 1;
3248}
3249
3250
3251
3252bool XrdHttpProtocol::ExtHandlerLoaded(const char *handlername) {
3253 for (int i = 0; i < exthandlercnt; i++) {
3254 if ( !strncmp(exthandler[i].name, handlername, 15) ) {
3255 return true;
3256 }
3257 }
3258 return false;
3259}
3260
3261
3262
3264
3265 for (int i = 0; i < exthandlercnt; i++) {
3267 return exthandler[i].ptr;
3268 }
3269 }
3270 return NULL;
3271}
struct ClientQueryRequest query
struct ClientStatRequest stat
#define XrdHttpCorsGetHandlerArgs
#define XrdHttpExtHandlerArgs
static int BIO_XrdLink_create(BIO *bio)
const char * XrdHttpSecEntityTident
int BIO_XrdLink_write(BIO *bio, const char *data, size_t datal, size_t *written)
#define HTTPS_ALERT(x, y, z)
static long BIO_XrdLink_ctrl(BIO *bio, int cmd, long num, void *ptr)
XrdSysTrace XrdHttpTrace("http")
static int BIO_XrdLink_read(BIO *bio, char *data, size_t datal, size_t *read)
static int BIO_XrdLink_destroy(BIO *bio)
static XrdVERSIONINFODEF(compiledVer, XrdHttpProtocolTest, XrdVNUMBER, XrdVERSION)
#define MAX_XRDHTTPEXTHANDLERS
#define XrdHttpSecXtractorArgs
std::string httpStatusToString(int status)
#define TLS_SET_VDEPTH(cOpts, vdv)
#define TLS_SET_REFINT(cOpts, refi)
void Release(XrdBuffer *bp)
virtual std::optional< std::string > getCORSAllowOriginHeader(const std::string &origin)=0
static char * secretkey
The key used to calculate the url hashes.
static char * gridmap
Gridmap file location. The same used by XrdSecGsi.
static XrdScheduler * Sched
static kXR_int32 myRole
Our role.
static char * Port_str
Our port, as a string.
XrdXrootd::Bridge * Bridge
The Bridge that we use to exercise the xrootd internals.
static char * staticredir
static bool selfhttps2http
If client is HTTPS, self-redirect with HTTP+token.
int doChksum(const XrdOucString &fname)
Perform a checksum request.
static XrdOucHash< StaticPreloadInfo > * staticpreload
static char * xrd_cslist
The list of checksums that were configured via the xrd.cksum parameter on the server config file.
static char * sslcipherfilter
static std::map< std::string, std::string > hdr2cgimap
Rules that turn HTTP headers to cgi tokens in the URL, for internal comsumption.
static char * sslcert
OpenSSL stuff.
XrdLink * Link
The link we are bound to.
int doStat(char *fname)
Perform a Stat request.
static int readWait
Timeout for reading data.
static std::unordered_map< std::string, std::vector< std::pair< std::string, std::string > > > m_staticheader_map
The static headers to always return; map is from verb to a list of (header, val) pairs.
static XrdHttpCors * xrdcors
static bool compatNameGeneration
static std::string xrdcorsLibPath
static bool isdesthttps
True if the redirections must be towards https targets.
static XrdObjectQ< XrdHttpProtocol > ProtStack
static bool isRequiredGridmap
static char * listredir
Url to redirect to in the case a listing is requested.
static int crlRefIntervalSec
CRL thread refresh interval.
static XrdBuffManager * BPool
static std::unordered_map< std::string, std::string > m_staticheaders
static bool tpcForwardCreds
If set to true, the HTTP TPC transfers will forward the credentials to redirected hosts.
static bool listdeny
If true, any form of listing is denied.
static int parseHeader2CGI(XrdOucStream &Config, XrdSysError &err, std::map< std::string, std::string > &header2cgi)
Use this function to parse header2cgi configurations.
XrdSecEntity SecEntity
Authentication area.
static bool embeddedstatic
If true, use the embedded css and icons.
static int sslverifydepth
Depth of verification of a certificate chain.
static int Configure(char *parms, XrdProtocol_Config *pi)
Read and apply the configuration.
static int Configure(XrdSysError &Eroute, const char *const parms, Configuration &cfg)
int reqstate
State machine to talk to the bridge.
XrdOucString resource
The resource specified by the request, stripped of opaque data.
ClientRequest xrdreq
The last issued xrd request, often pending.
virtual int FreeSSL(SSL *)
int setEtext(const char *text)
int Recv(char *buff, int blen)
int Send(const char *buff, int blen)
void Set(int inQMax, time_t agemax=1800)
static bool Import(const char *var, char *&val)
void Put(const char *varname, const char *value)
T * Rep(const char *KeyVal, T *KeyData, const int LifeTime=0, XrdOucHash_Options opt=Hash_default)
void insert(const int i, int start=-1)
void assign(const char *s, int j, int k=-1)
const char * c_str() const
static int a2tm(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
char * vorg
Entity's virtual organization(s)
const char * tident
Trace identifier always preset.
char * caps
Entity's capabilities.
char * grps
Entity's group name(s)
void Reset(const char *spV=0)
char * name
Entity's name.
char * role
Entity's role(s)
char * endorsements
Protocol specific endorsements.
char * moninfo
Information for monitoring.
char * host
Entity's host name dnr dependent.
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
XrdSysLogger * logger(XrdSysLogger *lp=0)
void SetLogger(XrdSysLogger *logp)
int SessionCache(int opts=scNone, const char *id=0, int idlen=0)
static const int DEFAULT_CRL_REF_INT_SEC
Default CRL refresh interval in seconds.
static const uint64_t servr
This is a server context.
static const uint64_t rfCRL
Turn on the CRL refresh thread.
static const uint64_t logVF
Log verify failures.
static const uint64_t artON
Auto retry Handshake.
const CTX_Params * GetParams()
static const int scOff
Turn off cache.
bool SetContextCiphers(const char *ciphers)
static const int scSrvr
Turn on cache server mode (default)
void SetTlsClientAuth(bool setting)
virtual bool Run(const char *xreqP, char *xdataP=0, int xdataL=0)=0
std::string cafile
-> ca cert file.
std::string cadir
-> ca cert directory.
int crlRT
crl refresh interval time in seconds
std::string pkey
-> private key path.
std::string cert
-> certificate path.