mirror of https://gitee.com/bigwinds/arangodb
added --server.database option for client tools
This commit is contained in:
parent
41acd59698
commit
42b8dfca49
|
@ -1113,10 +1113,10 @@ static bool handleUserDatabase (TRI_doc_mptr_t const* document,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
string dbName = doc.getStringValue("name", "");
|
string databaseName = doc.getStringValue("name", "");
|
||||||
string dbPath = doc.getStringValue("path", "");
|
string databasePath = doc.getStringValue("path", "");
|
||||||
|
|
||||||
int res = VocbaseManager::manager.canAddVocbase(dbName, dbPath, false);
|
int res = VocbaseManager::manager.canAddVocbase(databaseName, databasePath, false);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
LOGGER_ERROR("cannot load database: " << string(TRI_errno_string(res)));
|
LOGGER_ERROR("cannot load database: " << string(TRI_errno_string(res)));
|
||||||
|
@ -1146,15 +1146,15 @@ static bool handleUserDatabase (TRI_doc_mptr_t const* document,
|
||||||
systemDefaults->authenticateSystemOnly);
|
systemDefaults->authenticateSystemOnly);
|
||||||
|
|
||||||
// open/load database
|
// open/load database
|
||||||
TRI_vocbase_t* userVocbase = TRI_OpenVocBase(dbPath.c_str(), dbName.c_str(), &defaults);
|
TRI_vocbase_t* userVocbase = TRI_OpenVocBase(databasePath.c_str(), databaseName.c_str(), &defaults);
|
||||||
|
|
||||||
if (userVocbase) {
|
if (userVocbase) {
|
||||||
VocbaseManager::manager.addUserVocbase(userVocbase);
|
VocbaseManager::manager.addUserVocbase(userVocbase);
|
||||||
|
|
||||||
LOGGER_INFO("loaded database '" << dbName << "' from '" << dbPath << "'");
|
LOGGER_INFO("loaded database '" << databaseName << "' from '" << databasePath << "'");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOGGER_ERROR("unable to load database '" << dbName << "' from '" << dbPath << "'");
|
LOGGER_ERROR("unable to load database '" << databaseName << "' from '" << databasePath << "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1228,26 +1228,26 @@ static bool handleEnpoint (TRI_doc_mptr_t const* document,
|
||||||
|
|
||||||
TRI_json_t const* json = doc.getJson();
|
TRI_json_t const* json = doc.getJson();
|
||||||
|
|
||||||
vector<std::string> dbNames;
|
vector<std::string> databaseNames;
|
||||||
|
|
||||||
if (JsonHelper::isList(json)) {
|
if (JsonHelper::isList(json)) {
|
||||||
for (size_t i = 0; i < json->_value._objects._length; ++i) {
|
for (size_t i = 0; i < json->_value._objects._length; ++i) {
|
||||||
TRI_json_t const* e = (TRI_json_t const*) TRI_AtVector(&json->_value._objects, i);
|
TRI_json_t const* e = (TRI_json_t const*) TRI_AtVector(&json->_value._objects, i);
|
||||||
|
|
||||||
if (JsonHelper::isString(e)) {
|
if (JsonHelper::isString(e)) {
|
||||||
const string dbName = JsonHelper::getStringValue(e, "");
|
const string databaseName = JsonHelper::getStringValue(e, "");
|
||||||
|
|
||||||
if (! dbName.empty()) {
|
if (! databaseName.empty()) {
|
||||||
dbNames.push_back(dbName);
|
databaseNames.push_back(databaseName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dbNames.push_back(TRI_VOC_SYSTEM_DATABASE);
|
databaseNames.push_back(TRI_VOC_SYSTEM_DATABASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
VocbaseManager::manager.addEndpoint(endpoint, dbNames);
|
VocbaseManager::manager.addEndpoint(endpoint, databaseNames);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,15 +96,15 @@ void VocbaseContext::setRequestUserByName (string const& name) {
|
||||||
/// @brief checks the authentication
|
/// @brief checks the authentication
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool VocbaseContext::authenticate () {
|
HttpResponse::HttpResponseCode VocbaseContext::authenticate () {
|
||||||
if (! _vocbase) {
|
if (! _vocbase) {
|
||||||
// no vocbase known
|
// no vocbase known
|
||||||
return true;
|
return HttpResponse::NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! _vocbase->_requireAuthentication) {
|
if (! _vocbase->_requireAuthentication) {
|
||||||
// no authentication required at all
|
// no authentication required at all
|
||||||
return true;
|
return HttpResponse::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_vocbase->_authenticateSystemOnly) {
|
if (_vocbase->_authenticateSystemOnly) {
|
||||||
|
@ -114,10 +114,10 @@ bool VocbaseContext::authenticate () {
|
||||||
if (path != 0) {
|
if (path != 0) {
|
||||||
// check if path starts with /_
|
// check if path starts with /_
|
||||||
if (*path != '/') {
|
if (*path != '/') {
|
||||||
return true;
|
return HttpResponse::OK;
|
||||||
}
|
}
|
||||||
if (*path != '\0' && *(path + 1) != '_') {
|
if (*path != '\0' && *(path + 1) != '_') {
|
||||||
return true;
|
return HttpResponse::OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "VocBase/vocbase.h"
|
#include "VocBase/vocbase.h"
|
||||||
#include "Rest/HttpRequest.h"
|
#include "Rest/HttpRequest.h"
|
||||||
|
#include "Rest/HttpResponse.h"
|
||||||
#include "Rest/RequestContext.h"
|
#include "Rest/RequestContext.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -127,7 +128,7 @@ namespace triagens {
|
||||||
/// @brief checks the authentication
|
/// @brief checks the authentication
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool authenticate ();
|
rest::HttpResponse::HttpResponseCode authenticate ();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @}
|
/// @}
|
||||||
|
|
|
@ -258,12 +258,12 @@ void VocbaseManager::initializeFoxx (TRI_vocbase_t* vocbase,
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool VocbaseManager::addEndpoint (std::string const& name,
|
bool VocbaseManager::addEndpoint (std::string const& name,
|
||||||
std::vector<std::string> const& dbNames) {
|
std::vector<std::string> const& databaseNames) {
|
||||||
|
|
||||||
if (_endpointServer) {
|
if (_endpointServer) {
|
||||||
{
|
{
|
||||||
WRITE_LOCKER(_rwLock);
|
WRITE_LOCKER(_rwLock);
|
||||||
_endpoints[name] = dbNames;
|
_endpoints[name] = databaseNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _endpointServer->addEndpoint(name);
|
return _endpointServer->addEndpoint(name);
|
||||||
|
@ -280,7 +280,7 @@ TRI_vocbase_t* VocbaseManager::lookupVocbaseByHttpRequest (triagens::rest::HttpR
|
||||||
TRI_vocbase_t* vocbase = 0;
|
TRI_vocbase_t* vocbase = 0;
|
||||||
|
|
||||||
// get database name from request
|
// get database name from request
|
||||||
string requestedName = request->dbName();
|
string requestedName = request->databaseName();
|
||||||
|
|
||||||
if (requestedName.empty()) {
|
if (requestedName.empty()) {
|
||||||
// no name set in request, use system database name as a fallback
|
// no name set in request, use system database name as a fallback
|
||||||
|
@ -321,9 +321,9 @@ TRI_vocbase_t* VocbaseManager::lookupVocbaseByHttpRequest (triagens::rest::HttpR
|
||||||
}
|
}
|
||||||
|
|
||||||
// we have a user-defined mapping for the endpoint
|
// we have a user-defined mapping for the endpoint
|
||||||
const vector<string>& dbNames = (*it2).second;
|
const vector<string>& databaseNames = (*it2).second;
|
||||||
|
|
||||||
if (dbNames.size() == 0) {
|
if (databaseNames.size() == 0) {
|
||||||
// list of database names is specified but empty. this means no-one will get access
|
// list of database names is specified but empty. this means no-one will get access
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -331,7 +331,7 @@ TRI_vocbase_t* VocbaseManager::lookupVocbaseByHttpRequest (triagens::rest::HttpR
|
||||||
// finally check if the requested database is in the list of allowed databases for the endpoint
|
// finally check if the requested database is in the list of allowed databases for the endpoint
|
||||||
vector<string>::const_iterator it3;
|
vector<string>::const_iterator it3;
|
||||||
|
|
||||||
for (it3 = dbNames.begin(); it3 != dbNames.end(); ++it3) {
|
for (it3 = databaseNames.begin(); it3 != databaseNames.end(); ++it3) {
|
||||||
if (requestedName == *it3) {
|
if (requestedName == *it3) {
|
||||||
return vocbase;
|
return vocbase;
|
||||||
}
|
}
|
||||||
|
@ -345,24 +345,21 @@ TRI_vocbase_t* VocbaseManager::lookupVocbaseByHttpRequest (triagens::rest::HttpR
|
||||||
/// @brief authenticate a request
|
/// @brief authenticate a request
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool VocbaseManager::authenticate (TRI_vocbase_t* vocbase,
|
HttpResponse::HttpResponseCode VocbaseManager::authenticate (TRI_vocbase_t* vocbase,
|
||||||
triagens::rest::HttpRequest* request) {
|
triagens::rest::HttpRequest* request) {
|
||||||
|
|
||||||
if (! vocbase) {
|
assert(vocbase != 0);
|
||||||
// unknown vocbase
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<TRI_vocbase_t*, std::map<std::string, std::string> >::iterator mapIter;
|
std::map<TRI_vocbase_t*, std::map<std::string, std::string> >::iterator mapIter;
|
||||||
|
|
||||||
bool found;
|
bool found;
|
||||||
char const* auth = request->header("authorization", found);
|
char const* auth = request->header("authorization", found);
|
||||||
|
|
||||||
if (found) {
|
if (! found || ! TRI_CaseEqualString2(auth, "basic ", 6)) {
|
||||||
if (! TRI_CaseEqualString2(auth, "basic ", 6)) {
|
return HttpResponse::UNAUTHORIZED;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// skip over "basic "
|
||||||
auth += 6;
|
auth += 6;
|
||||||
|
|
||||||
while (*auth == ' ') {
|
while (*auth == ' ') {
|
||||||
|
@ -375,14 +372,14 @@ bool VocbaseManager::authenticate (TRI_vocbase_t* vocbase,
|
||||||
mapIter = _authCache.find(vocbase);
|
mapIter = _authCache.find(vocbase);
|
||||||
if (mapIter == _authCache.end()) {
|
if (mapIter == _authCache.end()) {
|
||||||
// unknown vocbase
|
// unknown vocbase
|
||||||
return false;
|
return HttpResponse::NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
map<string,string>::iterator i = mapIter->second.find(auth);
|
map<string, string>::iterator i = mapIter->second.find(auth);
|
||||||
|
|
||||||
if (i != mapIter->second.end()) {
|
if (i != mapIter->second.end()) {
|
||||||
request->setUser(i->second);
|
request->setUser(i->second);
|
||||||
return true;
|
return HttpResponse::OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +388,8 @@ bool VocbaseManager::authenticate (TRI_vocbase_t* vocbase,
|
||||||
std::string::size_type n = up.find(':', 0);
|
std::string::size_type n = up.find(':', 0);
|
||||||
if (n == std::string::npos || n == 0 || n + 1 > up.size()) {
|
if (n == std::string::npos || n == 0 || n + 1 > up.size()) {
|
||||||
LOGGER_TRACE("invalid authentication data found, cannot extract username/password");
|
LOGGER_TRACE("invalid authentication data found, cannot extract username/password");
|
||||||
return false;
|
|
||||||
|
return HttpResponse::BAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
const string username = up.substr(0, n);
|
const string username = up.substr(0, n);
|
||||||
|
@ -400,25 +398,23 @@ bool VocbaseManager::authenticate (TRI_vocbase_t* vocbase,
|
||||||
|
|
||||||
bool res = TRI_CheckAuthenticationAuthInfo2(vocbase, username.c_str(), up.substr(n + 1).c_str());
|
bool res = TRI_CheckAuthenticationAuthInfo2(vocbase, username.c_str(), up.substr(n + 1).c_str());
|
||||||
|
|
||||||
if (res) {
|
if (! res) {
|
||||||
|
return HttpResponse::UNAUTHORIZED;
|
||||||
|
}
|
||||||
|
|
||||||
WRITE_LOCKER(_rwLock);
|
WRITE_LOCKER(_rwLock);
|
||||||
|
|
||||||
mapIter = _authCache.find(vocbase);
|
mapIter = _authCache.find(vocbase);
|
||||||
if (mapIter == _authCache.end()) {
|
if (mapIter == _authCache.end()) {
|
||||||
// unknown vocbase
|
// unknown vocbase
|
||||||
return false;
|
return HttpResponse::UNAUTHORIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapIter->second[auth] = username;
|
mapIter->second[auth] = username;
|
||||||
request->setUser(username);
|
request->setUser(username);
|
||||||
|
|
||||||
// TODO: create a user object for the VocbaseContext
|
// TODO: create a user object for the VocbaseContext
|
||||||
}
|
return HttpResponse::OK;
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -32,10 +32,11 @@
|
||||||
#include "BasicsC/win-utils.h"
|
#include "BasicsC/win-utils.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "VocBase/vocbase.h"
|
|
||||||
#include "Rest/HttpRequest.h"
|
|
||||||
#include "Basics/ReadLocker.h"
|
#include "Basics/ReadLocker.h"
|
||||||
#include "Basics/WriteLocker.h"
|
#include "Basics/WriteLocker.h"
|
||||||
|
#include "Rest/HttpRequest.h"
|
||||||
|
#include "Rest/HttpResponse.h"
|
||||||
|
#include "VocBase/vocbase.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -182,7 +183,7 @@ namespace triagens {
|
||||||
/// @brief authenticate a request
|
/// @brief authenticate a request
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool authenticate (TRI_vocbase_t*,
|
rest::HttpResponse::HttpResponseCode authenticate (TRI_vocbase_t*,
|
||||||
triagens::rest::HttpRequest*);
|
triagens::rest::HttpRequest*);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -105,6 +105,7 @@ ArangoClient::ArangoClient ()
|
||||||
_disableAuthentication(false),
|
_disableAuthentication(false),
|
||||||
_endpointString(),
|
_endpointString(),
|
||||||
_endpointServer(0),
|
_endpointServer(0),
|
||||||
|
_databaseName("_system"),
|
||||||
_username("root"),
|
_username("root"),
|
||||||
_password(""),
|
_password(""),
|
||||||
_hasPassword(false),
|
_hasPassword(false),
|
||||||
|
@ -233,7 +234,8 @@ void ArangoClient::setupServer (ProgramOptionsDescription& description) {
|
||||||
ProgramOptionsDescription clientOptions("CLIENT options");
|
ProgramOptionsDescription clientOptions("CLIENT options");
|
||||||
|
|
||||||
clientOptions
|
clientOptions
|
||||||
("server.disable-authentication", &_disableAuthentication, "disable authentication")
|
("server.database", &_databaseName, "database name to use when connecting")
|
||||||
|
("server.disable-authentication", &_disableAuthentication, "disable authentication (will disable password prompt)")
|
||||||
("server.endpoint", &_endpointString, "endpoint to connect to, use 'none' to start without a server")
|
("server.endpoint", &_endpointString, "endpoint to connect to, use 'none' to start without a server")
|
||||||
("server.username", &_username, "username to use when connecting")
|
("server.username", &_username, "username to use when connecting")
|
||||||
("server.password", &_password, "password to use when connecting (leave empty for prompt)")
|
("server.password", &_password, "password to use when connecting (leave empty for prompt)")
|
||||||
|
@ -675,6 +677,14 @@ Endpoint* ArangoClient::endpointServer() const {
|
||||||
return _endpointServer;
|
return _endpointServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief database name
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
string const& ArangoClient::databaseName () const {
|
||||||
|
return _databaseName;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief user to send to endpoint
|
/// @brief user to send to endpoint
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -691,6 +701,14 @@ string const& ArangoClient::password () const {
|
||||||
return _password;
|
return _password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief set database name
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void ArangoClient::setDatabaseName (string const& databaseName) {
|
||||||
|
_databaseName = databaseName;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief set username
|
/// @brief set username
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -343,6 +343,18 @@ namespace triagens {
|
||||||
|
|
||||||
triagens::rest::Endpoint* endpointServer() const;
|
triagens::rest::Endpoint* endpointServer() const;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief database name
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
string const& databaseName () const;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief set database name
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void setDatabaseName (string const&);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief user to send to endpoint
|
/// @brief user to send to endpoint
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -518,6 +530,12 @@ namespace triagens {
|
||||||
|
|
||||||
triagens::rest::Endpoint* _endpointServer;
|
triagens::rest::Endpoint* _endpointServer;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief database name
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
string _databaseName;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief user to send to endpoint
|
/// @brief user to send to endpoint
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -78,6 +78,7 @@ namespace triagens {
|
||||||
const unsigned long batchSize,
|
const unsigned long batchSize,
|
||||||
BenchmarkCounter<unsigned long>* operationsCounter,
|
BenchmarkCounter<unsigned long>* operationsCounter,
|
||||||
Endpoint* endpoint,
|
Endpoint* endpoint,
|
||||||
|
const string& databaseName,
|
||||||
const string& username,
|
const string& username,
|
||||||
const string& password,
|
const string& password,
|
||||||
double requestTimeout,
|
double requestTimeout,
|
||||||
|
@ -91,6 +92,7 @@ namespace triagens {
|
||||||
_warningCount(0),
|
_warningCount(0),
|
||||||
_operationsCounter(operationsCounter),
|
_operationsCounter(operationsCounter),
|
||||||
_endpoint(endpoint),
|
_endpoint(endpoint),
|
||||||
|
_databaseName(databaseName),
|
||||||
_username(username),
|
_username(username),
|
||||||
_password(password),
|
_password(password),
|
||||||
_requestTimeout(requestTimeout),
|
_requestTimeout(requestTimeout),
|
||||||
|
@ -146,6 +148,13 @@ namespace triagens {
|
||||||
}
|
}
|
||||||
|
|
||||||
_client = new SimpleHttpClient(_connection, 10.0, true);
|
_client = new SimpleHttpClient(_connection, 10.0, true);
|
||||||
|
|
||||||
|
if (_client == 0) {
|
||||||
|
LOGGER_FATAL_AND_EXIT("out of memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
_client->setLocationRewriter(this, &rewriteLocation);
|
||||||
|
|
||||||
_client->setUserNamePassword("/", _username, _password);
|
_client->setUserNamePassword("/", _username, _password);
|
||||||
|
|
||||||
// test the connection
|
// test the connection
|
||||||
|
@ -213,6 +222,28 @@ namespace triagens {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief request location rewriter (injects database name)
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static string rewriteLocation (void* data, const string& location) {
|
||||||
|
BenchmarkThread* t = static_cast<BenchmarkThread*>(data);
|
||||||
|
|
||||||
|
assert(t != 0);
|
||||||
|
|
||||||
|
if (location.substr(0, 5) == "/_db/") {
|
||||||
|
// location already contains /_db/
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (location[0] == '/') {
|
||||||
|
return "/_db/" + t->_databaseName + location;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "/_db/" + t->_databaseName + "/" + location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief execute a batch request with numOperations parts
|
/// @brief execute a batch request with numOperations parts
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -442,6 +473,12 @@ namespace triagens {
|
||||||
|
|
||||||
Endpoint* _endpoint;
|
Endpoint* _endpoint;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief database name
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const string _databaseName;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief HTTP username
|
/// @brief HTTP username
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -470,7 +507,7 @@ namespace triagens {
|
||||||
/// @brief underlying client
|
/// @brief underlying client
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
triagens::httpclient::SimpleClient* _client;
|
triagens::httpclient::SimpleHttpClient* _client;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief connection to the server
|
/// @brief connection to the server
|
||||||
|
|
|
@ -290,6 +290,7 @@ int main (int argc, char* argv[]) {
|
||||||
(unsigned long) BatchSize,
|
(unsigned long) BatchSize,
|
||||||
&operationsCounter,
|
&operationsCounter,
|
||||||
endpoint,
|
endpoint,
|
||||||
|
BaseClient.databaseName(),
|
||||||
BaseClient.username(),
|
BaseClient.username(),
|
||||||
BaseClient.password(),
|
BaseClient.password(),
|
||||||
BaseClient.requestTimeout(),
|
BaseClient.requestTimeout(),
|
||||||
|
@ -348,7 +349,7 @@ int main (int argc, char* argv[]) {
|
||||||
|
|
||||||
cout << endl;
|
cout << endl;
|
||||||
cout << "Total number of operations: " << Operations << ", batch size: " << BatchSize << ", concurrency level (threads): " << Concurrency << endl;
|
cout << "Total number of operations: " << Operations << ", batch size: " << BatchSize << ", concurrency level (threads): " << Concurrency << endl;
|
||||||
cout << "Test case: " << TestCase << ", complexity: " << Complexity << ", collection: '" << Collection << "'" << endl;
|
cout << "Test case: " << TestCase << ", complexity: " << Complexity << ", database: '" << BaseClient.databaseName() << "', collection: '" << Collection << "'" << endl;
|
||||||
cout << "Total request/response duration (sum of all threads): " << fixed << requestTime << " s" << endl;
|
cout << "Total request/response duration (sum of all threads): " << fixed << requestTime << " s" << endl;
|
||||||
cout << "Request/response duration (per thread): " << fixed << (requestTime / (double) Concurrency) << " s" << endl;
|
cout << "Request/response duration (per thread): " << fixed << (requestTime / (double) Concurrency) << " s" << endl;
|
||||||
cout << "Time needed per operation: " << fixed << (time / Operations) << " s" << endl;
|
cout << "Time needed per operation: " << fixed << (time / Operations) << " s" << endl;
|
||||||
|
|
|
@ -61,6 +61,7 @@ using namespace std;
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
V8ClientConnection::V8ClientConnection (Endpoint* endpoint,
|
V8ClientConnection::V8ClientConnection (Endpoint* endpoint,
|
||||||
|
string databaseName,
|
||||||
const string& username,
|
const string& username,
|
||||||
const string& password,
|
const string& password,
|
||||||
double requestTimeout,
|
double requestTimeout,
|
||||||
|
@ -68,6 +69,7 @@ V8ClientConnection::V8ClientConnection (Endpoint* endpoint,
|
||||||
size_t numRetries,
|
size_t numRetries,
|
||||||
bool warn)
|
bool warn)
|
||||||
: _connection(0),
|
: _connection(0),
|
||||||
|
_databaseName(databaseName),
|
||||||
_lastHttpReturnCode(0),
|
_lastHttpReturnCode(0),
|
||||||
_lastErrorMessage(""),
|
_lastErrorMessage(""),
|
||||||
_client(0),
|
_client(0),
|
||||||
|
@ -83,9 +85,11 @@ V8ClientConnection::V8ClientConnection (Endpoint* endpoint,
|
||||||
_client = new SimpleHttpClient(_connection, requestTimeout, warn);
|
_client = new SimpleHttpClient(_connection, requestTimeout, warn);
|
||||||
|
|
||||||
if (_client == 0) {
|
if (_client == 0) {
|
||||||
throw "out of memory";
|
LOGGER_FATAL_AND_EXIT("out of memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_client->setLocationRewriter(this, &rewriteLocation);
|
||||||
|
|
||||||
_client->setUserNamePassword("/", username, password);
|
_client->setUserNamePassword("/", username, password);
|
||||||
|
|
||||||
// connect to server and get version number
|
// connect to server and get version number
|
||||||
|
@ -167,6 +171,28 @@ V8ClientConnection::~V8ClientConnection () {
|
||||||
/// @{
|
/// @{
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief request location rewriter (injects database name)
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
string V8ClientConnection::rewriteLocation (void* data, const string& location) {
|
||||||
|
V8ClientConnection* c = static_cast<V8ClientConnection*>(data);
|
||||||
|
|
||||||
|
assert(c != 0);
|
||||||
|
|
||||||
|
if (location.substr(0, 5) == "/_db/") {
|
||||||
|
// location already contains /_db/
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (location[0] == '/') {
|
||||||
|
return "/_db/" + c->_databaseName + location;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "/_db/" + c->_databaseName + "/" + location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief returns true if it is connected
|
/// @brief returns true if it is connected
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -175,6 +201,22 @@ bool V8ClientConnection::isConnected () {
|
||||||
return _connection->isConnected();
|
return _connection->isConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns the current database name
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const string& V8ClientConnection::getDatabaseName () {
|
||||||
|
return _databaseName;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief set the current database name
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void V8ClientConnection::setDatabaseName (const string& databaseName) {
|
||||||
|
_databaseName = databaseName;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief returns the version and build number of the arango server
|
/// @brief returns the version and build number of the arango server
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -91,6 +91,7 @@ namespace triagens {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
V8ClientConnection (triagens::rest::Endpoint*,
|
V8ClientConnection (triagens::rest::Endpoint*,
|
||||||
|
string,
|
||||||
const string&,
|
const string&,
|
||||||
const string&,
|
const string&,
|
||||||
double,
|
double,
|
||||||
|
@ -119,12 +120,30 @@ namespace triagens {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief request location rewriter (injects database name)
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static string rewriteLocation (void*, const string&);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief returns true if it is connected
|
/// @brief returns true if it is connected
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool isConnected ();
|
bool isConnected ();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns the current database name
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const string& getDatabaseName ();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief set the current database name
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void setDatabaseName (const string&);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief returns the version and build number of the arango server
|
/// @brief returns the version and build number of the arango server
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -344,6 +363,12 @@ namespace triagens {
|
||||||
|
|
||||||
triagens::httpclient::GeneralClientConnection* _connection;
|
triagens::httpclient::GeneralClientConnection* _connection;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief database name
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::string _databaseName;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief server version
|
/// @brief server version
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -284,10 +284,11 @@ int main (int argc, char* argv[]) {
|
||||||
|
|
||||||
if (BaseClient.endpointServer() == 0) {
|
if (BaseClient.endpointServer() == 0) {
|
||||||
cerr << "invalid value for --server.endpoint ('" << BaseClient.endpointString() << "')" << endl;
|
cerr << "invalid value for --server.endpoint ('" << BaseClient.endpointString() << "')" << endl;
|
||||||
TRI_EXIT_FUNCTION(EXIT_FAILURE,NULL);
|
TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientConnection = new V8ClientConnection(BaseClient.endpointServer(),
|
ClientConnection = new V8ClientConnection(BaseClient.endpointServer(),
|
||||||
|
BaseClient.databaseName(),
|
||||||
BaseClient.username(),
|
BaseClient.username(),
|
||||||
BaseClient.password(),
|
BaseClient.password(),
|
||||||
BaseClient.requestTimeout(),
|
BaseClient.requestTimeout(),
|
||||||
|
@ -298,7 +299,7 @@ int main (int argc, char* argv[]) {
|
||||||
if (! ClientConnection->isConnected() || ClientConnection->getLastHttpReturnCode() != HttpResponse::OK) {
|
if (! ClientConnection->isConnected() || ClientConnection->getLastHttpReturnCode() != HttpResponse::OK) {
|
||||||
cerr << "Could not connect to endpoint " << BaseClient.endpointServer()->getSpecification() << endl;
|
cerr << "Could not connect to endpoint " << BaseClient.endpointServer()->getSpecification() << endl;
|
||||||
cerr << "Error message: '" << ClientConnection->getErrorMessage() << "'" << endl;
|
cerr << "Error message: '" << ClientConnection->getErrorMessage() << "'" << endl;
|
||||||
TRI_EXIT_FUNCTION(EXIT_FAILURE,NULL);
|
TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// successfully connected
|
// successfully connected
|
||||||
|
@ -306,6 +307,7 @@ int main (int argc, char* argv[]) {
|
||||||
<< "' Version " << ClientConnection->getVersion() << endl;
|
<< "' Version " << ClientConnection->getVersion() << endl;
|
||||||
|
|
||||||
cout << "----------------------------------------" << endl;
|
cout << "----------------------------------------" << endl;
|
||||||
|
cout << "database: " << BaseClient.databaseName() << endl;
|
||||||
cout << "collection: " << CollectionName << endl;
|
cout << "collection: " << CollectionName << endl;
|
||||||
cout << "create: " << (CreateCollection ? "yes" : "no") << endl;
|
cout << "create: " << (CreateCollection ? "yes" : "no") << endl;
|
||||||
cout << "file: " << FileName << endl;
|
cout << "file: " << FileName << endl;
|
||||||
|
@ -333,7 +335,7 @@ int main (int argc, char* argv[]) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cerr << "Wrong length of quote character." << endl;
|
cerr << "Wrong length of quote character." << endl;
|
||||||
TRI_EXIT_FUNCTION(EXIT_FAILURE,NULL);
|
TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// separator
|
// separator
|
||||||
|
@ -342,24 +344,24 @@ int main (int argc, char* argv[]) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cerr << "Separator must be exactly one character." << endl;
|
cerr << "Separator must be exactly one character." << endl;
|
||||||
TRI_EXIT_FUNCTION(EXIT_FAILURE,NULL);
|
TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// collection name
|
// collection name
|
||||||
if (CollectionName == "") {
|
if (CollectionName == "") {
|
||||||
cerr << "collection name is missing." << endl;
|
cerr << "collection name is missing." << endl;
|
||||||
TRI_EXIT_FUNCTION(EXIT_FAILURE,NULL);
|
TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// filename
|
// filename
|
||||||
if (FileName == "") {
|
if (FileName == "") {
|
||||||
cerr << "file name is missing." << endl;
|
cerr << "file name is missing." << endl;
|
||||||
TRI_EXIT_FUNCTION(EXIT_FAILURE,NULL);
|
TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FileName != "-" && ! FileUtils::isRegularFile(FileName)) {
|
if (FileName != "-" && ! FileUtils::isRegularFile(FileName)) {
|
||||||
cerr << "file '" << FileName << "' is not a regular file." << endl;
|
cerr << "file '" << FileName << "' is not a regular file." << endl;
|
||||||
TRI_EXIT_FUNCTION(EXIT_FAILURE,NULL);
|
TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// progress
|
// progress
|
||||||
|
@ -389,7 +391,7 @@ int main (int argc, char* argv[]) {
|
||||||
|
|
||||||
else {
|
else {
|
||||||
cerr << "Wrong type '" << TypeImport << "'." << endl;
|
cerr << "Wrong type '" << TypeImport << "'." << endl;
|
||||||
TRI_EXIT_FUNCTION(EXIT_FAILURE,NULL);
|
TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << endl;
|
cout << endl;
|
||||||
|
|
|
@ -386,6 +386,7 @@ static v8::Handle<v8::Value> JS_compare_string (v8::Arguments const& argv) {
|
||||||
|
|
||||||
static V8ClientConnection* CreateConnection () {
|
static V8ClientConnection* CreateConnection () {
|
||||||
return new V8ClientConnection(BaseClient.endpointServer(),
|
return new V8ClientConnection(BaseClient.endpointServer(),
|
||||||
|
BaseClient.databaseName(),
|
||||||
BaseClient.username(),
|
BaseClient.username(),
|
||||||
BaseClient.password(),
|
BaseClient.password(),
|
||||||
BaseClient.requestTimeout(),
|
BaseClient.requestTimeout(),
|
||||||
|
@ -554,22 +555,24 @@ static v8::Handle<v8::Value> ClientConnection_reconnect (v8::Arguments const& ar
|
||||||
TRI_V8_EXCEPTION_INTERNAL(scope, "connection class corrupted");
|
TRI_V8_EXCEPTION_INTERNAL(scope, "connection class corrupted");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv.Length() < 1) {
|
if (argv.Length() < 2) {
|
||||||
TRI_V8_EXCEPTION_USAGE(scope, "reconnect(<endpoint>[, <username>, <password>])");
|
TRI_V8_EXCEPTION_USAGE(scope, "reconnect(<endpoint>, <databasename>, [, <username>, <password>])");
|
||||||
}
|
}
|
||||||
|
|
||||||
string definition = TRI_ObjectToString(argv[0]);
|
string definition = TRI_ObjectToString(argv[0]);
|
||||||
|
|
||||||
|
string databaseName = TRI_ObjectToString(argv[1]);
|
||||||
|
|
||||||
string username;
|
string username;
|
||||||
if (argv.Length() < 2) {
|
if (argv.Length() < 3) {
|
||||||
username = BaseClient.username();
|
username = BaseClient.username();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
username = TRI_ObjectToString(argv[1]);
|
username = TRI_ObjectToString(argv[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
string password;
|
string password;
|
||||||
if (argv.Length() < 3) {
|
if (argv.Length() < 4) {
|
||||||
cout << "Please specify a password: " << flush;
|
cout << "Please specify a password: " << flush;
|
||||||
|
|
||||||
// now prompt for it
|
// now prompt for it
|
||||||
|
@ -584,16 +587,18 @@ static v8::Handle<v8::Value> ClientConnection_reconnect (v8::Arguments const& ar
|
||||||
cout << "\n";
|
cout << "\n";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
password = TRI_ObjectToString(argv[2]);
|
password = TRI_ObjectToString(argv[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const string oldDefinition = BaseClient.endpointString();
|
const string oldDefinition = BaseClient.endpointString();
|
||||||
|
const string oldDatabaseName = BaseClient.databaseName();
|
||||||
const string oldUsername = BaseClient.username();
|
const string oldUsername = BaseClient.username();
|
||||||
const string oldPassword = BaseClient.password();
|
const string oldPassword = BaseClient.password();
|
||||||
|
|
||||||
delete connection;
|
delete connection;
|
||||||
|
|
||||||
BaseClient.setEndpointString(definition);
|
BaseClient.setEndpointString(definition);
|
||||||
|
BaseClient.setDatabaseName(databaseName);
|
||||||
BaseClient.setUsername(username);
|
BaseClient.setUsername(username);
|
||||||
BaseClient.setPassword(password);
|
BaseClient.setPassword(password);
|
||||||
|
|
||||||
|
@ -601,6 +606,7 @@ static v8::Handle<v8::Value> ClientConnection_reconnect (v8::Arguments const& ar
|
||||||
BaseClient.createEndpoint();
|
BaseClient.createEndpoint();
|
||||||
if (BaseClient.endpointServer() == 0) {
|
if (BaseClient.endpointServer() == 0) {
|
||||||
BaseClient.setEndpointString(oldDefinition);
|
BaseClient.setEndpointString(oldDefinition);
|
||||||
|
BaseClient.setDatabaseName(oldDatabaseName);
|
||||||
BaseClient.setUsername(oldUsername);
|
BaseClient.setUsername(oldUsername);
|
||||||
BaseClient.setPassword(oldPassword);
|
BaseClient.setPassword(oldPassword);
|
||||||
BaseClient.createEndpoint();
|
BaseClient.createEndpoint();
|
||||||
|
@ -644,6 +650,7 @@ static v8::Handle<v8::Value> ClientConnection_reconnect (v8::Arguments const& ar
|
||||||
|
|
||||||
// rollback
|
// rollback
|
||||||
BaseClient.setEndpointString(oldDefinition);
|
BaseClient.setEndpointString(oldDefinition);
|
||||||
|
BaseClient.setDatabaseName(oldDatabaseName);
|
||||||
BaseClient.setUsername(oldUsername);
|
BaseClient.setUsername(oldUsername);
|
||||||
BaseClient.setPassword(oldPassword);
|
BaseClient.setPassword(oldPassword);
|
||||||
BaseClient.createEndpoint();
|
BaseClient.createEndpoint();
|
||||||
|
@ -1173,6 +1180,50 @@ static v8::Handle<v8::Value> ClientConnection_getVersion (v8::Arguments const& a
|
||||||
return scope.Close(v8::String::New(connection->getVersion().c_str()));
|
return scope.Close(v8::String::New(connection->getVersion().c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief ClientConnection method "getDatabaseName"
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static v8::Handle<v8::Value> ClientConnection_getDatabaseName (v8::Arguments const& argv) {
|
||||||
|
v8::HandleScope scope;
|
||||||
|
|
||||||
|
// get the connection
|
||||||
|
V8ClientConnection* connection = TRI_UnwrapClass<V8ClientConnection>(argv.Holder(), WRAP_TYPE_CONNECTION);
|
||||||
|
|
||||||
|
if (connection == 0) {
|
||||||
|
TRI_V8_EXCEPTION_INTERNAL(scope, "connection class corrupted");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argv.Length() != 0) {
|
||||||
|
TRI_V8_EXCEPTION_USAGE(scope, "getDatabaseName()");
|
||||||
|
}
|
||||||
|
|
||||||
|
return scope.Close(v8::String::New(connection->getDatabaseName().c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief ClientConnection method "setDatabaseName"
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static v8::Handle<v8::Value> ClientConnection_setDatabaseName (v8::Arguments const& argv) {
|
||||||
|
v8::HandleScope scope;
|
||||||
|
|
||||||
|
// get the connection
|
||||||
|
V8ClientConnection* connection = TRI_UnwrapClass<V8ClientConnection>(argv.Holder(), WRAP_TYPE_CONNECTION);
|
||||||
|
|
||||||
|
if (connection == 0) {
|
||||||
|
TRI_V8_EXCEPTION_INTERNAL(scope, "connection class corrupted");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argv.Length() != 1 || ! argv[0]->IsString()) {
|
||||||
|
TRI_V8_EXCEPTION_USAGE(scope, "setDatabaseName(<name>)");
|
||||||
|
}
|
||||||
|
|
||||||
|
connection->setDatabaseName(TRI_ObjectToString(argv[0]));
|
||||||
|
|
||||||
|
return scope.Close(v8::True());
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief executes the shell
|
/// @brief executes the shell
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1646,6 +1697,8 @@ int main (int argc, char* argv[]) {
|
||||||
connection_proto->Set("reconnect", v8::FunctionTemplate::New(ClientConnection_reconnect));
|
connection_proto->Set("reconnect", v8::FunctionTemplate::New(ClientConnection_reconnect));
|
||||||
connection_proto->Set("toString", v8::FunctionTemplate::New(ClientConnection_toString));
|
connection_proto->Set("toString", v8::FunctionTemplate::New(ClientConnection_toString));
|
||||||
connection_proto->Set("getVersion", v8::FunctionTemplate::New(ClientConnection_getVersion));
|
connection_proto->Set("getVersion", v8::FunctionTemplate::New(ClientConnection_getVersion));
|
||||||
|
connection_proto->Set("getDatabaseName", v8::FunctionTemplate::New(ClientConnection_getDatabaseName));
|
||||||
|
connection_proto->Set("setDatabaseName", v8::FunctionTemplate::New(ClientConnection_setDatabaseName));
|
||||||
connection_proto->SetCallAsFunctionHandler(ClientConnection_ConstructorCallback);
|
connection_proto->SetCallAsFunctionHandler(ClientConnection_ConstructorCallback);
|
||||||
|
|
||||||
v8::Handle<v8::ObjectTemplate> connection_inst = connection_templ->InstanceTemplate();
|
v8::Handle<v8::ObjectTemplate> connection_inst = connection_templ->InstanceTemplate();
|
||||||
|
|
|
@ -263,8 +263,9 @@ ArangoDatabase.prototype.toString = function () {
|
||||||
/// @brief return all collections from the database
|
/// @brief return all collections from the database
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArangoDatabase.prototype._collections = function () {
|
ArangoDatabase.prototype._collections = function (excludeSystem) {
|
||||||
var requestResult = this._connection.GET(this._collectionurl());
|
var append = (excludeSystem ? "?excludeSystem=true" : "");
|
||||||
|
var requestResult = this._connection.GET(this._collectionurl() + append);
|
||||||
|
|
||||||
arangosh.checkRequestResult(requestResult);
|
arangosh.checkRequestResult(requestResult);
|
||||||
|
|
||||||
|
@ -452,8 +453,8 @@ ArangoDatabase.prototype._flushCache = function () {
|
||||||
/// @brief query the database properties
|
/// @brief query the database properties
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArangoDatabase.prototype._queryProperties = function () {
|
ArangoDatabase.prototype._queryProperties = function (force) {
|
||||||
if (this._properties === null) {
|
if (force || this._properties === null) {
|
||||||
var requestResult = this._connection.GET("/_api/current-database");
|
var requestResult = this._connection.GET("/_api/current-database");
|
||||||
|
|
||||||
arangosh.checkRequestResult(requestResult);
|
arangosh.checkRequestResult(requestResult);
|
||||||
|
@ -844,6 +845,37 @@ ArangoDatabase.prototype._listDatabases = function () {
|
||||||
return requestResult.result;
|
return requestResult.result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief uses a database
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ArangoDatabase.prototype._useDatabase = function (name) {
|
||||||
|
var old = this._connection.getDatabaseName();
|
||||||
|
|
||||||
|
this._connection.setDatabaseName(name);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// re-query properties
|
||||||
|
this._queryProperties(true);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
this._connection.setDatabaseName(old);
|
||||||
|
|
||||||
|
if (err.hasOwnProperty("errorNum")) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ArangoError({
|
||||||
|
error: true,
|
||||||
|
code: internal.errors.ERROR_BAD_PARAMETER.code,
|
||||||
|
errorNum: internal.errors.ERROR_BAD_PARAMETER.code,
|
||||||
|
errorMessage: "cannot use database '" + name + "'"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @}
|
/// @}
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -262,8 +262,9 @@ ArangoDatabase.prototype.toString = function () {
|
||||||
/// @brief return all collections from the database
|
/// @brief return all collections from the database
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArangoDatabase.prototype._collections = function () {
|
ArangoDatabase.prototype._collections = function (excludeSystem) {
|
||||||
var requestResult = this._connection.GET(this._collectionurl());
|
var append = (excludeSystem ? "?excludeSystem=true" : "");
|
||||||
|
var requestResult = this._connection.GET(this._collectionurl() + append);
|
||||||
|
|
||||||
arangosh.checkRequestResult(requestResult);
|
arangosh.checkRequestResult(requestResult);
|
||||||
|
|
||||||
|
@ -451,8 +452,8 @@ ArangoDatabase.prototype._flushCache = function () {
|
||||||
/// @brief query the database properties
|
/// @brief query the database properties
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArangoDatabase.prototype._queryProperties = function () {
|
ArangoDatabase.prototype._queryProperties = function (force) {
|
||||||
if (this._properties === null) {
|
if (force || this._properties === null) {
|
||||||
var requestResult = this._connection.GET("/_api/current-database");
|
var requestResult = this._connection.GET("/_api/current-database");
|
||||||
|
|
||||||
arangosh.checkRequestResult(requestResult);
|
arangosh.checkRequestResult(requestResult);
|
||||||
|
@ -843,6 +844,43 @@ ArangoDatabase.prototype._listDatabases = function () {
|
||||||
return requestResult.result;
|
return requestResult.result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief uses a database
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ArangoDatabase.prototype._useDatabase = function (name) {
|
||||||
|
var old = this._connection.getDatabaseName();
|
||||||
|
|
||||||
|
// no change
|
||||||
|
if (name === old) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._connection.setDatabaseName(name);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// re-query properties
|
||||||
|
this._queryProperties(true);
|
||||||
|
this._flushCache();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
this._connection.setDatabaseName(old);
|
||||||
|
|
||||||
|
if (err.hasOwnProperty("errorNum")) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ArangoError({
|
||||||
|
error: true,
|
||||||
|
code: internal.errors.ERROR_BAD_PARAMETER.code,
|
||||||
|
errorNum: internal.errors.ERROR_BAD_PARAMETER.code,
|
||||||
|
errorMessage: "cannot use database '" + name + "'"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @}
|
/// @}
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -47,7 +47,7 @@ function AuthSuite () {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
setUp : function () {
|
setUp : function () {
|
||||||
arango.reconnect(arango.getEndpoint(), "root", "");
|
arango.reconnect(arango.getEndpoint(), db._name(), "root", "");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
users.remove("hackers@arangodb.org");
|
users.remove("hackers@arangodb.org");
|
||||||
|
@ -76,21 +76,21 @@ function AuthSuite () {
|
||||||
users.save("hackers@arangodb.org", "foobar");
|
users.save("hackers@arangodb.org", "foobar");
|
||||||
users.reload();
|
users.reload();
|
||||||
|
|
||||||
arango.reconnect(arango.getEndpoint(), "hackers@arangodb.org", "foobar");
|
arango.reconnect(arango.getEndpoint(), db._name(), "hackers@arangodb.org", "foobar");
|
||||||
|
|
||||||
// this will issue a request using the new user
|
// this will issue a request using the new user
|
||||||
assertTrue(db._collections().length > 0);
|
assertTrue(db._collections().length > 0);
|
||||||
|
|
||||||
// double check with wrong passwords
|
// double check with wrong passwords
|
||||||
try {
|
try {
|
||||||
arango.reconnect(arango.getEndpoint(), "hackers@arangodb.org", "foobar2");
|
arango.reconnect(arango.getEndpoint(), db._name(), "hackers@arangodb.org", "foobar2");
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (err1) {
|
catch (err1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
arango.reconnect(arango.getEndpoint(), "hackers@arangodb.org", "");
|
arango.reconnect(arango.getEndpoint(), db._name(), "hackers@arangodb.org", "");
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (err2) {
|
catch (err2) {
|
||||||
|
@ -105,14 +105,14 @@ function AuthSuite () {
|
||||||
users.save("hackers@arangodb.org", "");
|
users.save("hackers@arangodb.org", "");
|
||||||
users.reload();
|
users.reload();
|
||||||
|
|
||||||
arango.reconnect(arango.getEndpoint(), "hackers@arangodb.org", "");
|
arango.reconnect(arango.getEndpoint(), db._name(), "hackers@arangodb.org", "");
|
||||||
|
|
||||||
// this will issue a request using the new user
|
// this will issue a request using the new user
|
||||||
assertTrue(db._collections().length > 0);
|
assertTrue(db._collections().length > 0);
|
||||||
|
|
||||||
// double check with wrong password
|
// double check with wrong password
|
||||||
try {
|
try {
|
||||||
arango.reconnect(arango.getEndpoint(), "hackers@arangodb.org", "foobar");
|
arango.reconnect(arango.getEndpoint(), db._name(), "hackers@arangodb.org", "foobar");
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (err1) {
|
catch (err1) {
|
||||||
|
@ -127,28 +127,28 @@ function AuthSuite () {
|
||||||
users.save("hackers@arangodb.org", "FooBar");
|
users.save("hackers@arangodb.org", "FooBar");
|
||||||
users.reload();
|
users.reload();
|
||||||
|
|
||||||
arango.reconnect(arango.getEndpoint(), "hackers@arangodb.org", "FooBar");
|
arango.reconnect(arango.getEndpoint(), db._name(), "hackers@arangodb.org", "FooBar");
|
||||||
|
|
||||||
// this will issue a request using the new user
|
// this will issue a request using the new user
|
||||||
assertTrue(db._collections().length > 0);
|
assertTrue(db._collections().length > 0);
|
||||||
|
|
||||||
// double check with wrong passwords
|
// double check with wrong passwords
|
||||||
try {
|
try {
|
||||||
arango.reconnect(arango.getEndpoint(), "hackers@arangodb.org", "Foobar");
|
arango.reconnect(arango.getEndpoint(), db._name(), "hackers@arangodb.org", "Foobar");
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (err1) {
|
catch (err1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
arango.reconnect(arango.getEndpoint(), "hackers@arangodb.org", "foobar");
|
arango.reconnect(arango.getEndpoint(), db._name(), "hackers@arangodb.org", "foobar");
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (err2) {
|
catch (err2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
arango.reconnect(arango.getEndpoint(), "hackers@arangodb.org", "FOOBAR");
|
arango.reconnect(arango.getEndpoint(), db._name(), "hackers@arangodb.org", "FOOBAR");
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (err3) {
|
catch (err3) {
|
||||||
|
@ -163,28 +163,28 @@ function AuthSuite () {
|
||||||
users.save("hackers@arangodb.org", "fuxx::bar");
|
users.save("hackers@arangodb.org", "fuxx::bar");
|
||||||
users.reload();
|
users.reload();
|
||||||
|
|
||||||
arango.reconnect(arango.getEndpoint(), "hackers@arangodb.org", "fuxx::bar");
|
arango.reconnect(arango.getEndpoint(), db._name(), "hackers@arangodb.org", "fuxx::bar");
|
||||||
|
|
||||||
// this will issue a request using the new user
|
// this will issue a request using the new user
|
||||||
assertTrue(db._collections().length > 0);
|
assertTrue(db._collections().length > 0);
|
||||||
|
|
||||||
// double check with wrong passwords
|
// double check with wrong passwords
|
||||||
try {
|
try {
|
||||||
arango.reconnect(arango.getEndpoint(), "hackers@arangodb.org", "fuxx");
|
arango.reconnect(arango.getEndpoint(), db._name(), "hackers@arangodb.org", "fuxx");
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (err1) {
|
catch (err1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
arango.reconnect(arango.getEndpoint(), "hackers@arangodb.org", "bar");
|
arango.reconnect(arango.getEndpoint(), db._name(), "hackers@arangodb.org", "bar");
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (err2) {
|
catch (err2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
arango.reconnect(arango.getEndpoint(), "hackers@arangodb.org", "");
|
arango.reconnect(arango.getEndpoint(), db._name(), "hackers@arangodb.org", "");
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (err3) {
|
catch (err3) {
|
||||||
|
@ -199,28 +199,28 @@ function AuthSuite () {
|
||||||
users.save("hackers@arangodb.org", ":\\abc'def:foobar@04. x-a");
|
users.save("hackers@arangodb.org", ":\\abc'def:foobar@04. x-a");
|
||||||
users.reload();
|
users.reload();
|
||||||
|
|
||||||
arango.reconnect(arango.getEndpoint(), "hackers@arangodb.org", ":\\abc'def:foobar@04. x-a");
|
arango.reconnect(arango.getEndpoint(), db._name(), "hackers@arangodb.org", ":\\abc'def:foobar@04. x-a");
|
||||||
|
|
||||||
// this will issue a request using the new user
|
// this will issue a request using the new user
|
||||||
assertTrue(db._collections().length > 0);
|
assertTrue(db._collections().length > 0);
|
||||||
|
|
||||||
// double check with wrong passwords
|
// double check with wrong passwords
|
||||||
try {
|
try {
|
||||||
arango.reconnect(arango.getEndpoint(), "hackers@arangodb.org", "foobar");
|
arango.reconnect(arango.getEndpoint(), db._name(), "hackers@arangodb.org", "foobar");
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (err1) {
|
catch (err1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
arango.reconnect(arango.getEndpoint(), "hackers@arangodb.org", "\\abc'def: x-a");
|
arango.reconnect(arango.getEndpoint(), db._name(), "hackers@arangodb.org", "\\abc'def: x-a");
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (err2) {
|
catch (err2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
arango.reconnect(arango.getEndpoint(), "hackers@arangodb.org", "");
|
arango.reconnect(arango.getEndpoint(), db._name(), "hackers@arangodb.org", "");
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (err3) {
|
catch (err3) {
|
||||||
|
|
|
@ -151,6 +151,14 @@ ArangoDatabase.prototype._listDatabases = function () {
|
||||||
return LIST_DATABASES();
|
return LIST_DATABASES();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief use a different database
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ArangoDatabase.prototype._useDatabase = function (name) {
|
||||||
|
return USE_DATABASES(name);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @}
|
/// @}
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -57,11 +57,11 @@ function ReplicationSuite () {
|
||||||
var replicatorPassword = "replicator-password";
|
var replicatorPassword = "replicator-password";
|
||||||
|
|
||||||
var connectToMaster = function () {
|
var connectToMaster = function () {
|
||||||
arango.reconnect(masterEndpoint, replicatorUser, replicatorPassword);
|
arango.reconnect(masterEndpoint, db._name(), replicatorUser, replicatorPassword);
|
||||||
};
|
};
|
||||||
|
|
||||||
var connectToSlave = function () {
|
var connectToSlave = function () {
|
||||||
arango.reconnect(slaveEndpoint, "root", "");
|
arango.reconnect(slaveEndpoint, db._name(), "root", "");
|
||||||
};
|
};
|
||||||
|
|
||||||
var collectionChecksum = function (name) {
|
var collectionChecksum = function (name) {
|
||||||
|
|
|
@ -463,11 +463,11 @@ namespace triagens {
|
||||||
// authenticate
|
// authenticate
|
||||||
// .............................................................................
|
// .............................................................................
|
||||||
|
|
||||||
bool auth = this->_server->getHandlerFactory()->authenticateRequest(this->_request);
|
HttpResponse::HttpResponseCode authResult = this->_server->getHandlerFactory()->authenticateRequest(this->_request);
|
||||||
|
|
||||||
// authenticated
|
// authenticated
|
||||||
// or an HTTP OPTIONS request. OPTIONS requests currently go unauthenticated
|
// or an HTTP OPTIONS request. OPTIONS requests currently go unauthenticated
|
||||||
if (auth || this->_requestType == HttpRequest::HTTP_REQUEST_OPTIONS) {
|
if (authResult == HttpResponse::OK || this->_requestType == HttpRequest::HTTP_REQUEST_OPTIONS) {
|
||||||
|
|
||||||
// handle HTTP OPTIONS requests directly
|
// handle HTTP OPTIONS requests directly
|
||||||
if (this->_requestType == HttpRequest::HTTP_REQUEST_OPTIONS) {
|
if (this->_requestType == HttpRequest::HTTP_REQUEST_OPTIONS) {
|
||||||
|
@ -539,6 +539,14 @@ namespace triagens {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// not found
|
||||||
|
else if (authResult == HttpResponse::NOT_FOUND) {
|
||||||
|
HttpResponse response(HttpResponse::NOT_FOUND);
|
||||||
|
|
||||||
|
this->handleResponse(&response);
|
||||||
|
this->resetState();
|
||||||
|
}
|
||||||
|
|
||||||
// not authenticated
|
// not authenticated
|
||||||
else {
|
else {
|
||||||
const string realm = "basic realm=\"" + this->_server->getHandlerFactory()->authenticationRealm(this->_request) + "\"";
|
const string realm = "basic realm=\"" + this->_server->getHandlerFactory()->authenticationRealm(this->_request) + "\"";
|
||||||
|
|
|
@ -143,15 +143,19 @@ pair<size_t, size_t> HttpHandlerFactory::sizeRestrictions () const {
|
||||||
/// disabled authentication etc.
|
/// disabled authentication etc.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool HttpHandlerFactory::authenticateRequest (HttpRequest* request) {
|
HttpResponse::HttpResponseCode HttpHandlerFactory::authenticateRequest (HttpRequest* request) {
|
||||||
RequestContext* rc = request->getRequestContext();
|
RequestContext* rc = request->getRequestContext();
|
||||||
|
|
||||||
if (! rc) {
|
if (! rc) {
|
||||||
if (! setRequestContext(request)) {
|
if (! setRequestContext(request)) {
|
||||||
return false;
|
return HttpResponse::NOT_FOUND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! rc) {
|
||||||
|
return HttpResponse::NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
return rc->authenticate();
|
return rc->authenticate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
#include "Basics/Mutex.h"
|
#include "Basics/Mutex.h"
|
||||||
#include "Basics/ReadWriteLock.h"
|
#include "Basics/ReadWriteLock.h"
|
||||||
|
#include "Rest/HttpResponse.h"
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- forward declarations
|
// --SECTION-- forward declarations
|
||||||
|
@ -183,7 +184,7 @@ namespace triagens {
|
||||||
/// @brief authenticates a new request, wrapper method
|
/// @brief authenticates a new request, wrapper method
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual bool authenticateRequest (HttpRequest * request);
|
virtual HttpResponse::HttpResponseCode authenticateRequest (HttpRequest * request);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief set request context, wrapper method
|
/// @brief set request context, wrapper method
|
||||||
|
|
|
@ -71,7 +71,7 @@ HttpRequest::HttpRequest (ConnectionInfo const& info, char const* header, size_t
|
||||||
_prefix(),
|
_prefix(),
|
||||||
_suffix(),
|
_suffix(),
|
||||||
_version(HTTP_UNKNOWN),
|
_version(HTTP_UNKNOWN),
|
||||||
_dbName(),
|
_databaseName(),
|
||||||
_user(),
|
_user(),
|
||||||
_requestContext(0) {
|
_requestContext(0) {
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ HttpRequest::HttpRequest ()
|
||||||
_prefix(),
|
_prefix(),
|
||||||
_suffix(),
|
_suffix(),
|
||||||
_version(HTTP_UNKNOWN),
|
_version(HTTP_UNKNOWN),
|
||||||
_dbName(),
|
_databaseName(),
|
||||||
_user(),
|
_user(),
|
||||||
_requestContext(0) {
|
_requestContext(0) {
|
||||||
}
|
}
|
||||||
|
@ -589,8 +589,8 @@ void HttpRequest::setRequestType (HttpRequestType newType) {
|
||||||
/// @brief returns the database name
|
/// @brief returns the database name
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
string const& HttpRequest::dbName () const {
|
string const& HttpRequest::databaseName () const {
|
||||||
return _dbName;
|
return _databaseName;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -834,7 +834,7 @@ void HttpRequest::parseHeader (char* ptr, size_t length) {
|
||||||
++q;
|
++q;
|
||||||
}
|
}
|
||||||
|
|
||||||
_dbName = string(pathBegin, q - pathBegin);
|
_databaseName = string(pathBegin, q - pathBegin);
|
||||||
|
|
||||||
pathBegin = q;
|
pathBegin = q;
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,7 +226,7 @@ namespace triagens {
|
||||||
/// @brief returns the database name
|
/// @brief returns the database name
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::string const& dbName () const;
|
std::string const& databaseName () const;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief returns the authenticated user
|
/// @brief returns the authenticated user
|
||||||
|
@ -658,7 +658,7 @@ namespace triagens {
|
||||||
/// @brief database name
|
/// @brief database name
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
string _dbName;
|
string _databaseName;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief authenticated user
|
/// @brief authenticated user
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "Rest/RequestUser.h"
|
#include "Rest/RequestUser.h"
|
||||||
#include "Rest/HttpRequest.h"
|
#include "Rest/HttpRequest.h"
|
||||||
|
#include "Rest/HttpResponse.h"
|
||||||
|
|
||||||
namespace triagens {
|
namespace triagens {
|
||||||
namespace rest {
|
namespace rest {
|
||||||
|
@ -97,7 +98,7 @@ namespace triagens {
|
||||||
/// @brief authenticate user
|
/// @brief authenticate user
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual bool authenticate () = 0;
|
virtual HttpResponse::HttpResponseCode authenticate () = 0;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @}
|
/// @}
|
||||||
|
|
|
@ -52,7 +52,14 @@ namespace triagens {
|
||||||
SimpleHttpClient::SimpleHttpClient (GeneralClientConnection* connection,
|
SimpleHttpClient::SimpleHttpClient (GeneralClientConnection* connection,
|
||||||
double requestTimeout,
|
double requestTimeout,
|
||||||
bool warn) :
|
bool warn) :
|
||||||
SimpleClient(connection, requestTimeout, warn), _result(0), _maxPacketSize(128 * 1024 * 1024) {
|
SimpleClient(connection, requestTimeout, warn),
|
||||||
|
_locationRewriter(),
|
||||||
|
_result(0),
|
||||||
|
_maxPacketSize(128 * 1024 * 1024) {
|
||||||
|
|
||||||
|
// waiting for C++11...
|
||||||
|
_locationRewriter.func = 0;
|
||||||
|
_locationRewriter.data = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleHttpClient::~SimpleHttpClient () {
|
SimpleHttpClient::~SimpleHttpClient () {
|
||||||
|
@ -73,8 +80,8 @@ namespace triagens {
|
||||||
_result = new SimpleHttpResult;
|
_result = new SimpleHttpResult;
|
||||||
_errorMessage = "";
|
_errorMessage = "";
|
||||||
|
|
||||||
// set body to all connections
|
// set body
|
||||||
setRequest(method, location, body, bodyLength, headerFields);
|
setRequest(method, rewriteLocation(location), body, bodyLength, headerFields);
|
||||||
|
|
||||||
double endTime = now() + _requestTimeout;
|
double endTime = now() + _requestTimeout;
|
||||||
double remainingTime = _requestTimeout;
|
double remainingTime = _requestTimeout;
|
||||||
|
|
|
@ -91,6 +91,16 @@ namespace triagens {
|
||||||
const string& username,
|
const string& username,
|
||||||
const string& password);
|
const string& password);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief allows rewriting locations
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void setLocationRewriter (void* data,
|
||||||
|
std::string (*func)(void*, const std::string&)) {
|
||||||
|
_locationRewriter.data = data;
|
||||||
|
_locationRewriter.func = func;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief reset state
|
/// @brief reset state
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -99,6 +109,18 @@ namespace triagens {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief rewrite a location URL
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
string rewriteLocation (const string& location) {
|
||||||
|
if (_locationRewriter.func != 0) {
|
||||||
|
return _locationRewriter.func(_locationRewriter.data, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief get the result
|
/// @brief get the result
|
||||||
/// the caller has to delete the result object
|
/// the caller has to delete the result object
|
||||||
|
@ -148,6 +170,16 @@ namespace triagens {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief struct for rewriting location URLs
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct {
|
||||||
|
void* data;
|
||||||
|
std::string (*func)(void*, const std::string&);
|
||||||
|
}
|
||||||
|
_locationRewriter;
|
||||||
|
|
||||||
uint32_t _nextChunkedSize;
|
uint32_t _nextChunkedSize;
|
||||||
|
|
||||||
SimpleHttpResult* _result;
|
SimpleHttpResult* _result;
|
||||||
|
|
Loading…
Reference in New Issue