35 #include <sys/types.h> 51 using std::istringstream;
55 #include "TheBESKeys.h" 58 #include "BESForbiddenError.h" 59 #include "BESNotFoundError.h" 60 #include "BESInternalError.h" 64 #define debug_key "BesUtil" 66 const string BES_KEY_TIMEOUT_CANCEL =
"BES.CancelTimeoutOnSend";
74 strm <<
"HTTP/1.0 200 OK" << CRLF;
75 strm <<
"XBES-Server: " << PACKAGE_STRING << CRLF;
77 const time_t t = time(0);
78 strm <<
"Date: " << rfc822_date(t).c_str() << CRLF;
79 strm <<
"Last-Modified: " << rfc822_date(t).c_str() << CRLF;
81 strm <<
"Content-Type: text/plain" << CRLF;
83 strm <<
"Content-Description: unknown" << CRLF;
93 strm <<
"HTTP/1.0 200 OK" << CRLF;
94 strm <<
"XBES-Server: " << PACKAGE_STRING << CRLF;
96 const time_t t = time(0);
97 strm <<
"Date: " << rfc822_date(t).c_str() << CRLF;
98 strm <<
"Last-Modified: " << rfc822_date(t).c_str() << CRLF;
100 strm <<
"Content-type: text/html" << CRLF;
102 strm <<
"Content-Description: unknown" << CRLF;
138 static const char *days[] = {
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat" };
139 static const char *months[] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec" };
150 string BESUtil::rfc822_date(
const time_t t)
152 struct tm *stm = gmtime(&t);
155 snprintf(d, 255,
"%s, %02d %s %4d %02d:%02d:%02d GMT", days[stm->tm_wday], stm->tm_mday, months[stm->tm_mon],
156 1900 + stm->tm_year, stm->tm_hour, stm->tm_min, stm->tm_sec);
161 string BESUtil::unhexstring(
string s)
165 ss >> std::hex >> val;
167 tmp_str[0] = static_cast<char>(val);
169 return string(tmp_str);
176 string::size_type i = 0;
178 while ((i = res.find_first_of(escape, i)) != string::npos) {
179 if (except.find(res.substr(i, 3)) != string::npos) {
183 res.replace(i, 3, unhexstring(res.substr(i + 1, 2)));
191 string return_string = s;
192 for (
int j = 0; j < static_cast<int>(return_string.length()); j++) {
193 return_string[j] = (char) tolower(return_string[j]);
196 return return_string;
202 string::size_type index = 0;
206 string::size_type bs = s.find(
'\\', index);
207 if (bs == string::npos) {
208 new_str += s.substr(index, s.length() - index);
212 new_str += s.substr(index, bs - index);
213 new_str += s[bs + 1];
246 if (path ==
"")
return;
251 int (*ye_old_stat_function)(
const char *pathname,
struct stat *buf);
252 if (follow_sym_links) {
253 BESDEBUG(debug_key,
"eval_w10n_resourceId() - Using 'stat' function (follow_sym_links = true)" << endl);
254 ye_old_stat_function = &stat;
257 BESDEBUG(debug_key,
"eval_w10n_resourceId() - Using 'lstat' function (follow_sym_links = false)" << endl);
258 ye_old_stat_function = &lstat;
263 string::size_type dotdot = path.find(
"..");
264 if (dotdot != string::npos) {
265 string s = (string)
"You are not allowed to access the node " + path;
276 if (rem[0] ==
'/') rem = rem.substr(1, rem.length() - 1);
277 if (rem[rem.length() - 1] ==
'/') rem = rem.substr(0, rem.length() - 1);
280 string fullpath = root;
281 if (fullpath[fullpath.length() - 1] ==
'/') {
282 fullpath = fullpath.substr(0, fullpath.length() - 1);
288 size_t slash = rem.find(
'/');
289 if (slash == string::npos) {
290 fullpath = fullpath +
"/" + rem;
291 checked = checked +
"/" + rem;
295 fullpath = fullpath +
"/" + rem.substr(0, slash);
296 checked = checked +
"/" + rem.substr(0, slash);
297 rem = rem.substr(slash + 1, rem.length() - slash);
301 int statret = ye_old_stat_function(fullpath.c_str(), &buf);
306 char *s_err = strerror(errsv);
307 string error =
"Unable to access node " + checked +
": ";
309 error = error + s_err;
312 error = error +
"unknown access error";
315 BESDEBUG(debug_key,
"check_path() - error: "<< error <<
" errno: " << errno << endl);
320 if (errsv == ENOENT || errsv == ENOTDIR) {
333 if (S_ISLNK(buf.st_mode)) {
334 string error =
"You do not have permission to access " + checked;
342 size_t slash = rem.find(
'/');
343 if (slash == string::npos) {
344 fullpath = fullpath +
"/" + rem;
345 checked = checked +
"/" + rem;
349 fullpath = fullpath +
"/" + rem.substr(0, slash);
350 checked = checked +
"/" + rem.substr(0, slash);
351 rem = rem.substr(slash + 1, rem.length() - slash);
354 if (!follow_sym_links) {
356 int statret = lstat(fullpath.c_str(), &buf);
361 char *s_err = strerror(errsv);
362 string error =
"Unable to access node " + checked +
": ";
364 error = error + s_err;
367 error = error +
"unknown access error";
371 if (errsv == ENOENT) {
380 if (S_ISLNK( buf.st_mode )) {
381 string error =
"You do not have permission to access " 391 int statret = stat(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) {
432 if (base > 36 || base < 2)
437 if (val < 0) *buf++ =
'-';
438 r = ldiv(labs(val), base);
445 *buf++ =
"0123456789abcdefghijklmnopqrstuvwxyz"[(int) r.rem];
453 string::size_type first = key.find_first_not_of(
" \t\n\r");
454 string::size_type last = key.find_last_not_of(
" \t\n\r");
455 if (first == string::npos)
458 string::size_type num = last - first + 1;
459 string new_key = key.substr(first, num);
465 string BESUtil::entity(
char c)
491 string::size_type i = 0;
493 while ((i = in.find_first_of(not_allowed, i)) != string::npos) {
494 in.replace(i, 1, entity(in[i]));
508 string::size_type i = 0;
510 while ((i = in.find(
">", i)) != string::npos)
511 in.replace(i, 4,
">");
514 while ((i = in.find(
"<", i)) != string::npos)
515 in.replace(i, 4,
"<");
518 while ((i = in.find(
"&", i)) != string::npos)
519 in.replace(i, 5,
"&");
522 while ((i = in.find(
"'", i)) != string::npos)
523 in.replace(i, 6,
"'");
526 while ((i = in.find(
""", i)) != string::npos)
527 in.replace(i, 6,
"\"");
547 std::string::size_type start = 0;
548 std::string::size_type qstart = 0;
549 std::string::size_type adelim = 0;
550 std::string::size_type aquote = 0;
554 if (str[start] ==
'"') {
555 bool endquote =
false;
558 aquote = str.find(
'"', qstart);
559 if (aquote == string::npos) {
560 string currval = str.substr(start, str.length() - start);
561 string err =
"BESUtil::explode - No end quote after value " + currval;
566 if (str[aquote - 1] ==
'\\') {
567 if (str[aquote - 2] ==
'\\') {
580 if (str[qstart] != delim && qstart != str.length()) {
581 string currval = str.substr(start, qstart - start);
582 string err =
"BESUtil::explode - No delim after end quote " + currval;
585 if (qstart == str.length()) {
586 adelim = string::npos;
593 adelim = str.find(delim, start);
595 if (adelim == string::npos) {
596 aval = str.substr(start, str.length() - start);
600 aval = str.substr(start, adelim - start);
603 values.push_back(aval);
605 if (start == str.length()) {
606 values.push_back(
"");
625 list<string>::const_iterator i = values.begin();
626 list<string>::const_iterator e = values.end();
629 for (; i != e; i++) {
630 if (!first) result += delim;
631 d = (*i).find(delim);
632 if (d != string::npos && (*i)[0] !=
'"') {
633 string err = (string)
"BESUtil::implode - delimiter exists in value " + (*i);
666 string::size_type colon = url_str.find(
":");
667 if (colon == string::npos) {
668 string err =
"BESUtil::url_explode: missing colon for protocol";
672 url_parts.protocol = url_str.substr(0, colon);
674 if (url_str.substr(colon, 3) !=
"://") {
675 string err =
"BESUtil::url_explode: no :// in the URL";
680 rest = url_str.substr(colon);
682 string::size_type slash = rest.find(
"/");
683 if (slash == string::npos) slash = rest.length();
685 string::size_type at = rest.find(
"@");
686 if ((at != string::npos) && (at < slash)) {
688 string up = rest.substr(0, at);
689 colon = up.find(
":");
690 if (colon != string::npos) {
691 url_parts.uname = up.substr(0, colon);
692 url_parts.psswd = up.substr(colon + 1);
695 url_parts.uname = up;
698 rest = rest.substr(at + 1);
700 slash = rest.find(
"/");
701 if (slash == string::npos) slash = rest.length();
702 colon = rest.find(
":");
703 if ((colon != string::npos) && (colon < slash)) {
705 url_parts.domain = rest.substr(0, colon);
707 rest = rest.substr(colon + 1);
708 slash = rest.find(
"/");
709 if (slash != string::npos) {
710 url_parts.port = rest.substr(0, slash);
711 url_parts.path = rest.substr(slash + 1);
714 url_parts.port = rest;
719 slash = rest.find(
"/");
720 if (slash != string::npos) {
721 url_parts.domain = rest.substr(0, slash);
722 url_parts.path = rest.substr(slash + 1);
725 url_parts.domain = rest;
732 string url = url_parts.protocol +
"://";
733 if (!url_parts.uname.empty()) {
734 url += url_parts.uname;
735 if (!url_parts.psswd.empty()) url +=
":" + url_parts.psswd;
738 url += url_parts.domain;
739 if (!url_parts.port.empty()) url +=
":" + url_parts.port;
740 if (!url_parts.path.empty()) url +=
"/" + url_parts.path;
760 assert(!firstPart.empty());
763 string first = firstPart;
764 string second = secondPart;
767 if (ensureLeadingSlash && first[0] !=
'/')
771 if (second[0] ==
'/')
772 second = second.substr(1);
775 if (first.back() ==
'/')
776 return first.append(second);
778 return first.append(
"/").append(second);
782 BESDEBUG(
"util",
"BESUtil::assemblePath() - firstPart: "<< firstPart << endl);
783 BESDEBUG(
"util",
"BESUtil::assemblePath() - secondPart: "<< secondPart << endl);
785 assert(!firstPart.empty());
787 string first = firstPart;
788 string second = secondPart;
790 if (ensureLeadingSlash) {
791 if (first[0] !=
'/') first =
"/" + first;
796 while (!first.empty() && *first.rbegin() ==
'/') {
798 first = first.substr(0, first.length() - 1);
802 while (!second.empty() && second[0] ==
'/') {
807 string newPath = first.append(
"/").append(second);
809 BESDEBUG(
"util",
"BESUtil::assemblePath() - newPath: "<< newPath << endl);
815 BESDEBUG(
"util",
"BESUtil::assemblePath() - firstPart: "<< firstPart << endl);
816 BESDEBUG(
"util",
"BESUtil::assemblePath() - secondPart: "<< secondPart << endl);
818 string first = firstPart;
819 string second = secondPart;
821 if (ensureLeadingSlash) {
822 if (*first.begin() !=
'/') first =
"/" + first;
826 while (*first.rbegin() ==
'/' && first.length() > 0) {
827 first = first.substr(0, first.length() - 1);
831 if (*first.rbegin() !=
'/') {
836 while (*second.begin() ==
'/' && second.length() > 0) {
837 second = second.substr(1);
840 string newPath = first + second;
842 BESDEBUG(
"util",
"BESUtil::assemblePath() - newPath: "<< newPath << endl);
854 if (fullString.length() >= ending.length()) {
855 return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending));
880 bool cancel_timeout_on_send =
false;
883 const string dosettrue =
"true";
884 const string dosetyes =
"yes";
887 if(
true == found ) {
889 if( dosettrue == doset || dosetyes == doset )
890 cancel_timeout_on_send =
true;
892 BESDEBUG(
"util",__func__ <<
"() - cancel_timeout_on_send: " <<(cancel_timeout_on_send?
"true":
"false") << endl);
893 if (cancel_timeout_on_send)
error thrown if the resource requested cannot be found
static string id2xml(string in, const string ¬_allowed="><&'\"")
exception thrown if inernal error encountered
static string lowercase(const string &s)
static void conditional_timeout_cancel()
void get_value(const string &s, string &val, bool &found)
Retrieve the value of a given key, if set.
static string www2id(const string &in, const string &escape="%", const string &except="")
static void removeLeadingAndTrailingBlanks(string &key)
static string assemblePath(const string &firstPart, const string &secondPart, bool addLeadingSlash=false)
Assemble path fragments making sure that they are separated by a single '/' character.
static string implode(const list< string > &values, char delim)
static TheBESKeys * TheKeys()
static string xml2id(string in)
static void set_mime_html(ostream &strm)
Generate an HTTP 1.0 response header for a html document.
static void explode(char delim, const string &str, list< string > &values)
static void set_mime_text(ostream &strm)
Generate an HTTP 1.0 response header for a text document.
static void url_explode(const 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)
error thrown if the BES is not allowed to access the resource requested
static char * fastpidconverter(char *buf, int base)
static string unescape(const string &s)
static void check_path(const string &path, const string &root, bool follow_sym_links)