1
0
Fork 0

added shared client / admin port

This commit is contained in:
Frank Celler 2012-04-10 23:48:48 +02:00
parent af2902009a
commit 9e87d18161
8 changed files with 132 additions and 54 deletions

View File

@ -50,9 +50,10 @@ using namespace triagens::avocado;
/// @brief constructor /// @brief constructor
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
RestActionHandler::RestActionHandler (HttpRequest* request, TRI_vocbase_t* vocbase) RestActionHandler::RestActionHandler (HttpRequest* request, pair<TRI_vocbase_t*, set<string>*>* data)
: RestVocbaseBaseHandler(request, vocbase), : RestVocbaseBaseHandler(request, data->first),
_action(0) { _action(0),
_allowedQueues(*data->second) {
_action = TRI_LookupActionVocBase(request); _action = TRI_LookupActionVocBase(request);
} }
@ -100,43 +101,61 @@ HttpHandler::status_e RestActionHandler::execute () {
bool res = false; bool res = false;
// extract the sub-request type // need an action
if (_action != 0) { if (_action == 0) {
HttpRequest::HttpRequestType type = request->requestType();
// prepare logging
switch (type) {
case HttpRequest::HTTP_REQUEST_DELETE: task = &logExecute; break;
case HttpRequest::HTTP_REQUEST_GET: task = &logExecute; break;
case HttpRequest::HTTP_REQUEST_POST: task = &logExecute; break;
case HttpRequest::HTTP_REQUEST_PUT: task = &logExecute; break;
case HttpRequest::HTTP_REQUEST_HEAD: task = &logHead; break;
case HttpRequest::HTTP_REQUEST_ILLEGAL: task = &logIllegal; break;
}
_timing << *task;
LOGGER_REQUEST_IN_START_I(_timing);
// execute one of the CRUD methods
switch (type) {
case HttpRequest::HTTP_REQUEST_GET: res = executeAction(); break;
case HttpRequest::HTTP_REQUEST_POST: res = executeAction(); break;
case HttpRequest::HTTP_REQUEST_PUT: res = executeAction(); break;
case HttpRequest::HTTP_REQUEST_DELETE: res = executeAction(); break;
case HttpRequest::HTTP_REQUEST_HEAD: res = executeAction(); break;
default:
res = false;
generateNotImplemented("METHOD");
break;
}
}
else {
string n = request->requestPath(); string n = request->requestPath();
n += StringUtils::join(request->suffix(), "/"); n += StringUtils::join(request->suffix(), "/");
generateNotImplemented(n); generateNotImplemented(n);
} }
else {
// check the permission base on queue name
bool allowed = false;
for (set<string>::iterator i = _allowedQueues.begin(); i != _allowedQueues.end(); ++i) {
if (_action->_queue == *i) {
allowed = true;
break;
}
}
if (! allowed) {
generateForbidden();
}
else {
// extract the sub-request type
HttpRequest::HttpRequestType type = request->requestType();
// prepare logging
switch (type) {
case HttpRequest::HTTP_REQUEST_DELETE: task = &logExecute; break;
case HttpRequest::HTTP_REQUEST_GET: task = &logExecute; break;
case HttpRequest::HTTP_REQUEST_POST: task = &logExecute; break;
case HttpRequest::HTTP_REQUEST_PUT: task = &logExecute; break;
case HttpRequest::HTTP_REQUEST_HEAD: task = &logHead; break;
case HttpRequest::HTTP_REQUEST_ILLEGAL: task = &logIllegal; break;
}
_timing << *task;
LOGGER_REQUEST_IN_START_I(_timing);
// execute one of the CRUD methods
switch (type) {
case HttpRequest::HTTP_REQUEST_GET: res = executeAction(); break;
case HttpRequest::HTTP_REQUEST_POST: res = executeAction(); break;
case HttpRequest::HTTP_REQUEST_PUT: res = executeAction(); break;
case HttpRequest::HTTP_REQUEST_DELETE: res = executeAction(); break;
case HttpRequest::HTTP_REQUEST_HEAD: res = executeAction(); break;
default:
res = false;
generateNotImplemented("METHOD");
break;
}
}
}
_timingResult = res ? RES_ERR : RES_OK; _timingResult = res ? RES_ERR : RES_OK;

View File

@ -69,7 +69,7 @@ namespace triagens {
/// @brief constructor /// @brief constructor
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
RestActionHandler (rest::HttpRequest*, TRI_vocbase_t*); RestActionHandler (rest::HttpRequest*, std::pair<TRI_vocbase_t*, set<string>*>*);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @} /// @}
@ -146,6 +146,12 @@ namespace triagens {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
TRI_action_t const* _action; TRI_action_t const* _action;
////////////////////////////////////////////////////////////////////////////////
/// @brief allowed queues
////////////////////////////////////////////////////////////////////////////////
set<string> const& _allowedQueues;
}; };
} }
} }

View File

@ -283,6 +283,16 @@ void RestVocbaseBaseHandler::generateNotImplemented (string const& path) {
"'" + path + "' not implemented"); "'" + path + "' not implemented");
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief generates forbidden
////////////////////////////////////////////////////////////////////////////////
void RestVocbaseBaseHandler::generateForbidden () {
generateError(HttpResponse::FORBIDDEN,
TRI_ERROR_FORBIDDEN,
"operation forbidden");
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief generates precondition failed /// @brief generates precondition failed
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -199,6 +199,12 @@ namespace triagens {
void generateNotImplemented (string const& path); void generateNotImplemented (string const& path);
////////////////////////////////////////////////////////////////////////////////
/// @brief generates forbidden
////////////////////////////////////////////////////////////////////////////////
void generateForbidden ();
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief generates precondition failed /// @brief generates precondition failed
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -246,8 +246,8 @@ void ActionDispatcherThread::initialise () {
if (_context.IsEmpty()) { if (_context.IsEmpty()) {
LOGGER_FATAL << "cannot initialize V8 engine"; LOGGER_FATAL << "cannot initialize V8 engine";
cerr << "cannot initialize V8 engine\n";
_isolate->Exit(); _isolate->Exit();
TRI_FlushLogging();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -265,9 +265,9 @@ void ActionDispatcherThread::initialise () {
if (! ok) { if (! ok) {
LOGGER_FATAL << "cannot load json utilities from file '" << files[i] << "'"; LOGGER_FATAL << "cannot load json utilities from file '" << files[i] << "'";
cerr << "cannot load json utilities from file '" << files[i] << "'\n";
_context->Exit(); _context->Exit();
_isolate->Exit(); _isolate->Exit();
TRI_FlushLogging();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }

View File

@ -160,7 +160,7 @@ AvocadoServer::AvocadoServer (int argc, char** argv)
_httpServer(0), _httpServer(0),
_adminHttpServer(0), _adminHttpServer(0),
_httpPort("127.0.0.1:8529"), _httpPort("127.0.0.1:8529"),
_adminPort("127.0.0.1:8530"), _adminPort(),
_dispatcherThreads(1), _dispatcherThreads(1),
_startupPath(), _startupPath(),
_startupModules("js/modules"), _startupModules("js/modules"),
@ -562,11 +562,21 @@ int AvocadoServer::startupServer () {
// create a http server and http handler factory // create a http server and http handler factory
// ............................................................................. // .............................................................................
bool useHttpPort = ! _httpPort.empty();
bool useAdminPort = ! _adminPort.empty() && _adminPort != "-";
bool shareAdminPort = useHttpPort && _adminPort.empty();
Scheduler* scheduler = _applicationServer->scheduler(); Scheduler* scheduler = _applicationServer->scheduler();
if (! _httpPort.empty()) { set<string> allowedQueuesHttp;
pair< TRI_vocbase_t*, set<string>* > handlerDataHttp = make_pair(_vocbase, &allowedQueuesHttp);
if (useHttpPort) {
HttpHandlerFactory* factory = new HttpHandlerFactory(); HttpHandlerFactory* factory = new HttpHandlerFactory();
allowedQueuesHttp.insert("STANDARD");
allowedQueuesHttp.insert("CLIENT");
vector<AddressPort> ports; vector<AddressPort> ports;
ports.push_back(AddressPort(_httpPort)); ports.push_back(AddressPort(_httpPort));
@ -574,7 +584,15 @@ int AvocadoServer::startupServer () {
factory->addPrefixHandler(RestVocbaseBaseHandler::DOCUMENT_PATH, RestHandlerCreator<RestDocumentHandler>::createData<TRI_vocbase_t*>, _vocbase); factory->addPrefixHandler(RestVocbaseBaseHandler::DOCUMENT_PATH, RestHandlerCreator<RestDocumentHandler>::createData<TRI_vocbase_t*>, _vocbase);
factory->addPrefixHandler(RestVocbaseBaseHandler::EDGE_PATH, RestHandlerCreator<RestEdgeHandler>::createData<TRI_vocbase_t*>, _vocbase); factory->addPrefixHandler(RestVocbaseBaseHandler::EDGE_PATH, RestHandlerCreator<RestEdgeHandler>::createData<TRI_vocbase_t*>, _vocbase);
factory->addPrefixHandler("/", RestHandlerCreator<RestActionHandler>::createData<TRI_vocbase_t*>, _vocbase);
if (shareAdminPort) {
_applicationAdminServer->addHandlers(factory, "/_admin");
allowedQueuesHttp.insert("SYSTEM");
}
factory->addPrefixHandler("/",
RestHandlerCreator<RestActionHandler>::createData< pair< TRI_vocbase_t*, set<string>* >* >,
(void*) &handlerDataHttp);
_httpServer = _applicationHttpServer->buildServer(new AvocadoHttpServer(scheduler, dispatcher), factory, ports); _httpServer = _applicationHttpServer->buildServer(new AvocadoHttpServer(scheduler, dispatcher), factory, ports);
} }
@ -583,20 +601,29 @@ int AvocadoServer::startupServer () {
// create a http server and http handler factory // create a http server and http handler factory
// ............................................................................. // .............................................................................
if (! _adminPort.empty()) { set<string> allowedQueuesAdmin;
pair< TRI_vocbase_t*, set<string>* > handlerDataAdmin = make_pair(_vocbase, &allowedQueuesAdmin);
if (useAdminPort) {
HttpHandlerFactory* adminFactory = new HttpHandlerFactory(); HttpHandlerFactory* adminFactory = new HttpHandlerFactory();
allowedQueuesAdmin.insert("STANDARD");
allowedQueuesAdmin.insert("CLIENT");
allowedQueuesAdmin.insert("SYSTEM");
vector<AddressPort> adminPorts; vector<AddressPort> adminPorts;
adminPorts.push_back(AddressPort(_adminPort)); adminPorts.push_back(AddressPort(_adminPort));
_applicationAdminServer->addBasicHandlers(adminFactory); _applicationAdminServer->addBasicHandlers(adminFactory);
_applicationAdminServer->addHandlers(adminFactory, "/admin"); _applicationAdminServer->addHandlers(adminFactory, "/_admin");
adminFactory->addPrefixHandler(RestVocbaseBaseHandler::DOCUMENT_PATH, RestHandlerCreator<RestDocumentHandler>::createData<TRI_vocbase_t*>, _vocbase); adminFactory->addPrefixHandler(RestVocbaseBaseHandler::DOCUMENT_PATH, RestHandlerCreator<RestDocumentHandler>::createData<TRI_vocbase_t*>, _vocbase);
adminFactory->addPrefixHandler(RestVocbaseBaseHandler::EDGE_PATH, RestHandlerCreator<RestEdgeHandler>::createData<TRI_vocbase_t*>, _vocbase); adminFactory->addPrefixHandler(RestVocbaseBaseHandler::EDGE_PATH, RestHandlerCreator<RestEdgeHandler>::createData<TRI_vocbase_t*>, _vocbase);
adminFactory->addPrefixHandler("/", RestHandlerCreator<RestActionHandler>::createData<TRI_vocbase_t*>, _vocbase); adminFactory->addPrefixHandler("/",
RestHandlerCreator<RestActionHandler>::createData< pair< TRI_vocbase_t*, set<string>* >* >,
(void*) &handlerDataAdmin);
_adminHttpServer = _applicationHttpServer->buildServer(adminFactory, adminPorts); _adminHttpServer = _applicationHttpServer->buildServer(new AvocadoHttpServer(scheduler, dispatcher), adminFactory, adminPorts);
} }
// ............................................................................. // .............................................................................
@ -605,19 +632,24 @@ int AvocadoServer::startupServer () {
LOGGER_INFO << "AvocadoDB (version " << TRIAGENS_VERSION << ") is ready for business"; LOGGER_INFO << "AvocadoDB (version " << TRIAGENS_VERSION << ") is ready for business";
if (_httpPort.empty()) { if (useHttpPort) {
if (shareAdminPort) {
LOGGER_INFO << "HTTP client/admin port: " << _httpPort;
}
else {
LOGGER_INFO << "HTTP client port: " << _httpPort;
}
}
else {
LOGGER_WARNING << "HTTP client port not defined, maybe you want to use the 'server.http-port' option?"; LOGGER_WARNING << "HTTP client port not defined, maybe you want to use the 'server.http-port' option?";
} }
else {
LOGGER_INFO << "HTTP client port: " << _httpPort;
}
if (_adminPort.empty()) { if (useAdminPort) {
LOGGER_INFO << "HTTP admin port not defined, maybe you want to use the 'server.admin-port' option?";
}
else {
LOGGER_INFO << "HTTP admin port: " << _adminPort; LOGGER_INFO << "HTTP admin port: " << _adminPort;
} }
else if (! shareAdminPort) {
LOGGER_INFO << "HTTP admin port not defined, maybe you want to use the 'server.admin-port' option?";
}
LOGGER_INFO << "Have Fun!"; LOGGER_INFO << "Have Fun!";

View File

@ -199,7 +199,10 @@ namespace triagens {
/// @CMDOPT{--server.http-port @CA{port}} /// @CMDOPT{--server.http-port @CA{port}}
/// ///
/// Specifies the @CA{port} for HTTP requests by clients. This will bind to any /// Specifies the @CA{port} for HTTP requests by clients. This will bind to any
/// address available. /// address available. If you do not specify an admin port, then the http port
/// will serve both client and administration request. If you have
/// higher security requirements, you can use a special administration
/// port.
/// ///
/// @CMDOPT{--server.http-port @CA{address}:@CA{port}} /// @CMDOPT{--server.http-port @CA{address}:@CA{port}}
/// ///

View File

@ -17,7 +17,9 @@ static string JS_common_bootstrap_errors =
" \"ERROR_DEAD_PID\" : { \"code\" : 8, \"message\" : \"dead process identifier\" }, \n" " \"ERROR_DEAD_PID\" : { \"code\" : 8, \"message\" : \"dead process identifier\" }, \n"
" \"ERROR_NOT_IMPLEMENTED\" : { \"code\" : 9, \"message\" : \"not implemented\" }, \n" " \"ERROR_NOT_IMPLEMENTED\" : { \"code\" : 9, \"message\" : \"not implemented\" }, \n"
" \"ERROR_BAD_PARAMETER\" : { \"code\" : 10, \"message\" : \"bad parameter\" }, \n" " \"ERROR_BAD_PARAMETER\" : { \"code\" : 10, \"message\" : \"bad parameter\" }, \n"
" \"ERROR_FORBIDDEN\" : { \"code\" : 11, \"message\" : \"forbidden\" }, \n"
" \"ERROR_HTTP_BAD_PARAMETER\" : { \"code\" : 400, \"message\" : \"bad parameter\" }, \n" " \"ERROR_HTTP_BAD_PARAMETER\" : { \"code\" : 400, \"message\" : \"bad parameter\" }, \n"
" \"ERROR_HTTP_FORBIDDEN\" : { \"code\" : 403, \"message\" : \"forbidden\" }, \n"
" \"ERROR_HTTP_NOT_FOUND\" : { \"code\" : 404, \"message\" : \"not found\" }, \n" " \"ERROR_HTTP_NOT_FOUND\" : { \"code\" : 404, \"message\" : \"not found\" }, \n"
" \"ERROR_HTTP_METHOD_NOT_ALLOWED\" : { \"code\" : 405, \"message\" : \"method not supported\" }, \n" " \"ERROR_HTTP_METHOD_NOT_ALLOWED\" : { \"code\" : 405, \"message\" : \"method not supported\" }, \n"
" \"ERROR_HTTP_SERVER_ERROR\" : { \"code\" : 500, \"message\" : \"internal server error\" }, \n" " \"ERROR_HTTP_SERVER_ERROR\" : { \"code\" : 500, \"message\" : \"internal server error\" }, \n"