30 #include <sys/types.h>
47 #include <Constructor.h>
50 using std::istringstream;
56 #include "BESForbiddenError.h"
57 #include "BESNotFoundError.h"
58 #include "BESInternalError.h"
59 #include "BESSyntaxUserError.h"
61 #include "w10n_utils.h"
62 #include "W10NNames.h"
66 void eval_resource_path(
const string &w10nResourceId,
const string &catalogRoot,
const bool follow_sym_links,
67 string &validPath,
bool &isFile,
bool &isDir,
string &remainder)
70 BESDEBUG(W10N_DEBUG_KEY,
"eval_resource_path() - CatalogRoot: "<< catalogRoot << endl);
71 BESDEBUG(W10N_DEBUG_KEY,
"eval_resource_path() - w10n resourceID: "<< w10nResourceId << endl);
76 int (*ye_old_stat_function)(
const char *pathname,
struct stat *buf);
77 if (follow_sym_links) {
78 BESDEBUG(W10N_DEBUG_KEY,
"eval_resource_path() - Using 'stat' function (follow_sym_links = true)" << endl);
79 ye_old_stat_function = &stat;
82 BESDEBUG(W10N_DEBUG_KEY,
"eval_resource_path() - Using 'lstat' function (follow_sym_links = false)" << endl);
83 ye_old_stat_function = &lstat;
88 if (w10nResourceId ==
"") {
89 BESDEBUG(W10N_DEBUG_KEY,
"eval_resource_path() - w10n resourceID is empty" << endl);
98 string::size_type dotdot = w10nResourceId.find(
"..");
99 if (dotdot != string::npos) {
100 BESDEBUG(W10N_DEBUG_KEY,
101 "eval_resource_path() - ERROR: w10n resourceID '" << w10nResourceId <<
"' contains the substring '..' This is Forbidden." << endl);
102 string s = (string)
"Invalid node name '" + w10nResourceId +
"' ACCESS IS FORBIDDEN";
112 string rem = w10nResourceId;
116 if (rem[0] ==
'/') rem = rem.substr(1, rem.length() - 1);
119 if (rem[rem.length() - 1] ==
'/') rem = rem.substr(0, rem.length() - 1);
122 string fullpath = catalogRoot;
124 if (fullpath[fullpath.length() - 1] ==
'/') {
125 fullpath = fullpath.substr(0, fullpath.length() - 1);
136 size_t slash = rem.find(
'/');
137 if (slash == string::npos) {
138 BESDEBUG(W10N_DEBUG_KEY,
"eval_resource_path() - Checking final path component: " << rem << endl);
139 fullpath = fullpath +
"/" + rem;
140 checking = validPath +
"/" + rem;
145 fullpath = fullpath +
"/" + rem.substr(0, slash);
146 checking = validPath +
"/" + rem.substr(0, slash);
147 rem = rem.substr(slash + 1, rem.length() - slash);
150 BESDEBUG(W10N_DEBUG_KEY,
"eval_resource_path() - fullpath: "<< fullpath << endl);
151 BESDEBUG(W10N_DEBUG_KEY,
"eval_resource_path() - checking: "<< checking << endl);
154 int statret = ye_old_stat_function(fullpath.c_str(), &sb);
160 char *s_err = strerror(errsv);
161 string error =
"Unable to access node " + checking +
": ";
163 error = error + s_err;
166 error = error +
"unknown access error";
168 BESDEBUG(W10N_DEBUG_KEY,
"eval_resource_path() - error: "<< error <<
" errno: " << errno << endl);
172 if (errsv == ENOENT || errsv == ENOTDIR) {
173 BESDEBUG(W10N_DEBUG_KEY,
"eval_resource_path() - validPath: "<< validPath << endl);
174 BESDEBUG(W10N_DEBUG_KEY,
"eval_resource_path() - remainder: "<< remainder << endl);
182 validPath = checking;
185 if (S_ISREG(sb.st_mode)) {
186 BESDEBUG(W10N_DEBUG_KEY,
"eval_resource_path() - '"<< checking <<
"' Is regular file." << endl);
190 else if (S_ISDIR(sb.st_mode)) {
191 BESDEBUG(W10N_DEBUG_KEY,
"eval_resource_path() - '"<< checking <<
"' Is directory." << endl);
195 else if (S_ISLNK(sb.st_mode)) {
196 BESDEBUG(W10N_DEBUG_KEY,
"eval_resource_path() - '"<< checking <<
"' Is symbolic Link." << endl);
197 string error =
"Service not configured to traverse symbolic links as embodied by the node '" + checking
198 +
"' ACCESS IS FORBIDDEN";
205 std::string escape_for_json(
const std::string &input)
207 std::stringstream ss;
208 for (
size_t i = 0; i < input.length(); ++i) {
209 if (
unsigned(input[i]) <
'\x20' || input[i] ==
'\\' || input[i] ==
'"') {
210 ss <<
"\\u" << std::setfill(
'0') << std::setw(4) << std::hex << unsigned(input[i]);
219 long computeConstrainedShape(libdap::Array *a, std::vector<unsigned int> *shape)
221 BESDEBUG(W10N_DEBUG_KEY,
"w10n::computeConstrainedShape() - BEGIN. Array name: "<< a->name() << endl);
223 libdap::Array::Dim_iter dIt;
228 unsigned int dimSize = 1;
232 BESDEBUG(W10N_DEBUG_KEY,
233 "w10n::computeConstrainedShape() - Array has " << a->dimensions(
true) <<
" dimensions."<< endl);
237 for (dIt = a->dim_begin(); dIt != a->dim_end(); dIt++) {
238 BESDEBUG(W10N_DEBUG_KEY,
239 "w10n::computeConstrainedShape() - Processing dimension '" << a->dimension_name(dIt)<<
"'. (dim# "<< dimNum <<
")"<< endl);
240 start = a->dimension_start(dIt,
true);
241 stride = a->dimension_stride(dIt,
true);
242 stop = a->dimension_stop(dIt,
true);
243 BESDEBUG(W10N_DEBUG_KEY,
244 "w10n::computeConstrainedShape() - start: " << start <<
" stride: " << stride <<
" stop: "<<stop<< endl);
246 dimSize = 1 + ((stop - start) / stride);
247 BESDEBUG(W10N_DEBUG_KEY,
"w10n::computeConstrainedShape() - dimSize: " << dimSize << endl);
249 (*shape)[dimNum++] = dimSize;
250 totalSize *= dimSize;
253 BESDEBUG(W10N_DEBUG_KEY,
"w10n::computeConstrainedShape() - totalSize: " << totalSize << endl);
254 BESDEBUG(W10N_DEBUG_KEY,
"w10n::computeConstrainedShape() - END." << endl);
259 void checkConstrainedDDSForW10nDataCompatibility(libdap::DDS *dds)
263 for (libdap::DDS::Vars_iter i = dds->var_begin(); i != dds->var_end(); i++) {
264 libdap::BaseType *bt = (*i);
266 if (bt->is_constructor_type()) {
267 checkConstructorForW10nDataCompatibility((libdap::Constructor *) bt);
269 else if (bt->is_vector_type()) {
270 if (bt->var()->is_constructor_type()) {
271 string msg =
"Arrays of ";
272 msg += bt->type_name() +
" are not supported by the w10n service.";
273 BESDEBUG(W10N_DEBUG_KEY,
274 "w10n::checkConstrainedDDSForW10nDataCompatibility() - ERROR! " << msg << endl);
282 if (markedCount > 1) {
283 string msg =
"More than one variable in the dataset is projected and that's a no-no for w10n data responses.";
284 BESDEBUG(W10N_DEBUG_KEY,
"w10n::checkConstrainedDDSForW10nDataCompatibility() - ERROR! " << msg << endl);
289 void checkConstructorForW10nDataCompatibility(libdap::Constructor *constructor)
292 for (libdap::Constructor::Vars_iter i = constructor->var_begin(); i != constructor->var_end(); i++) {
293 libdap::BaseType *bt = (*i);
296 if (bt->is_constructor_type()) {
297 checkConstructorForW10nDataCompatibility((libdap::Constructor *) bt);
299 else if (bt->is_vector_type()) {
300 if (bt->var()->is_constructor_type()) {
301 string msg =
"Arrays of ";
302 msg += bt->type_name() +
" are not supported by the w10n service.";
303 BESDEBUG(W10N_DEBUG_KEY,
304 "w10n::checkConstructorForW10nDataCompatibility() - ERROR! " << msg << endl);
313 if (markedCount > 1) {
315 if (markedCount == constructor->element_count())
316 msg =
"The w10n protocol does not support data responses from nodes. The variable " + constructor->name()
317 +
" is a node variable.";
319 msg =
"More than one child variable of the node variable " + constructor->name()
320 +
" is projected and that's a no-no for w10n data responses.";
321 BESDEBUG(W10N_DEBUG_KEY,
"w10n::checkConstructorForW10nDataCompatibility() - ERROR! " << msg << endl);
326 bool allVariablesMarkedToSend(libdap::DDS *dds)
328 bool allMarked =
true;
330 for (libdap::DDS::Vars_iter vi = dds->var_begin(), ve = dds->var_end(); vi != ve; vi++) {
331 libdap::BaseType *v = *vi;
333 if (v->is_constructor_type()) {
334 allMarked = allMarked && allVariablesMarkedToSend((libdap::Constructor *) v);
336 else if (v->is_vector_type() && v->var()->is_constructor_type()) {
337 allMarked = allMarked && allVariablesMarkedToSend((libdap::Constructor *) v->var());
340 allMarked = allMarked &&
true;
344 allMarked = allMarked &&
false;
351 bool allVariablesMarkedToSend(libdap::Constructor *ctor)
353 bool allMarked =
true;
355 libdap::Constructor::Vars_iter vi = ctor->var_begin();
356 libdap::Constructor::Vars_iter ve = ctor->var_end();
357 for (; vi != ve; vi++) {
358 libdap::BaseType *v = *vi;
360 if (v->is_constructor_type()) {
361 allMarked = allMarked && allVariablesMarkedToSend((libdap::Constructor *) v);
363 else if (v->is_vector_type() && v->var()->is_constructor_type()) {
364 allMarked = allMarked && allVariablesMarkedToSend((libdap::Constructor *) v->var());
367 allMarked = allMarked &&
true;
371 allMarked = allMarked &&
false;