35 #include <sys/types.h>
59 using std::stringstream;
60 using std::istringstream;
68 #include "TheBESKeys.h"
71 #include "BESForbiddenError.h"
72 #include "BESNotFoundError.h"
73 #include "BESInternalError.h"
75 #include "BESCatalogList.h"
80 #define prolog string("BESUtil::").append(__func__).append("() - ")
82 const string BES_KEY_TIMEOUT_CANCEL =
"BES.CancelTimeoutOnSend";
90 strm <<
"HTTP/1.0 200 OK" << CRLF;
91 strm <<
"XBES-Server: " << PACKAGE_STRING << CRLF;
93 const time_t t = time(0);
94 strm <<
"Date: " << rfc822_date(t).c_str() << CRLF;
95 strm <<
"Last-Modified: " << rfc822_date(t).c_str() << CRLF;
97 strm <<
"Content-Type: text/plain" << CRLF;
99 strm <<
"Content-Description: unknown" << CRLF;
109 strm <<
"HTTP/1.0 200 OK" << CRLF;
110 strm <<
"XBES-Server: " << PACKAGE_STRING << CRLF;
112 const time_t t = time(0);
113 strm <<
"Date: " << rfc822_date(t).c_str() << CRLF;
114 strm <<
"Last-Modified: " << rfc822_date(t).c_str() << CRLF;
116 strm <<
"Content-type: text/html" << CRLF;
118 strm <<
"Content-Description: unknown" << CRLF;
154 static const char *days[] = {
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat" };
155 static const char *months[] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec" };
166 string BESUtil::rfc822_date(
const time_t t)
172 snprintf(d, 255,
"%s, %02d %s %4d %02d:%02d:%02d GMT", days[stm.tm_wday], stm.tm_mday,
173 months[stm.tm_mon], 1900 + stm.tm_year, stm.tm_hour, stm.tm_min, stm.tm_sec);
178 string BESUtil::unhexstring(
const string& s)
182 ss >> std::hex >> val;
184 tmp_str[0] =
static_cast<char>(val);
193 string::size_type i = 0;
195 while ((i = res.find_first_of(escape, i)) != string::npos) {
196 if (except.find(res.substr(i, 3)) != string::npos) {
200 res.replace(i, 3, unhexstring(res.substr(i + 1, 2)));
208 string return_string = s;
209 for (
int j = 0; j < static_cast<int>(return_string.length()); j++) {
210 return_string[j] = (char) tolower(return_string[j]);
213 return return_string;
219 string::size_type index = 0;
223 string::size_type bs = s.find(
'\\', index);
224 if (bs == string::npos) {
225 new_str += s.substr(index, s.length() - index);
229 new_str += s.substr(index, bs - index);
230 new_str += s[bs + 1];
264 if (path ==
"")
return;
269 int (*ye_old_stat_function)(
const char *pathname,
struct stat *buf);
270 if (follow_sym_links) {
271 BESDEBUG(MODULE, prolog <<
"Using 'stat' function (follow_sym_links = true)" << endl);
272 ye_old_stat_function = &stat;
275 BESDEBUG(MODULE,
"check_path() - Using 'lstat' function (follow_sym_links = false)" << endl);
276 ye_old_stat_function = &lstat;
281 string::size_type dotdot = path.find(
"..");
282 if (dotdot != string::npos) {
283 string s (
"Upward path traversal (i.e. '..') is not supported. path: ");
296 string remaining_path = path;
297 BESDEBUG(MODULE, prolog <<
"remaining_path: " << remaining_path << endl);
298 if (remaining_path[0] ==
'/') {
299 remaining_path = remaining_path.substr(1);
301 if (remaining_path[remaining_path.length() - 1] ==
'/') {
302 remaining_path = remaining_path.substr(0, remaining_path.length() - 1);
306 string fullpath = root;
308 if (fullpath[fullpath.length() - 1] ==
'/') {
309 fullpath = fullpath.substr(0, fullpath.length() - 1);
315 size_t slash = remaining_path.find(
'/');
316 if (slash == string::npos) {
318 fullpath.append(
"/").append(remaining_path);
324 fullpath.append(
"/").append(remaining_path.substr(0, slash));
325 remaining_path = remaining_path.substr(slash + 1, remaining_path.length() - slash);
328 BESDEBUG(MODULE, prolog <<
"Testing: " << fullpath << endl);
330 int statret = ye_old_stat_function(fullpath.c_str(), &buf);
335 char *s_err = strerror(errsv);
337 string error =
"Unable to access node " + fullpath +
": ";
341 error.append(
"unknown error");
346 if (errsv == ENOENT || errsv == ENOTDIR) {
349 ss <<
"Failed to locate resource " << fullpath;
350 BESDEBUG(MODULE, prolog <<
"ERROR: " << ss.str() <<
" errno: " << errno << endl);
355 ss <<
"Unable to access node " << fullpath;
356 BESDEBUG(MODULE, prolog <<
"ERROR: " << ss.str() <<
" errno: " << errno << endl);
365 if (S_ISLNK(buf.st_mode)) {
368 ss <<
"You do not have permission to access " << fullpath;
369 BESDEBUG(MODULE, prolog <<
"ERROR: " << ss.str() <<
" errno: " << errno << endl);
377 size_t slash = rem.find(
'/');
378 if (slash == string::npos) {
379 fullpath = fullpath +
"/" + rem;
380 checked = checked +
"/" + rem;
384 fullpath = fullpath +
"/" + rem.substr(0, slash);
385 checked = checked +
"/" + rem.substr(0, slash);
386 rem = rem.substr(slash + 1, rem.length() - slash);
389 if (!follow_sym_links) {
391 int statret = lstat(fullpath.c_str(), &buf);
396 char *s_err = strerror(errsv);
397 string error =
"Unable to access node " + checked +
": ";
399 error = error + s_err;
402 error = error +
"unknown access error";
406 if (errsv == ENOENT) {
415 if (S_ISLNK( buf.st_mode )) {
416 string error =
"You do not have permission to access "
426 int statret = stat(fullpath.c_str(), &buf);
431 char *s_err = strerror(errsv);
432 string error =
"Unable to access node " + checked +
": ";
434 error = error + s_err;
437 error = error +
"unknown access error";
441 if (errsv == ENOENT) {
467 if (base > 36 || base < 2)
472 if (val < 0) *buf++ =
'-';
473 r = ldiv(labs(val), base);
480 *buf++ =
"0123456789abcdefghijklmnopqrstuvwxyz"[(
int) r.rem];
488 string::size_type first = key.find_first_not_of(
" \t\n\r");
489 string::size_type last = key.find_last_not_of(
" \t\n\r");
490 if (first == string::npos)
493 string::size_type num = last - first + 1;
494 string new_key = key.substr(first, num);
500 string BESUtil::entity(
char c)
526 string::size_type i = 0;
528 while ((i = in.find_first_of(not_allowed, i)) != string::npos) {
529 in.replace(i, 1, entity(in[i]));
543 string::size_type i = 0;
545 while ((i = in.find(
">", i)) != string::npos)
546 in.replace(i, 4,
">");
549 while ((i = in.find(
"<", i)) != string::npos)
550 in.replace(i, 4,
"<");
553 while ((i = in.find(
"&", i)) != string::npos)
554 in.replace(i, 5,
"&");
557 while ((i = in.find(
"'", i)) != string::npos)
558 in.replace(i, 6,
"'");
561 while ((i = in.find(
""", i)) != string::npos)
562 in.replace(i, 6,
"\"");
582 std::string::size_type start = 0;
583 std::string::size_type qstart = 0;
584 std::string::size_type adelim = 0;
585 std::string::size_type aquote = 0;
589 if (str[start] ==
'"') {
590 bool endquote =
false;
593 aquote = str.find(
'"', qstart);
594 if (aquote == string::npos) {
595 string currval = str.substr(start, str.length() - start);
596 string err =
"BESUtil::explode - No end quote after value " + currval;
601 if (str[aquote - 1] ==
'\\') {
602 if (str[aquote - 2] ==
'\\') {
615 if (str[qstart] != delim && qstart != str.length()) {
616 string currval = str.substr(start, qstart - start);
617 string err =
"BESUtil::explode - No delim after end quote " + currval;
620 if (qstart == str.length()) {
621 adelim = string::npos;
628 adelim = str.find(delim, start);
630 if (adelim == string::npos) {
631 aval = str.substr(start, str.length() - start);
635 aval = str.substr(start, adelim - start);
638 values.push_back(aval);
640 if (start == str.length()) {
641 values.push_back(
"");
660 list<string>::const_iterator i = values.begin();
661 list<string>::const_iterator e = values.end();
664 for (; i != e; i++) {
665 if (!first) result += delim;
666 d = (*i).find(delim);
667 if (d != string::npos && (*i)[0] !=
'"') {
668 string err = (string)
"BESUtil::implode - delimiter exists in value " + (*i);
701 string::size_type colon = url_str.find(
":");
702 if (colon == string::npos) {
703 string err =
"BESUtil::url_explode: missing colon for protocol";
707 url_parts.protocol = url_str.substr(0, colon);
709 if (url_str.substr(colon, 3) !=
"://") {
710 string err =
"BESUtil::url_explode: no :// in the URL";
715 rest = url_str.substr(colon);
717 string::size_type slash = rest.find(
"/");
718 if (slash == string::npos) slash = rest.length();
720 string::size_type at = rest.find(
"@");
721 if ((at != string::npos) && (at < slash)) {
723 string up = rest.substr(0, at);
724 colon = up.find(
":");
725 if (colon != string::npos) {
726 url_parts.uname = up.substr(0, colon);
727 url_parts.psswd = up.substr(colon + 1);
730 url_parts.uname = up;
733 rest = rest.substr(at + 1);
735 slash = rest.find(
"/");
736 if (slash == string::npos) slash = rest.length();
737 colon = rest.find(
":");
738 if ((colon != string::npos) && (colon < slash)) {
740 url_parts.domain = rest.substr(0, colon);
742 rest = rest.substr(colon + 1);
743 slash = rest.find(
"/");
744 if (slash != string::npos) {
745 url_parts.port = rest.substr(0, slash);
746 url_parts.path = rest.substr(slash + 1);
749 url_parts.port = rest;
754 slash = rest.find(
"/");
755 if (slash != string::npos) {
756 url_parts.domain = rest.substr(0, slash);
757 url_parts.path = rest.substr(slash + 1);
760 url_parts.domain = rest;
767 string url = url_parts.protocol +
"://";
768 if (!url_parts.uname.empty()) {
769 url += url_parts.uname;
770 if (!url_parts.psswd.empty()) url +=
":" + url_parts.psswd;
773 url += url_parts.domain;
774 if (!url_parts.port.empty()) url +=
":" + url_parts.port;
775 if (!url_parts.path.empty()) url +=
"/" + url_parts.path;
793 string first = firstPart;
794 string second = secondPart;
795 string sep(1,separator);
799 while (!first.empty() && *first.rbegin() == separator) {
801 first = first.substr(0, first.length() - 1);
804 while (!second.empty() && second[0] == separator) {
812 else if (second.empty()) {
816 newPath = first.append(sep).append(second);
840 string BESUtil::assemblePath(
const string &firstPart,
const string &secondPart,
bool leadingSlash,
bool trailingSlash)
843 assert(!firstPart.empty());
846 string first = firstPart;
847 string second = secondPart;
850 if (ensureLeadingSlash && first[0] !=
'/')
854 if (second[0] ==
'/')
855 second = second.substr(1);
858 if (first.back() ==
'/')
859 return first.append(second);
861 return first.append(
"/").append(second);
865 BESDEBUG(MODULE, prolog <<
"firstPart: '" << firstPart <<
"'" << endl);
866 BESDEBUG(MODULE, prolog <<
"secondPart: '" << secondPart <<
"'" << endl);
871 string first = firstPart;
872 string second = secondPart;
876 while (!first.empty() && *first.rbegin() ==
'/') {
878 first = first.substr(0, first.length() - 1);
882 while (!second.empty() && second[0] ==
'/') {
892 else if (second.empty()) {
896 newPath = first.append(
"/").append(second);
902 if (newPath.empty()) {
905 else if (newPath.compare(0, 1,
"/")) {
906 newPath =
"/" + newPath;
911 if (newPath.compare(newPath.length(), 1,
"/")) {
912 newPath = newPath.append(
"/");
916 while(newPath.length()>1 && *newPath.rbegin() ==
'/')
917 newPath = newPath.substr(0,newPath.length()-1);
919 BESDEBUG(MODULE, prolog <<
"newPath: " << newPath << endl);
924 BESDEBUG(
"util",
"BESUtil::assemblePath() - firstPart: "<< firstPart << endl);
925 BESDEBUG(
"util",
"BESUtil::assemblePath() - secondPart: "<< secondPart << endl);
927 string first = firstPart;
928 string second = secondPart;
930 if (ensureLeadingSlash) {
931 if (*first.begin() !=
'/') first =
"/" + first;
935 while (*first.rbegin() ==
'/' && first.length() > 0) {
936 first = first.substr(0, first.length() - 1);
940 if (*first.rbegin() !=
'/') {
945 while (*second.begin() ==
'/' && second.length() > 0) {
946 second = second.substr(1);
949 string newPath = first + second;
951 BESDEBUG(
"util",
"BESUtil::assemblePath() - newPath: "<< newPath << endl);
963 if (fullString.length() >= ending.length()) {
964 return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending));
994 const string false_str =
"false";
995 const string no_str =
"no";
997 bool cancel_timeout_on_send =
true;
1004 if ( value == false_str || value == no_str) cancel_timeout_on_send =
false;
1006 BESDEBUG(MODULE, __func__ <<
"() - cancel_timeout_on_send: " << (cancel_timeout_on_send ?
"true" :
"false") << endl);
1007 if (cancel_timeout_on_send) alarm(0);
1017 unsigned int replace_count = 0;
1018 size_t pos = s.find(find_this);
1019 while (pos != string::npos) {
1021 s.replace(pos, find_this.size(), replace_with_this);
1023 pos = s.find(find_this, pos + replace_with_this.size());
1026 return replace_count;
1042 if (separator.length() != 1)
1043 throw BESInternalError(
"Path separators must be a single character. The string '" + separator +
"' does not qualify.", __FILE__, __LINE__);
1044 char separator_char = separator[0];
1045 string double_separator;
1046 double_separator = double_separator.append(separator).append(separator);
1048 string path(raw_path);
1055 if (path == separator) {
1058 if (leading_separator) {
1059 if (path[0] != separator_char) {
1060 path = string(separator).append(path);
1064 if (path[0] == separator_char) {
1065 path = path.substr(1);
1068 if (trailing_separator) {
1069 if (*path.rbegin() != separator_char) {
1070 path = path.append(separator);
1074 if (*path.rbegin() == separator_char) {
1075 path = path.substr(0, path.length() - 1);
1089 string::size_type lastPos = str.find_first_not_of(delimiters, 0);
1091 string::size_type pos = str.find_first_of(delimiters, lastPos);
1092 while (string::npos != pos || string::npos != lastPos) {
1094 tokens.push_back(str.substr(lastPos, pos - lastPos));
1096 lastPos = str.find_first_not_of(delimiters, pos);
1098 pos = str.find_first_of(delimiters, lastPos);
1110 return get_time(time(0), use_local_time);
1122 char buf[
sizeof "YYYY-MM-DDTHH:MM:SS zones"];
1132 if (!use_local_time) {
1133 gmtime_r(&the_time, &result);
1134 status = strftime(buf,
sizeof buf,
"%FT%T%Z", &result);
1137 localtime_r(&the_time, &result);
1138 status = strftime(buf,
sizeof buf,
"%FT%T%Z", &result);
1142 ERROR_LOG(prolog +
"Error formatting time value!");
1143 return "date-format-error";
1163 vector<string> tokens;
1165 while (getline(ss, item, delim)) {
1167 if (item.empty() && skip_empty)
1170 tokens.push_back(item);
1176 BESCatalog *BESUtil::separateCatalogFromPath(std::string &ppath)
1179 vector<string> path_tokens;
1183 BESDEBUG(MODULE, prolog <<
"Normalized path: " << path << endl);
1188 string use_container = ppath;
1192 if (!path_tokens.empty()) {
1193 BESDEBUG(MODULE,
"First path token: " << path_tokens[0] << endl);
1196 BESDEBUG(MODULE, prolog <<
"Located catalog " << catalog->
get_catalog_name() <<
" from path component" << endl);
1201 BESDEBUG(MODULE, prolog <<
"Modified container/path value to: " << use_container << endl);
1208 void ios_state_msg(std::ios &ios_ref, std::stringstream &msg) {
1209 msg <<
" {ios.good()=" << (ios_ref.good() ?
"true" :
"false") <<
"}";
1210 msg <<
" {ios.eof()=" << (ios_ref.eof()?
"true":
"false") <<
"}";
1211 msg <<
" {ios.fail()=" << (ios_ref.fail()?
"true":
"false") <<
"}";
1212 msg <<
" {ios.bad()=" << (ios_ref.bad()?
"true":
"false") <<
"}";
1217 #define OUTPUT_FILE_BLOCK_SIZE 4096
1229 msg << prolog <<
"Using ostream: " << (
void *) &o_strm <<
" cout: " << (
void *) &cout << endl;
1230 BESDEBUG(MODULE, msg.str());
1231 INFO_LOG( msg.str());
1233 char rbuffer[OUTPUT_FILE_BLOCK_SIZE];
1234 std::ifstream i_stream(file_name, std::ios_base::in | std::ios_base::binary);
1237 if(!i_stream.good()){
1239 msg << prolog <<
"Failed to open file " << file_name;
1240 ios_state_msg(i_stream, msg);
1241 BESDEBUG(MODULE, msg.str() << endl);
1248 msg << prolog <<
"Problem with ostream. " << file_name;
1249 ios_state_msg(i_stream, msg);
1250 BESDEBUG(MODULE, msg.str() << endl);
1256 uint64_t tcount = 0;
1257 while (i_stream.good() && o_strm.good()){
1258 i_stream.read(&rbuffer[0], OUTPUT_FILE_BLOCK_SIZE);
1259 o_strm.write(&rbuffer[0], i_stream.gcount());
1260 tcount += i_stream.gcount();
1265 if(i_stream.fail() && !i_stream.eof()){
1267 msg << prolog <<
"There was an ifstream error when reading from: " << file_name;
1268 ios_state_msg(i_stream, msg);
1269 msg <<
" last_lap: " << i_stream.gcount() <<
" bytes";
1270 msg <<
" total_read: " << tcount <<
" bytes";
1271 BESDEBUG(MODULE, msg.str() << endl);
1276 if (!i_stream.eof()){
1278 msg << prolog <<
"Failed to reach EOF on source file: " << file_name;
1279 ios_state_msg(i_stream, msg);
1280 msg <<
" last_lap: " << i_stream.gcount() <<
" bytes";
1281 msg <<
" total_read: " << tcount <<
" bytes";
1282 BESDEBUG(MODULE, msg.str() << endl);
1289 msg << prolog <<
"There was an ostream error during transmit. Transmitted " << tcount <<
" bytes.";
1290 ios_state_msg(o_strm, msg);
1291 auto crntpos = o_strm.tellp();
1292 msg <<
" current_position: " << crntpos << endl;
1293 BESDEBUG(MODULE, msg.str());
1294 ERROR_LOG(msg.str());
1299 msg << prolog <<
"Sent "<< tcount <<
" bytes from file '" << file_name<<
"'. " << endl;
1300 BESDEBUG(MODULE,msg.str());
1301 INFO_LOG(msg.str());
1304 uint64_t BESUtil::file_to_stream_helper(
const std::string &file_name, std::ostream &o_strm, uint64_t byteCount){
1307 msg << prolog <<
"Using ostream: " << (
void *) &o_strm <<
" cout: " << (
void *) &cout << endl;
1308 BESDEBUG(MODULE, msg.str());
1309 INFO_LOG( msg.str());
1311 char rbuffer[OUTPUT_FILE_BLOCK_SIZE];
1312 std::ifstream i_stream(file_name, std::ios_base::in | std::ios_base::binary);
1315 if(!i_stream.good()){
1317 msg << prolog <<
"Failed to open file " << file_name;
1318 ios_state_msg(i_stream, msg);
1319 BESDEBUG(MODULE, msg.str() << endl);
1326 msg << prolog <<
"Problem with ostream. " << file_name;
1327 ios_state_msg(i_stream, msg);
1328 BESDEBUG(MODULE, msg.str() << endl);
1333 i_stream.seekg(byteCount);
1337 while (i_stream.good() && o_strm.good()){
1338 i_stream.read(&rbuffer[0], OUTPUT_FILE_BLOCK_SIZE);
1339 o_strm.write(&rbuffer[0], i_stream.gcount());
1340 BESDEBUG(MODULE,
"i_stream: " << i_stream.gcount() << endl);
1341 byteCount += i_stream.gcount();
1346 if(i_stream.fail() && !i_stream.eof()){
1348 msg << prolog <<
"There was an ifstream error when reading from: " << file_name;
1349 ios_state_msg(i_stream, msg);
1350 msg <<
" last_lap: " << i_stream.gcount() <<
" bytes";
1351 msg <<
" total_read: " << byteCount <<
" bytes";
1352 BESDEBUG(MODULE, msg.str() << endl);
1357 if (!i_stream.eof()){
1359 msg << prolog <<
"Failed to reach EOF on source file: " << file_name;
1360 ios_state_msg(i_stream, msg);
1361 msg <<
" last_lap: " << i_stream.gcount() <<
" bytes";
1362 msg <<
" total_read: " << byteCount <<
" bytes";
1363 BESDEBUG(MODULE, msg.str() << endl);
1370 msg << prolog <<
"There was an ostream error during transmit. Transmitted " << byteCount <<
" bytes.";
1371 ios_state_msg(o_strm, msg);
1372 auto crntpos = o_strm.tellp();
1373 msg <<
" current_position: " << crntpos << endl;
1374 BESDEBUG(MODULE, msg.str());
1375 ERROR_LOG(msg.str());
1380 msg <<
"Sent "<< byteCount <<
" bytes from file '" << file_name<<
"'. " << endl;
1381 BESDEBUG(MODULE,msg.str());
1382 INFO_LOG(msg.str());
1392 #define FILE_CALLS 0
1401 msg << prolog <<
"Using ostream: " << (
void *) &o_strm <<
" cout: " << (
void *) &cout << endl;
1402 BESDEBUG(MODULE, msg.str());
1403 INFO_LOG(msg.str());
1405 char rbuffer[OUTPUT_FILE_BLOCK_SIZE];
1412 std::ifstream i_stream(file_name, std::ios_base::in | std::ios_base::binary);
1414 int fd = open(file_name.c_str(), O_RDONLY | O_NONBLOCK);
1420 BESDEBUG(MODULE,
"Starting transfer" << endl);
1421 uint64_t tcount = 0;
1422 while (!i_stream.bad() && !i_stream.fail() && o_strm.good()) {
1423 if (file_write_done && i_stream.eof()) {
1424 BESDEBUG(MODULE,
"breaking out of loop" << endl);
1428 i_stream.read(&rbuffer[0], OUTPUT_FILE_BLOCK_SIZE);
1431 int status = read(fd, &rbuffer[0], OUTPUT_FILE_BLOCK_SIZE);
1435 else if (status == -1) {
1436 BESDEBUG(MODULE,
"read() call error: " << errno << endl);
1439 o_strm.write(&rbuffer[0], status);
1443 o_strm.write(&rbuffer[0], i_stream.gcount());
1444 tcount += i_stream.gcount();
1445 BESDEBUG(MODULE,
"transfer bytes " << tcount << endl);
1457 msg << prolog <<
"There was an ostream error during transmit. Transmitted " << tcount <<
" bytes.";
1458 ios_state_msg(o_strm, msg);
1459 auto crntpos = o_strm.tellp();
1460 msg <<
" current_position: " << crntpos << endl;
1461 BESDEBUG(MODULE, msg.str());
1462 INFO_LOG(msg.str());
1466 msg <<
"Sent "<< tcount <<
" bytes from file '" << file_name<<
"'. " << endl;
1467 BESDEBUG(MODULE,msg.str());
1468 INFO_LOG(msg.str());
1486 void BESUtil::split(
const string &s,
const string &delimiter, vector<uint64_t> &res)
1488 const size_t delim_len = delimiter.length();
1490 size_t pos_start = 0, pos_end;
1492 while ((pos_end = s.find (delimiter, pos_start)) != string::npos) {
1493 res.push_back (stoull(s.substr(pos_start, pos_end - pos_start)));
1494 pos_start = pos_end + delim_len;
1497 res.push_back (stoull(s.substr (pos_start)));
1509 void BESUtil::split(
const string &s,
const string &delimiter, vector<string> &res)
1511 const size_t delim_len = delimiter.length();
1513 size_t pos_start = 0, pos_end;
1515 while ((pos_end = s.find (delimiter, pos_start)) != string::npos) {
1516 res.push_back(s.substr(pos_start, pos_end - pos_start));
1517 pos_start = pos_end + delim_len;
1520 res.push_back(s.substr (pos_start));
static BESCatalogList * TheCatalogList()
Get the singleton BESCatalogList instance.
Catalogs provide a hierarchical organization for data.
virtual std::string get_catalog_name() const
Get the name for this catalog.
error thrown if the BES is not allowed to access the resource requested
exception thrown if internal error encountered
error thrown if the resource requested cannot be found
static std::vector< std::string > split(const std::string &s, char delim='/', bool skip_empty=true)
Splits the string s into the return vector of tokens using the delimiter delim and skipping empty val...
static uint64_t file_to_stream_task(const std::string &file_name, std::atomic< bool > &file_write_done, std::ostream &o_strm)
static void explode(char delim, const std::string &str, std::list< std::string > &values)
static void url_explode(const std::string &url_str, BESUtil::url &url_parts)
Given a url, break the url into its different parts.
static bool endsWith(std::string const &fullString, std::string const &ending)
static void tokenize(const std::string &str, std::vector< std::string > &tokens, const std::string &delimiters="/")
static void set_mime_text(std::ostream &strm)
Generate an HTTP 1.0 response header for a text document.
static std::string id2xml(std::string in, const std::string ¬_allowed="><&'\"")
static void conditional_timeout_cancel()
Checks if the timeout alarm should be canceled based on the value of the BES key BES....
static void check_path(const std::string &path, const std::string &root, bool follow_sym_links)
Check if the specified path is valid.
static unsigned int replace_all(std::string &s, std::string find_this, std::string replace_with_this)
Operates on the string 's' to replaces every occurrence of the value of the string 'find_this' with t...
static void set_mime_html(std::ostream &strm)
Generate an HTTP 1.0 response header for a html document.
static std::string lowercase(const std::string &s)
static std::string pathConcat(const std::string &firstPart, const std::string &secondPart, char separator='/')
Concatenate path fragments making sure that they are separated by a single '/' character.
static std::string assemblePath(const std::string &firstPart, const std::string &secondPart, bool leadingSlash=false, bool trailingSlash=false)
Assemble path fragments making sure that they are separated by a single '/' character.
static std::string www2id(const std::string &in, const std::string &escape="%", const std::string &except="")
static std::string implode(const std::list< std::string > &values, char delim)
static void file_to_stream(const std::string &file_name, std::ostream &o_strm)
Copies the contents of the file identified by file_name to the stream o_strm.
static std::string normalize_path(const std::string &path, bool leading_separator, bool trailing_separator, std::string separator="/")
Removes duplicate separators and provides leading and trailing separators as directed.
static std::string xml2id(std::string in)
static std::string unescape(const std::string &s)
static char * fastpidconverter(char *buf, int base)
static void removeLeadingAndTrailingBlanks(std::string &key)
static std::string get_time(bool use_local_time=false)
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
static TheBESKeys * TheKeys()