mirror of https://gitee.com/bigwinds/arangodb
Bug fix/move a few actions from js to cpp (#8549)
This commit is contained in:
parent
deb770caba
commit
207c978d1e
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "actions.h"
|
||||
|
||||
#include "Basics/Exceptions.h"
|
||||
#include "Basics/ReadLocker.h"
|
||||
#include "Basics/ReadWriteLock.h"
|
||||
#include "Basics/StringUtils.h"
|
||||
|
@ -40,6 +41,14 @@ static std::unordered_map<std::string, std::shared_ptr<TRI_action_t>> PrefixActi
|
|||
|
||||
/// @brief actions lock
|
||||
static ReadWriteLock ActionsLock;
|
||||
|
||||
/// @brief actions of this type are executed directly. nothing to do here
|
||||
TRI_action_result_t TRI_fake_action_t::execute(TRI_vocbase_t*,
|
||||
arangodb::GeneralRequest*,
|
||||
arangodb::GeneralResponse*,
|
||||
arangodb::Mutex*, void**) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "TRI_fake_action_t::execute must never be called");
|
||||
}
|
||||
|
||||
/// @brief defines an action
|
||||
std::shared_ptr<TRI_action_t> TRI_DefineActionVocBase(std::string const& name,
|
||||
|
@ -51,8 +60,7 @@ std::shared_ptr<TRI_action_t> TRI_DefineActionVocBase(std::string const& name,
|
|||
url = url.substr(1);
|
||||
}
|
||||
|
||||
action->_url = url;
|
||||
action->_urlParts = StringUtils::split(url, "/").size();
|
||||
action->setUrl(url, StringUtils::split(url, "/").size());
|
||||
|
||||
std::unordered_map<std::string, std::shared_ptr<TRI_action_t>>* which;
|
||||
|
||||
|
|
|
@ -58,6 +58,11 @@ class TRI_action_t {
|
|||
|
||||
virtual bool cancel(arangodb::Mutex* dataLock, void** data) = 0;
|
||||
|
||||
void setUrl(std::string const& url, size_t urlParts) {
|
||||
_url = url;
|
||||
_urlParts = urlParts;
|
||||
}
|
||||
|
||||
std::string _url;
|
||||
|
||||
size_t _urlParts;
|
||||
|
@ -66,6 +71,28 @@ class TRI_action_t {
|
|||
bool _allowUseDatabase;
|
||||
};
|
||||
|
||||
/// @brief fake action class used only inside /_admin/execute RestHandler
|
||||
class TRI_fake_action_t final : public TRI_action_t {
|
||||
public:
|
||||
TRI_fake_action_t(std::string const& url, size_t urlParts)
|
||||
: TRI_action_t() {
|
||||
setUrl(url, urlParts);
|
||||
}
|
||||
|
||||
void visit(void*) override {}
|
||||
|
||||
/// @brief actions of this type are executed directly. nothing to do here
|
||||
TRI_action_result_t execute(TRI_vocbase_t*, arangodb::GeneralRequest*,
|
||||
arangodb::GeneralResponse*,
|
||||
arangodb::Mutex*, void**) override;
|
||||
|
||||
/// @brief actions of this type are not registered anywhere, and thus
|
||||
/// cannot be canceled
|
||||
bool cancel(arangodb::Mutex*, void**) override {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief defines an action
|
||||
std::shared_ptr<TRI_action_t> TRI_DefineActionVocBase(std::string const& name,
|
||||
std::shared_ptr<TRI_action_t> action);
|
||||
|
|
|
@ -442,13 +442,16 @@ SET(ARANGOD_SOURCES
|
|||
Replication/common-defines.cpp
|
||||
Replication/utilities.cpp
|
||||
RestHandler/RestAdminDatabaseHandler.cpp
|
||||
RestHandler/RestAdminExecuteHandler.cpp
|
||||
RestHandler/RestAdminLogHandler.cpp
|
||||
RestHandler/RestAdminRoutingHandler.cpp
|
||||
RestHandler/RestAdminServerHandler.cpp
|
||||
RestHandler/RestAdminStatisticsHandler.cpp
|
||||
RestHandler/RestAqlFunctionsHandler.cpp
|
||||
RestHandler/RestAqlReloadHandler.cpp
|
||||
RestHandler/RestAqlUserFunctionsHandler.cpp
|
||||
RestHandler/RestAuthHandler.cpp
|
||||
RestHandler/RestAuthReloadHandler.cpp
|
||||
RestHandler/RestBaseHandler.cpp
|
||||
RestHandler/RestBatchHandler.cpp
|
||||
RestHandler/RestCollectionHandler.cpp
|
||||
|
@ -476,6 +479,7 @@ SET(ARANGOD_SOURCES
|
|||
RestHandler/RestSimpleQueryHandler.cpp
|
||||
RestHandler/RestStatusHandler.cpp
|
||||
RestHandler/RestTasksHandler.cpp
|
||||
RestHandler/RestTimeHandler.cpp
|
||||
RestHandler/RestTransactionHandler.cpp
|
||||
RestHandler/RestTtlHandler.cpp
|
||||
RestHandler/RestUploadHandler.cpp
|
||||
|
|
|
@ -45,13 +45,16 @@
|
|||
#include "ProgramOptions/ProgramOptions.h"
|
||||
#include "ProgramOptions/Section.h"
|
||||
#include "RestHandler/RestAdminDatabaseHandler.h"
|
||||
#include "RestHandler/RestAdminExecuteHandler.h"
|
||||
#include "RestHandler/RestAdminLogHandler.h"
|
||||
#include "RestHandler/RestAdminRoutingHandler.h"
|
||||
#include "RestHandler/RestAdminServerHandler.h"
|
||||
#include "RestHandler/RestAdminStatisticsHandler.h"
|
||||
#include "RestHandler/RestAqlFunctionsHandler.h"
|
||||
#include "RestHandler/RestAqlReloadHandler.h"
|
||||
#include "RestHandler/RestAqlUserFunctionsHandler.h"
|
||||
#include "RestHandler/RestAuthHandler.h"
|
||||
#include "RestHandler/RestAuthReloadHandler.h"
|
||||
#include "RestHandler/RestBatchHandler.h"
|
||||
#include "RestHandler/RestCollectionHandler.h"
|
||||
#include "RestHandler/RestControlPregelHandler.h"
|
||||
|
@ -79,6 +82,7 @@
|
|||
#include "RestHandler/RestStatusHandler.h"
|
||||
#include "RestHandler/RestTasksHandler.h"
|
||||
#include "RestHandler/RestTestHandler.h"
|
||||
#include "RestHandler/RestTimeHandler.h"
|
||||
#include "RestHandler/RestTransactionHandler.h"
|
||||
#include "RestHandler/RestTtlHandler.h"
|
||||
#include "RestHandler/RestUploadHandler.h"
|
||||
|
@ -95,6 +99,7 @@
|
|||
#include "Ssl/SslServerFeature.h"
|
||||
#include "StorageEngine/EngineSelectorFeature.h"
|
||||
#include "StorageEngine/StorageEngine.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
|
||||
using namespace arangodb::rest;
|
||||
using namespace arangodb::options;
|
||||
|
@ -448,7 +453,21 @@ void GeneralServerFeature::defineHandlers() {
|
|||
// And now some handlers which are registered in both /_api and /_admin
|
||||
_handlerFactory->addHandler("/_admin/actions",
|
||||
RestHandlerCreator<MaintenanceRestHandler>::createNoData);
|
||||
|
||||
_handlerFactory->addHandler("/_admin/aql/reload",
|
||||
RestHandlerCreator<RestAqlReloadHandler>::createNoData);
|
||||
|
||||
_handlerFactory->addHandler("/_admin/auth/reload",
|
||||
RestHandlerCreator<RestAuthReloadHandler>::createNoData);
|
||||
|
||||
if (V8DealerFeature::DEALER && V8DealerFeature::DEALER->allowAdminExecute()) {
|
||||
_handlerFactory->addHandler("/_admin/execute",
|
||||
RestHandlerCreator<RestAdminExecuteHandler>::createNoData);
|
||||
}
|
||||
|
||||
_handlerFactory->addHandler("/_admin/time",
|
||||
RestHandlerCreator<RestTimeHandler>::createNoData);
|
||||
|
||||
_handlerFactory->addPrefixHandler("/_api/job",
|
||||
RestHandlerCreator<arangodb::RestJobHandler>::createData<AsyncJobManager*>,
|
||||
_jobManager.get());
|
||||
|
|
|
@ -49,7 +49,7 @@ enum class RequestLane {
|
|||
// which are not CLIENT_AQL or CLIENT_V8.
|
||||
CLIENT_SLOW,
|
||||
|
||||
// Used for all requests send by the web ui
|
||||
// Used for all requests sent by the web ui
|
||||
CLIENT_UI,
|
||||
|
||||
// For requests between agents. These are basically the
|
||||
|
|
|
@ -0,0 +1,214 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RestAdminExecuteHandler.h"
|
||||
|
||||
#include "Actions/ActionFeature.h"
|
||||
#include "Actions/actions.h"
|
||||
#include "Basics/Exceptions.h"
|
||||
#include "Basics/StaticStrings.h"
|
||||
#include "Basics/StringUtils.h"
|
||||
#include "Logger/Logger.h"
|
||||
#include "V8/v8-globals.h"
|
||||
#include "V8/v8-vpack.h"
|
||||
#include "V8Server/v8-actions.h"
|
||||
#include "V8Server/V8Context.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/Value.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::rest;
|
||||
|
||||
RestAdminExecuteHandler::RestAdminExecuteHandler(GeneralRequest* request, GeneralResponse* response)
|
||||
: RestVocbaseBaseHandler(request, response) {}
|
||||
|
||||
RestStatus RestAdminExecuteHandler::execute() {
|
||||
if (!V8DealerFeature::DEALER) {
|
||||
generateError(rest::ResponseCode::BAD, TRI_ERROR_INTERNAL,
|
||||
"JavaScript operations are not available");
|
||||
return RestStatus::DONE;
|
||||
}
|
||||
|
||||
TRI_ASSERT(V8DealerFeature::DEALER->allowAdminExecute());
|
||||
|
||||
arangodb::velocypack::StringRef bodyStr = _request->rawPayload();
|
||||
char const* body = bodyStr.data();
|
||||
size_t bodySize = bodyStr.size();
|
||||
|
||||
if (bodySize == 0) {
|
||||
// nothing to execute. return an empty response
|
||||
VPackBuilder result;
|
||||
result.openObject(true);
|
||||
result.add(StaticStrings::Error, VPackValue(false));
|
||||
result.add(StaticStrings::Code, VPackValue(static_cast<int>(rest::ResponseCode::OK)));
|
||||
result.close();
|
||||
|
||||
generateResult(rest::ResponseCode::OK, result.slice());
|
||||
return RestStatus::DONE;
|
||||
}
|
||||
|
||||
try {
|
||||
LOG_TOPIC("c838e", WARN, Logger::FIXME) << "about to execute: '" << Logger::CHARS(body, bodySize) << "'";
|
||||
|
||||
ssize_t forceContext = -1;
|
||||
bool found;
|
||||
std::string const& c = _request->header("x-arango-v8-context", found);
|
||||
|
||||
if (found && !c.empty()) {
|
||||
forceContext = basics::StringUtils::int32(c);
|
||||
}
|
||||
|
||||
// get a V8 context
|
||||
bool const allowUseDatabase = ActionFeature::ACTION->allowUseDatabase();
|
||||
V8Context* context = V8DealerFeature::DEALER->enterContext(&_vocbase, allowUseDatabase, forceContext);
|
||||
|
||||
// note: the context might be nullptr in case of shut-down
|
||||
if (context == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_RESOURCE_LIMIT,
|
||||
"unable to acquire V8 context in time");
|
||||
}
|
||||
|
||||
TRI_DEFER(V8DealerFeature::DEALER->exitContext(context));
|
||||
|
||||
{
|
||||
v8::Isolate* isolate = context->_isolate;
|
||||
v8::HandleScope scope(isolate);
|
||||
|
||||
v8::Handle<v8::Object> current = isolate->GetCurrentContext()->Global();
|
||||
v8::TryCatch tryCatch(isolate);
|
||||
|
||||
// get built-in Function constructor (see ECMA-262 5th edition 15.3.2)
|
||||
v8::Local<v8::Function> ctor = v8::Local<v8::Function>::Cast(
|
||||
current->Get(TRI_V8_ASCII_STRING(isolate, "Function")));
|
||||
v8::Handle<v8::Value> args[1] = {TRI_V8_PAIR_STRING(isolate, body, bodySize)};
|
||||
v8::Local<v8::Object> function = ctor->NewInstance(TRI_IGETC, 1, args).FromMaybe(v8::Local<v8::Object>());
|
||||
v8::Handle<v8::Function> action = v8::Local<v8::Function>::Cast(function);
|
||||
|
||||
v8::Handle<v8::Value> rv;
|
||||
|
||||
if (!action.IsEmpty()) {
|
||||
action->SetName(TRI_V8_ASCII_STRING(isolate, "source"));
|
||||
|
||||
TRI_GET_GLOBALS();
|
||||
|
||||
TRI_fake_action_t adminExecuteAction("_admin/execute", 2);
|
||||
|
||||
v8g->_currentRequest = TRI_RequestCppToV8(isolate, v8g, _request.get(), &adminExecuteAction);
|
||||
v8g->_currentResponse = v8::Object::New(isolate);
|
||||
|
||||
auto guard = scopeGuard([&v8g, &isolate]() {
|
||||
v8g->_currentRequest = v8::Undefined(isolate);
|
||||
v8g->_currentResponse = v8::Undefined(isolate);
|
||||
});
|
||||
|
||||
v8::Handle<v8::Value> args[] = {v8::Null(isolate)};
|
||||
rv = action->Call(current, 0, args);
|
||||
}
|
||||
|
||||
if (tryCatch.HasCaught()) {
|
||||
// got an error
|
||||
std::string errorMessage;
|
||||
|
||||
auto stacktraceV8 = tryCatch.StackTrace(TRI_IGETC).FromMaybe(v8::Local<v8::Value>());
|
||||
v8::String::Utf8Value tryCatchStackTrace(isolate, stacktraceV8);
|
||||
if (*tryCatchStackTrace != nullptr) {
|
||||
errorMessage = *tryCatchStackTrace;
|
||||
} else if (!tryCatch.Message().IsEmpty()) {
|
||||
v8::String::Utf8Value tryCatchMessage(isolate, tryCatch.Message()->Get());
|
||||
if (*tryCatchMessage != nullptr) {
|
||||
errorMessage = *tryCatchMessage;
|
||||
}
|
||||
}
|
||||
|
||||
_response->setResponseCode(rest::ResponseCode::SERVER_ERROR);
|
||||
switch (_response->transportType()) {
|
||||
case Endpoint::TransportType::HTTP: {
|
||||
HttpResponse* httpResponse = dynamic_cast<HttpResponse*>(_response.get());
|
||||
if (httpResponse == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unable to cast response object");
|
||||
}
|
||||
_response->setContentType(rest::ContentType::TEXT);
|
||||
httpResponse->body().appendText(errorMessage.data(), errorMessage.size());
|
||||
break;
|
||||
}
|
||||
case Endpoint::TransportType::VST: {
|
||||
VPackBuffer<uint8_t> buffer;
|
||||
VPackBuilder builder(buffer);
|
||||
builder.add(VPackValuePair(reinterpret_cast<uint8_t const*>(errorMessage.data()), errorMessage.size()));
|
||||
_response->setContentType(rest::ContentType::VPACK);
|
||||
_response->setPayload(std::move(buffer), true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// all good!
|
||||
bool returnAsJSON = _request->parsedValue("returnAsJSON", false);
|
||||
if (returnAsJSON) {
|
||||
// if the result is one of the following type, we return it as is
|
||||
returnAsJSON &= (rv->IsString() || rv->IsStringObject() ||
|
||||
rv->IsNumber() || rv->IsNumberObject() ||
|
||||
rv->IsBoolean());
|
||||
}
|
||||
|
||||
VPackBuilder result;
|
||||
bool handled = false;
|
||||
int res = TRI_ERROR_FAILED;
|
||||
|
||||
if (returnAsJSON) {
|
||||
result.openObject(true);
|
||||
result.add(StaticStrings::Error, VPackValue(false));
|
||||
result.add(StaticStrings::Code, VPackValue(static_cast<int>(rest::ResponseCode::OK)));
|
||||
if (rv->IsObject()) {
|
||||
res = TRI_V8ToVPack(isolate, result, rv, false);
|
||||
handled = true;
|
||||
}
|
||||
result.close();
|
||||
}
|
||||
|
||||
if (!handled) {
|
||||
result.clear();
|
||||
|
||||
VPackBuilder temp;
|
||||
res = TRI_V8ToVPack(isolate, temp, rv, false);
|
||||
result.add(temp.slice());
|
||||
}
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
}
|
||||
|
||||
generateResult(rest::ResponseCode::OK, result.slice());
|
||||
}
|
||||
}
|
||||
|
||||
} catch (basics::Exception const& ex) {
|
||||
generateError(GeneralResponse::responseCode(ex.code()), ex.code(), ex.what());
|
||||
} catch (std::exception const& ex) {
|
||||
generateError(rest::ResponseCode::SERVER_ERROR, TRI_ERROR_INTERNAL, ex.what());
|
||||
}
|
||||
|
||||
return RestStatus::DONE;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGOD_REST_HANDLER_REST_ADMIN_EXECUTE_HANDLER_H
|
||||
#define ARANGOD_REST_HANDLER_REST_ADMIN_EXECUTE_HANDLER_H 1
|
||||
|
||||
#include "RestHandler/RestVocbaseBaseHandler.h"
|
||||
|
||||
namespace arangodb {
|
||||
class RestAdminExecuteHandler : public arangodb::RestVocbaseBaseHandler {
|
||||
public:
|
||||
RestAdminExecuteHandler(GeneralRequest*, GeneralResponse*);
|
||||
|
||||
public:
|
||||
char const* name() const override final { return "RestAdminExecuteHandler"; }
|
||||
RequestLane lane() const override final { return RequestLane::CLIENT_V8; }
|
||||
RestStatus execute() override;
|
||||
};
|
||||
} // namespace arangodb
|
||||
|
||||
#endif
|
|
@ -0,0 +1,51 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RestAqlReloadHandler.h"
|
||||
|
||||
#include "ApplicationFeatures/ApplicationServer.h"
|
||||
#include "Basics/StaticStrings.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/Value.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::rest;
|
||||
|
||||
RestAqlReloadHandler::RestAqlReloadHandler(GeneralRequest* request, GeneralResponse* response)
|
||||
: RestBaseHandler(request, response) {}
|
||||
|
||||
RestStatus RestAqlReloadHandler::execute() {
|
||||
V8DealerFeature::DEALER->addGlobalContextMethod("reloadAql");
|
||||
|
||||
VPackBuilder result;
|
||||
result.openObject(true);
|
||||
result.add(StaticStrings::Error, VPackValue(false));
|
||||
result.add(StaticStrings::Code, VPackValue(static_cast<int>(rest::ResponseCode::OK)));
|
||||
result.close();
|
||||
|
||||
generateResult(rest::ResponseCode::OK, result.slice());
|
||||
return RestStatus::DONE;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGOD_REST_HANDLER_REST_AQL_RELOAD_HANDLER_H
|
||||
#define ARANGOD_REST_HANDLER_REST_AQL_RELOAD_HANDLER_H 1
|
||||
|
||||
#include "RestHandler/RestBaseHandler.h"
|
||||
|
||||
namespace arangodb {
|
||||
class RestAqlReloadHandler : public arangodb::RestBaseHandler {
|
||||
public:
|
||||
RestAqlReloadHandler(GeneralRequest*, GeneralResponse*);
|
||||
|
||||
public:
|
||||
char const* name() const override final { return "RestAqlReloadHandler"; }
|
||||
RequestLane lane() const override final { return RequestLane::CLIENT_SLOW; }
|
||||
RestStatus execute() override;
|
||||
};
|
||||
} // namespace arangodb
|
||||
|
||||
#endif
|
|
@ -0,0 +1,56 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RestAuthReloadHandler.h"
|
||||
|
||||
#include "ApplicationFeatures/ApplicationServer.h"
|
||||
#include "Auth/UserManager.h"
|
||||
#include "Basics/StaticStrings.h"
|
||||
#include "GeneralServer/AuthenticationFeature.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/Value.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::rest;
|
||||
|
||||
RestAuthReloadHandler::RestAuthReloadHandler(GeneralRequest* request, GeneralResponse* response)
|
||||
: RestBaseHandler(request, response) {}
|
||||
|
||||
RestStatus RestAuthReloadHandler::execute() {
|
||||
auth::UserManager* um = AuthenticationFeature::instance()->userManager();
|
||||
if (um != nullptr) {
|
||||
um->triggerLocalReload();
|
||||
um->triggerGlobalReload(); // noop except on coordinator
|
||||
}
|
||||
|
||||
VPackBuilder result;
|
||||
result.openObject(true);
|
||||
result.add(StaticStrings::Error, VPackValue(false));
|
||||
result.add(StaticStrings::Code, VPackValue(static_cast<int>(rest::ResponseCode::OK)));
|
||||
result.close();
|
||||
|
||||
generateResult(rest::ResponseCode::OK, result.slice());
|
||||
return RestStatus::DONE;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGOD_REST_HANDLER_REST_AUTH_RELOAD_HANDLER_H
|
||||
#define ARANGOD_REST_HANDLER_REST_AUTH_RELOAD_HANDLER_H 1
|
||||
|
||||
#include "RestHandler/RestBaseHandler.h"
|
||||
|
||||
namespace arangodb {
|
||||
class RestAuthReloadHandler : public arangodb::RestBaseHandler {
|
||||
public:
|
||||
RestAuthReloadHandler(GeneralRequest*, GeneralResponse*);
|
||||
|
||||
public:
|
||||
char const* name() const override final { return "RestAuthReloadHandler"; }
|
||||
RequestLane lane() const override final { return RequestLane::CLIENT_SLOW; }
|
||||
RestStatus execute() override;
|
||||
};
|
||||
} // namespace arangodb
|
||||
|
||||
#endif
|
|
@ -0,0 +1,48 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RestTimeHandler.h"
|
||||
|
||||
#include "Basics/StaticStrings.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/Value.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::rest;
|
||||
|
||||
RestTimeHandler::RestTimeHandler(GeneralRequest* request, GeneralResponse* response)
|
||||
: RestBaseHandler(request, response) {}
|
||||
|
||||
RestStatus RestTimeHandler::execute() {
|
||||
VPackBuilder result;
|
||||
result.openObject(true);
|
||||
result.add(StaticStrings::Error, VPackValue(false));
|
||||
result.add(StaticStrings::Code, VPackValue(static_cast<int>(rest::ResponseCode::OK)));
|
||||
result.add("time", VPackValue(TRI_microtime()));
|
||||
result.close();
|
||||
|
||||
generateResult(rest::ResponseCode::OK, result.slice());
|
||||
return RestStatus::DONE;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGOD_REST_HANDLER_REST_TIME_HANDLER_H
|
||||
#define ARANGOD_REST_HANDLER_REST_TIME_HANDLER_H 1
|
||||
|
||||
#include "RestHandler/RestBaseHandler.h"
|
||||
|
||||
namespace arangodb {
|
||||
class RestTimeHandler : public arangodb::RestBaseHandler {
|
||||
public:
|
||||
RestTimeHandler(GeneralRequest*, GeneralResponse*);
|
||||
|
||||
public:
|
||||
char const* name() const override final { return "RestTimeHandler"; }
|
||||
RequestLane lane() const override final { return RequestLane::CLIENT_FAST; }
|
||||
RestStatus execute() override;
|
||||
};
|
||||
} // namespace arangodb
|
||||
|
||||
#endif
|
|
@ -233,7 +233,7 @@ void RestTransactionHandler::executeJSTransaction() {
|
|||
auto slice = _request->payload();
|
||||
if (!slice.isObject()) {
|
||||
generateError(
|
||||
Result(TRI_ERROR_BAD_PARAMETER, "could not acquire v8 context"));
|
||||
Result(TRI_ERROR_BAD_PARAMETER, "expecting object input data"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -361,7 +361,6 @@ void V8DealerFeature::start() {
|
|||
<< ", max: " << _nrMaxContexts;
|
||||
|
||||
defineDouble("V8_CONTEXTS", static_cast<double>(_nrMaxContexts));
|
||||
defineBoolean("ALLOW_ADMIN_EXECUTE", _allowAdminExecute);
|
||||
|
||||
// setup instances
|
||||
{
|
||||
|
@ -568,22 +567,20 @@ void V8DealerFeature::unprepare() {
|
|||
}
|
||||
|
||||
bool V8DealerFeature::addGlobalContextMethod(std::string const& method) {
|
||||
auto cb = [this, &method]() -> bool {
|
||||
bool result = true;
|
||||
for (auto& context : _contexts) {
|
||||
try {
|
||||
if (!context->addGlobalContextMethod(method)) {
|
||||
result = false;
|
||||
}
|
||||
} catch (...) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
bool result = true;
|
||||
|
||||
CONDITION_LOCKER(guard, _contextCondition);
|
||||
return cb();
|
||||
|
||||
for (auto& context : _contexts) {
|
||||
try {
|
||||
if (!context->addGlobalContextMethod(method)) {
|
||||
result = false;
|
||||
}
|
||||
} catch (...) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void V8DealerFeature::collectGarbage() {
|
||||
|
|
|
@ -76,6 +76,8 @@ class V8DealerFeature final : public application_features::ApplicationFeature {
|
|||
bool _enableJS;
|
||||
|
||||
public:
|
||||
bool allowAdminExecute() const { return _allowAdminExecute; }
|
||||
|
||||
bool addGlobalContextMethod(std::string const&);
|
||||
void collectGarbage();
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ class v8_action_t final : public TRI_action_t {
|
|||
void** data) override {
|
||||
TRI_action_result_t result;
|
||||
|
||||
// allow use datase execution in rest calls
|
||||
// allow use database execution in rest calls
|
||||
bool allowUseDatabaseInRestActions = ActionFeature::ACTION->allowUseDatabase();
|
||||
|
||||
if (_allowUseDatabase) {
|
||||
|
@ -307,9 +307,10 @@ static void AddCookie(v8::Isolate* isolate, TRI_v8_global_t const* v8g,
|
|||
/// @brief convert a C++ HttpRequest to a V8 request object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Object> RequestCppToV8(v8::Isolate* isolate,
|
||||
TRI_v8_global_t const* v8g,
|
||||
GeneralRequest* request) {
|
||||
v8::Handle<v8::Object> TRI_RequestCppToV8(v8::Isolate* isolate,
|
||||
TRI_v8_global_t const* v8g,
|
||||
arangodb::GeneralRequest* request,
|
||||
TRI_action_t const* action) {
|
||||
// setup the request
|
||||
v8::Handle<v8::Object> req = v8::Object::New(isolate);
|
||||
|
||||
|
@ -505,11 +506,11 @@ static v8::Handle<v8::Object> RequestCppToV8(v8::Isolate* isolate,
|
|||
req->Set(RequestTypeKey, HeadConstant);
|
||||
break;
|
||||
}
|
||||
case rest::RequestType::GET: {
|
||||
default:
|
||||
TRI_GET_GLOBAL_STRING(GetConstant);
|
||||
req->Set(RequestTypeKey, GetConstant);
|
||||
break;
|
||||
case rest::RequestType::GET:
|
||||
default: {
|
||||
TRI_GET_GLOBAL_STRING(GetConstant);
|
||||
req->Set(RequestTypeKey, GetConstant);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -561,6 +562,37 @@ static v8::Handle<v8::Object> RequestCppToV8(v8::Isolate* isolate,
|
|||
TRI_GET_GLOBAL_STRING(CookiesKey);
|
||||
req->Set(CookiesKey, cookiesObject);
|
||||
}
|
||||
|
||||
// copy suffix, which comes from the action:
|
||||
std::vector<std::string> const& suffixes = request->decodedSuffixes();
|
||||
std::vector<std::string> const& rawSuffixes = request->suffixes();
|
||||
|
||||
uint32_t index = 0;
|
||||
char const* sep = "";
|
||||
|
||||
size_t const n = suffixes.size();
|
||||
v8::Handle<v8::Array> suffixArray =
|
||||
v8::Array::New(isolate, static_cast<int>(n - action->_urlParts));
|
||||
v8::Handle<v8::Array> rawSuffixArray =
|
||||
v8::Array::New(isolate, static_cast<int>(n - action->_urlParts));
|
||||
|
||||
for (size_t s = action->_urlParts; s < n; ++s) {
|
||||
suffixArray->Set(index, TRI_V8_STD_STRING(isolate, suffixes[s]));
|
||||
rawSuffixArray->Set(index, TRI_V8_STD_STRING(isolate, rawSuffixes[s]));
|
||||
++index;
|
||||
|
||||
path += sep + suffixes[s];
|
||||
sep = "/";
|
||||
}
|
||||
|
||||
TRI_GET_GLOBAL_STRING(SuffixKey);
|
||||
req->Set(SuffixKey, suffixArray);
|
||||
TRI_GET_GLOBAL_STRING(RawSuffixKey);
|
||||
req->Set(RawSuffixKey, rawSuffixArray);
|
||||
|
||||
// copy full path
|
||||
TRI_GET_GLOBAL_STRING(PathKey);
|
||||
req->Set(PathKey, TRI_V8_STD_STRING(isolate, path));
|
||||
|
||||
return req;
|
||||
}
|
||||
|
@ -791,7 +823,8 @@ static void ResponseV8ToCpp(v8::Isolate* isolate, TRI_v8_global_t const* v8g,
|
|||
HttpResponse* httpResponse = dynamic_cast<HttpResponse*>(response);
|
||||
httpResponse->body().appendText(content, length);
|
||||
TRI_FreeString(content);
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
|
||||
case Endpoint::TransportType::VST: {
|
||||
VPackBuffer<uint8_t> buffer;
|
||||
|
@ -800,9 +833,10 @@ static void ResponseV8ToCpp(v8::Isolate* isolate, TRI_v8_global_t const* v8g,
|
|||
TRI_FreeString(content);
|
||||
|
||||
// create vpack from file
|
||||
response->setContentType(rest::ContentType::VPACK);
|
||||
response->setContentType(rest::ContentType::TEXT);
|
||||
response->setPayload(std::move(buffer), true);
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
TRI_FreeString(content);
|
||||
|
@ -885,39 +919,7 @@ static TRI_action_result_t ExecuteActionVocbase(TRI_vocbase_t* vocbase, v8::Isol
|
|||
|
||||
TRI_GET_GLOBALS();
|
||||
|
||||
v8::Handle<v8::Object> req = RequestCppToV8(isolate, v8g, request);
|
||||
|
||||
// copy suffix, which comes from the action:
|
||||
std::string path = request->prefix();
|
||||
std::vector<std::string> const& suffixes = request->decodedSuffixes();
|
||||
std::vector<std::string> const& rawSuffixes = request->suffixes();
|
||||
|
||||
uint32_t index = 0;
|
||||
char const* sep = "";
|
||||
|
||||
size_t const n = suffixes.size();
|
||||
v8::Handle<v8::Array> suffixArray =
|
||||
v8::Array::New(isolate, static_cast<int>(n - action->_urlParts));
|
||||
v8::Handle<v8::Array> rawSuffixArray =
|
||||
v8::Array::New(isolate, static_cast<int>(n - action->_urlParts));
|
||||
|
||||
for (size_t s = action->_urlParts; s < n; ++s) {
|
||||
suffixArray->Set(index, TRI_V8_STD_STRING(isolate, suffixes[s]));
|
||||
rawSuffixArray->Set(index, TRI_V8_STD_STRING(isolate, rawSuffixes[s]));
|
||||
++index;
|
||||
|
||||
path += sep + suffixes[s];
|
||||
sep = "/";
|
||||
}
|
||||
|
||||
TRI_GET_GLOBAL_STRING(SuffixKey);
|
||||
req->Set(SuffixKey, suffixArray);
|
||||
TRI_GET_GLOBAL_STRING(RawSuffixKey);
|
||||
req->Set(RawSuffixKey, rawSuffixArray);
|
||||
|
||||
// copy full path
|
||||
TRI_GET_GLOBAL_STRING(PathKey);
|
||||
req->Set(PathKey, TRI_V8_STD_STRING(isolate, path));
|
||||
v8::Handle<v8::Object> req = TRI_RequestCppToV8(isolate, v8g, request, action);
|
||||
|
||||
// create the response object
|
||||
v8::Handle<v8::Object> res = v8::Object::New(isolate);
|
||||
|
|
|
@ -28,6 +28,18 @@
|
|||
|
||||
#include <v8.h>
|
||||
|
||||
class TRI_action_t;
|
||||
struct TRI_v8_global_t;
|
||||
|
||||
namespace arangodb {
|
||||
class GeneralRequest;
|
||||
}
|
||||
|
||||
v8::Handle<v8::Object> TRI_RequestCppToV8(v8::Isolate* isolate,
|
||||
TRI_v8_global_t const* v8g,
|
||||
arangodb::GeneralRequest* request,
|
||||
TRI_action_t const* action);
|
||||
|
||||
void TRI_InitV8Actions(v8::Isolate* isolate, v8::Handle<v8::Context> context);
|
||||
|
||||
void TRI_InitV8DebugUtils(v8::Isolate* isolate, v8::Handle<v8::Context> context);
|
||||
|
|
|
@ -246,7 +246,7 @@ Result arangodb::registerUserFunction(TRI_vocbase_t& vocbase, velocypack::Slice
|
|||
|
||||
v8::Handle<v8::Value> result;
|
||||
{
|
||||
v8::TryCatch tryCatch(isolate);;
|
||||
v8::TryCatch tryCatch(isolate);
|
||||
|
||||
result = TRI_ExecuteJavaScriptString(isolate, isolate->GetCurrentContext(),
|
||||
TRI_V8_STD_STRING(isolate, testCode),
|
||||
|
|
|
@ -412,7 +412,7 @@ void Task::work(ExecContext const* exec) {
|
|||
|
||||
// call the function within a try/catch
|
||||
try {
|
||||
v8::TryCatch tryCatch(isolate);;
|
||||
v8::TryCatch tryCatch(isolate);
|
||||
action->Call(current, 1, &fArgs);
|
||||
if (tryCatch.HasCaught()) {
|
||||
if (tryCatch.CanContinue()) {
|
||||
|
|
|
@ -42,7 +42,7 @@ Result executeTransaction(v8::Isolate* isolate, basics::ReadWriteLock& lock,
|
|||
v8::Handle<v8::Value> in = TRI_VPackToV8(isolate, slice);
|
||||
|
||||
v8::Handle<v8::Value> result;
|
||||
v8::TryCatch tryCatch(isolate);;
|
||||
v8::TryCatch tryCatch(isolate);
|
||||
|
||||
v8::Handle<v8::Object> request = v8::Object::New(isolate);
|
||||
v8::Handle<v8::Value> jsPortTypeKey =
|
||||
|
@ -276,7 +276,7 @@ Result executeTransactionJS(v8::Isolate* isolate, v8::Handle<v8::Value> const& a
|
|||
v8::Local<v8::Function> ctor = v8::Local<v8::Function>::Cast(
|
||||
current->Get(TRI_V8_ASCII_STRING(isolate, "Function")));
|
||||
|
||||
// Invoke Function constructor to create function with the given body and no
|
||||
// Invoke Function constructor to create function with the given body and the
|
||||
// arguments
|
||||
std::string body = TRI_ObjectToString(isolate,
|
||||
TRI_GetProperty(context, isolate, object, "action"));
|
||||
|
|
|
@ -1467,7 +1467,7 @@ v8::Local<v8::Value> V8ClientConnection::requestData(
|
|||
int res = TRI_V8ToVPack(isolate, builder, body, false);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG_TOPIC("46ae2", ERR, Logger::V8)
|
||||
<< "error converting request body " << TRI_errno_string(res);
|
||||
<< "error converting request body: " << TRI_errno_string(res);
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
req->addVPack(std::move(buffer));
|
||||
|
@ -1526,7 +1526,7 @@ v8::Local<v8::Value> V8ClientConnection::requestDataRaw(
|
|||
int res = TRI_V8ToVPack(isolate, builder, body, false);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG_TOPIC("10318", ERR, Logger::V8)
|
||||
<< "error converting request body " << TRI_errno_string(res);
|
||||
<< "error converting request body: " << TRI_errno_string(res);
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
req->addVPack(std::move(buffer));
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const internal = require('internal');
|
||||
const console = require('console');
|
||||
const actions = require('@arangodb/actions');
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -47,48 +46,3 @@ actions.defineHttp({
|
|||
res.body = JSON.stringify(req);
|
||||
}
|
||||
});
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief was docuBlock JSF_get_admin_time
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url: '_admin/time',
|
||||
prefix: false,
|
||||
|
||||
callback: function (req, res) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK, { time: internal.time() });
|
||||
}
|
||||
});
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief was docuBlock JSF_post_admin_execute
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (global.ALLOW_ADMIN_EXECUTE) {
|
||||
actions.defineHttp({
|
||||
url: '_admin/execute',
|
||||
prefix: false,
|
||||
|
||||
callback: function (req, res) {
|
||||
/* jshint evil: true */
|
||||
var body = req.requestBody;
|
||||
var result;
|
||||
|
||||
console.warn("about to execute: '%s'", body);
|
||||
|
||||
if (body !== '') {
|
||||
result = eval('(function() {' + body + '}());');
|
||||
}
|
||||
|
||||
if (req.parameters.hasOwnProperty('returnAsJSON') &&
|
||||
req.parameters.returnAsJSON === 'true') {
|
||||
actions.resultOk(req, res, actions.HTTP_OK, result);
|
||||
} else {
|
||||
actions.resultOk(req, res, actions.HTTP_OK, JSON.stringify(result));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
delete global.ALLOW_ADMIN_EXECUTE;
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
/* jshint strict: false */
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief global configuration
|
||||
// /
|
||||
// / @file
|
||||
// /
|
||||
// / DISCLAIMER
|
||||
// /
|
||||
// / Copyright 2014 ArangoDB GmbH, Cologne, Germany
|
||||
// /
|
||||
// / Licensed under the Apache License, Version 2.0 (the "License")
|
||||
// / you may not use this file except in compliance with the License.
|
||||
// / You may obtain a copy of the License at
|
||||
// /
|
||||
// / http://www.apache.org/licenses/LICENSE-2.0
|
||||
// /
|
||||
// / Unless required by applicable law or agreed to in writing, software
|
||||
// / distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// / WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// / See the License for the specific language governing permissions and
|
||||
// / limitations under the License.
|
||||
// /
|
||||
// / Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
// /
|
||||
// / @author Jan Steemann
|
||||
// / @author Copyright 2014, triAGENS GmbH, Cologne, Germany
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var actions = require('@arangodb/actions');
|
||||
var configuration = require('@arangodb/configuration');
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief _admin/configuration/versions
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url: '_admin/configuration/notifications/versions',
|
||||
prefix: false,
|
||||
|
||||
callback: function (req, res) {
|
||||
var json;
|
||||
|
||||
try {
|
||||
switch (req.requestType) {
|
||||
case actions.GET:
|
||||
actions.resultOk(req, res, actions.HTTP_OK, configuration.notifications.versions());
|
||||
break;
|
||||
|
||||
case actions.PUT:
|
||||
json = actions.getJsonBody(req, res, actions.HTTP_BAD);
|
||||
|
||||
if (json === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
configuration.notifications.setVersions(json);
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_OK, {});
|
||||
break;
|
||||
|
||||
default:
|
||||
actions.resultUnsupported(req, res);
|
||||
}
|
||||
} catch (err) {
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
|
@ -29,8 +29,6 @@
|
|||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var actions = require('@arangodb/actions');
|
||||
var internal = require('internal');
|
||||
var users = require('@arangodb/users');
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief main routing action
|
||||
|
@ -72,31 +70,3 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief reloads the server authentication information
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url: '_admin/auth/reload',
|
||||
prefix: false,
|
||||
|
||||
callback: function (req, res) {
|
||||
users.reload();
|
||||
actions.resultOk(req, res, actions.HTTP_OK);
|
||||
}
|
||||
});
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief reloads the AQL user functions
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
actions.defineHttp({
|
||||
url: '_admin/aql/reload',
|
||||
prefix: false,
|
||||
|
||||
callback: function (req, res) {
|
||||
internal.reloadAqlFunctions();
|
||||
actions.resultOk(req, res, actions.HTTP_OK);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -389,7 +389,10 @@ authRouter.post('/job', function (req, res) {
|
|||
`);
|
||||
|
||||
authRouter.delete('/job', function (req, res) {
|
||||
db._frontend.removeByExample({model: 'job'}, false);
|
||||
let frontend = db._collection('_frontend');
|
||||
if (frontend) {
|
||||
frontend.removeByExample({model: 'job'}, false);
|
||||
}
|
||||
res.json(true);
|
||||
})
|
||||
.summary('Delete all jobs')
|
||||
|
@ -398,7 +401,10 @@ authRouter.delete('/job', function (req, res) {
|
|||
`);
|
||||
|
||||
authRouter.delete('/job/:id', function (req, res) {
|
||||
db._frontend.removeByExample({id: req.pathParams.id}, false);
|
||||
let frontend = db._collection('_frontend');
|
||||
if (frontend) {
|
||||
frontend.removeByExample({id: req.pathParams.id}, false);
|
||||
}
|
||||
res.json(true);
|
||||
})
|
||||
.summary('Delete a job id')
|
||||
|
|
|
@ -273,24 +273,6 @@ global.DEFINE_MODULE('internal', (function () {
|
|||
delete global.SYS_EXECUTE;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief getCurrentRequest
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (global.SYS_GET_CURRENT_REQUEST) {
|
||||
exports.getCurrentRequest = global.SYS_GET_CURRENT_REQUEST;
|
||||
delete global.SYS_GET_CURRENT_REQUEST;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief getCurrentResponse
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (global.SYS_GET_CURRENT_RESPONSE) {
|
||||
exports.getCurrentResponse = global.SYS_GET_CURRENT_RESPONSE;
|
||||
delete global.SYS_GET_CURRENT_RESPONSE;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief extend
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -23,17 +23,11 @@
|
|||
// / @author Dr. Frank Celler, Lucas Dohmen
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var db = require('@arangodb').db;
|
||||
var internal = require('internal');
|
||||
var shallowCopy = require('@arangodb/util').shallowCopy;
|
||||
let db = require('@arangodb').db;
|
||||
let internal = require('internal');
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief the frontend collection
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function getFrontendCollection () {
|
||||
return db._collection('_frontend');
|
||||
}
|
||||
const cn = '_frontend';
|
||||
const key = 'notifications';
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief the notifications configuration
|
||||
|
@ -46,36 +40,28 @@ exports.notifications = {};
|
|||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.notifications.versions = function () {
|
||||
var n = 'notifications';
|
||||
var v = 'versions';
|
||||
var d;
|
||||
let frontend = getFrontendCollection();
|
||||
if (!frontend) {
|
||||
// collection not (yet) available
|
||||
return { versions: {} };
|
||||
}
|
||||
let doc = {};
|
||||
|
||||
try {
|
||||
d = frontend.document(n);
|
||||
} catch (err) {
|
||||
let frontend = internal.db._collection(cn);
|
||||
if (frontend) {
|
||||
try {
|
||||
d = frontend.save({ _key: n });
|
||||
} catch (err2) {
|
||||
d = {};
|
||||
doc = frontend.document(key);
|
||||
} catch (err) {
|
||||
try {
|
||||
doc = frontend.insert({ _key: key });
|
||||
} catch (err) {}
|
||||
}
|
||||
}
|
||||
|
||||
d = shallowCopy(d);
|
||||
|
||||
if (!d.hasOwnProperty(v)) {
|
||||
d.versions = {};
|
||||
if (!doc.hasOwnProperty('versions')) {
|
||||
doc.versions = {};
|
||||
}
|
||||
if (internal.hasOwnProperty('frontendVersionCheck') &&
|
||||
!internal.frontendVersionCheck) {
|
||||
doc.enableVersionNotification = false;
|
||||
}
|
||||
|
||||
if (!internal.frontendVersionCheck) {
|
||||
d.enableVersionNotification = false;
|
||||
}
|
||||
|
||||
return d;
|
||||
return doc;
|
||||
};
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -83,19 +69,18 @@ exports.notifications.versions = function () {
|
|||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.notifications.setVersions = function (data) {
|
||||
const n = 'notifications';
|
||||
|
||||
let frontend = getFrontendCollection();
|
||||
let frontend = internal.db._collection(cn);
|
||||
if (!frontend) {
|
||||
// collection not (yet) available
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
frontend.document(n);
|
||||
// assume document is there already
|
||||
frontend.update(key, data);
|
||||
} catch (err) {
|
||||
frontend.save({ _key: n });
|
||||
// probably not, so try to insert it
|
||||
data._key = key;
|
||||
frontend.insert(data);
|
||||
}
|
||||
|
||||
frontend.update(n, data);
|
||||
};
|
|
@ -238,11 +238,29 @@
|
|||
|
||||
if (global.SYS_EXECUTE_GLOBAL_CONTEXT_FUNCTION) {
|
||||
exports.executeGlobalContextFunction = global.SYS_EXECUTE_GLOBAL_CONTEXT_FUNCTION;
|
||||
}else {
|
||||
} else {
|
||||
exports.executeGlobalContextFunction = function () {
|
||||
// nothing to do. we're probably in --no-server mode
|
||||
};
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief getCurrentRequest
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (global.SYS_GET_CURRENT_REQUEST) {
|
||||
exports.getCurrentRequest = global.SYS_GET_CURRENT_REQUEST;
|
||||
delete global.SYS_GET_CURRENT_REQUEST;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief getCurrentResponse
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (global.SYS_GET_CURRENT_RESPONSE) {
|
||||
exports.getCurrentResponse = global.SYS_GET_CURRENT_RESPONSE;
|
||||
delete global.SYS_GET_CURRENT_RESPONSE;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief reloads the AQL user functions
|
||||
|
|
|
@ -74,15 +74,7 @@ function RequireCanceledTestSuite() {
|
|||
'x-arango-v8-context': 0
|
||||
});
|
||||
|
||||
var d;
|
||||
|
||||
try {
|
||||
d = VPACK_TO_V8(c.body);
|
||||
} catch (err) {
|
||||
require("internal").print(c.body);
|
||||
throw err;
|
||||
}
|
||||
|
||||
var d = VPACK_TO_V8(c.body);
|
||||
assertEqual(2, d.length);
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue