diff --git a/arangod/CMakeLists.txt b/arangod/CMakeLists.txt index 3622fc98d9..e6f23f93cc 100644 --- a/arangod/CMakeLists.txt +++ b/arangod/CMakeLists.txt @@ -185,16 +185,17 @@ add_executable(${BIN_ARANGOD} FulltextIndex/fulltext-query.cpp FulltextIndex/fulltext-result.cpp GeoIndex/GeoIndex.cpp - HttpServer/AsyncJobManager.cpp - HttpServer/HttpCommTask.cpp - HttpServer/HttpListenTask.cpp - HttpServer/HttpServer.cpp - HttpServer/HttpServerJob.cpp - HttpServer/HttpsCommTask.cpp - HttpServer/HttpsServer.cpp - HttpServer/RestHandler.cpp - HttpServer/RestHandlerFactory.cpp - HttpServer/PathHandler.cpp + GeneralServer/AsyncJobManager.cpp + GeneralServer/HttpCommTask.cpp + GeneralServer/HttpServerJob.cpp + GeneralServer/GeneralCommTask.cpp + GeneralServer/HttpCommTask.cpp + GeneralServer/HttpsCommTask.cpp + GeneralServer/GeneralListenTask.cpp + GeneralServer/GeneralServer.cpp + GeneralServer/RestHandler.cpp + GeneralServer/RestHandlerFactory.cpp + GeneralServer/PathHandler.cpp Indexes/EdgeIndex.cpp Indexes/FulltextIndex.cpp Indexes/GeoIndex2.cpp diff --git a/arangod/Cluster/HeartbeatThread.cpp b/arangod/Cluster/HeartbeatThread.cpp index 01db65d16b..184f129cff 100644 --- a/arangod/Cluster/HeartbeatThread.cpp +++ b/arangod/Cluster/HeartbeatThread.cpp @@ -39,7 +39,7 @@ #include "Dispatcher/Dispatcher.h" #include "Dispatcher/DispatcherFeature.h" #include "Dispatcher/Job.h" -#include "HttpServer/RestHandlerFactory.h" +#include "GeneralServer/RestHandlerFactory.h" #include "Logger/Logger.h" #include "RestServer/RestServerFeature.h" #include "V8/v8-globals.h" @@ -128,30 +128,30 @@ void HeartbeatThread::runDBServer() { std::function updatePlan = [&](VPackSlice const& result) { - if (!result.isNumber()) { - LOG_TOPIC(ERR, Logger::HEARTBEAT) << "Plan Version is not a number! " - << result.toJson(); - return false; - } - uint64_t version = result.getNumber(); + if (!result.isNumber()) { + LOG_TOPIC(ERR, Logger::HEARTBEAT) << "Plan Version is not a number! " + << result.toJson(); + return false; + } + uint64_t version = result.getNumber(); - bool doSync = false; - { - MUTEX_LOCKER(mutexLocker, _statusLock); - if (version > _desiredVersions.plan) { - _desiredVersions.plan = version; - LOG_TOPIC(DEBUG, Logger::HEARTBEAT) - << "Desired Current Version is now " << _desiredVersions.plan; - doSync = true; - } - } + bool doSync = false; + { + MUTEX_LOCKER(mutexLocker, _statusLock); + if (version > _desiredVersions.plan) { + _desiredVersions.plan = version; + LOG_TOPIC(DEBUG, Logger::HEARTBEAT) << "Desired Current Version is now " + << _desiredVersions.plan; + doSync = true; + } + } - if (doSync) { - syncDBServerStatusQuo(); - } + if (doSync) { + syncDBServerStatusQuo(); + } - return true; - }; + return true; + }; auto planAgencyCallback = std::make_shared( _agency, "Plan/Version", updatePlan, true); @@ -610,14 +610,15 @@ bool HeartbeatThread::syncDBServerStatusQuo() { if (becauseOfCurrent) { ci->invalidateCurrent(); } - + // only warn if the application server is still there and dispatching // should succeed bool warn = false; - application_features::ApplicationServer* server = application_features::ApplicationServer::server; + application_features::ApplicationServer* server = + application_features::ApplicationServer::server; if (server != nullptr) { auto state = server->state(); - warn = (state != application_features::ServerState::IN_STOP && + warn = (state != application_features::ServerState::IN_STOP && state != application_features::ServerState::IN_UNPREPARE && state != application_features::ServerState::STOPPED && state != application_features::ServerState::ABORT); diff --git a/arangod/HttpServer/AsyncJobManager.cpp b/arangod/GeneralServer/AsyncJobManager.cpp similarity index 99% rename from arangod/HttpServer/AsyncJobManager.cpp rename to arangod/GeneralServer/AsyncJobManager.cpp index 29aca92054..5423e0730a 100644 --- a/arangod/HttpServer/AsyncJobManager.cpp +++ b/arangod/GeneralServer/AsyncJobManager.cpp @@ -25,8 +25,8 @@ #include "Basics/ReadLocker.h" #include "Basics/WriteLocker.h" -#include "HttpServer/HttpServerJob.h" -#include "HttpServer/RestHandler.h" +#include "GeneralServer/HttpServerJob.h" +#include "GeneralServer/RestHandler.h" #include "Logger/Logger.h" #include "Rest/GeneralResponse.h" diff --git a/arangod/HttpServer/AsyncJobManager.h b/arangod/GeneralServer/AsyncJobManager.h similarity index 100% rename from arangod/HttpServer/AsyncJobManager.h rename to arangod/GeneralServer/AsyncJobManager.h diff --git a/arangod/HttpServer/HttpCommTask.cpp b/arangod/GeneralServer/GeneralCommTask.cpp similarity index 91% rename from arangod/HttpServer/HttpCommTask.cpp rename to arangod/GeneralServer/GeneralCommTask.cpp index 0d3db02081..0bd2afdd27 100644 --- a/arangod/HttpServer/HttpCommTask.cpp +++ b/arangod/GeneralServer/GeneralCommTask.cpp @@ -22,15 +22,15 @@ /// @author Dr. Frank Celler //////////////////////////////////////////////////////////////////////////////// -#include "HttpCommTask.h" +#include "GeneralCommTask.h" #include "Basics/HybridLogicalClock.h" #include "Basics/MutexLocker.h" #include "Basics/StaticStrings.h" #include "Basics/StringBuffer.h" -#include "HttpServer/HttpServer.h" -#include "HttpServer/RestHandler.h" -#include "HttpServer/RestHandlerFactory.h" +#include "GeneralServer/GeneralServer.h" +#include "GeneralServer/RestHandler.h" +#include "GeneralServer/RestHandlerFactory.h" #include "Logger/Logger.h" #include "RestServer/RestServerFeature.h" #include "Scheduler/Scheduler.h" @@ -45,22 +45,24 @@ using namespace arangodb::rest; /// @brief static initializers //////////////////////////////////////////////////////////////////////////////// -size_t const HttpCommTask::MaximalHeaderSize = 1 * 1024 * 1024; // 1 MB -size_t const HttpCommTask::MaximalBodySize = 512 * 1024 * 1024; // 512 MB -size_t const HttpCommTask::MaximalPipelineSize = 512 * 1024 * 1024; // 512 MB -size_t const HttpCommTask::RunCompactEvery = 500; +size_t const GeneralCommTask::MaximalHeaderSize = 1 * 1024 * 1024; // 1 MB +size_t const GeneralCommTask::MaximalBodySize = 512 * 1024 * 1024; // 512 MB +size_t const GeneralCommTask::MaximalPipelineSize = + 512 * 1024 * 1024; // 512 MB +size_t const GeneralCommTask::RunCompactEvery = 500; //////////////////////////////////////////////////////////////////////////////// /// @brief constructs a new task //////////////////////////////////////////////////////////////////////////////// -HttpCommTask::HttpCommTask(HttpServer* server, TRI_socket_t socket, - ConnectionInfo&& info, double keepAliveTimeout) - : Task("HttpCommTask"), +GeneralCommTask::GeneralCommTask(GeneralServer* server, TRI_socket_t socket, + ConnectionInfo&& info, double keepAliveTimeout) + : Task("GeneralCommTask"), SocketTask(socket, keepAliveTimeout), _connectionInfo(std::move(info)), _server(server), _allowMethodOverride(server->allowMethodOverride()), + _protocol("unknown"), _writeBuffers(), _writeBuffersStats(), _readPosition(0), @@ -97,7 +99,7 @@ HttpCommTask::HttpCommTask(HttpServer* server, TRI_socket_t socket, /// @brief destructs a task //////////////////////////////////////////////////////////////////////////////// -HttpCommTask::~HttpCommTask() { +GeneralCommTask::~GeneralCommTask() { LOG(TRACE) << "connection closed, client " << TRI_get_fd_or_handle_of_socket(_commSocket); @@ -114,7 +116,7 @@ HttpCommTask::~HttpCommTask() { delete _request; } -void HttpCommTask::handleResponse(HttpResponse* response) { +void GeneralCommTask::handleResponse(HttpResponse* response) { _requestPending = false; _isChunked = false; _startThread = false; @@ -126,16 +128,16 @@ void HttpCommTask::handleResponse(HttpResponse* response) { } } -void HttpCommTask::handleSimpleError(GeneralResponse::ResponseCode code) { +void GeneralCommTask::handleSimpleError(GeneralResponse::ResponseCode code) { HttpResponse response(code); resetState(true); addResponse(&response); } -void HttpCommTask::handleSimpleError(GeneralResponse::ResponseCode responseCode, - int errorNum, - std::string const& errorMessage) { +void GeneralCommTask::handleSimpleError( + GeneralResponse::ResponseCode responseCode, int errorNum, + std::string const& errorMessage) { HttpResponse response(responseCode); VPackBuilder builder; @@ -147,7 +149,8 @@ void HttpCommTask::handleSimpleError(GeneralResponse::ResponseCode responseCode, builder.close(); try { - response.setPayload(_request, builder.slice(), true, VPackOptions::Defaults); + response.setPayload(_request, builder.slice(), true, + VPackOptions::Defaults); clearRequest(); handleResponse(&response); @@ -157,7 +160,7 @@ void HttpCommTask::handleSimpleError(GeneralResponse::ResponseCode responseCode, } } -GeneralResponse::ResponseCode HttpCommTask::authenticateRequest() { +GeneralResponse::ResponseCode GeneralCommTask::authenticateRequest() { auto context = (_request == nullptr) ? nullptr : _request->requestContext(); if (context == nullptr && _request != nullptr) { @@ -181,7 +184,7 @@ GeneralResponse::ResponseCode HttpCommTask::authenticateRequest() { /// @brief reads data from the socket //////////////////////////////////////////////////////////////////////////////// -bool HttpCommTask::processRead() { +bool GeneralCommTask::processRead() { if (_requestPending || _readBuffer->c_str() == nullptr) { return false; } @@ -296,7 +299,7 @@ bool HttpCommTask::processRead() { // update the connection information, i. e. client and server addresses // and ports - _request->setProtocol(_server->protocol()); + _request->setProtocol(_protocol); LOG(TRACE) << "server port " << _connectionInfo.serverPort << ", client port " << _connectionInfo.clientPort; @@ -321,10 +324,11 @@ bool HttpCommTask::processRead() { // if the request asks to allow credentials, we'll check against the // configured whitelist of origins - std::vector const& accessControlAllowOrigins = _server->trustedOrigins(); + std::vector const& accessControlAllowOrigins = + _server->trustedOrigins(); if (StringUtils::boolean(allowCredentials) && - !accessControlAllowOrigins.empty()) { + !accessControlAllowOrigins.empty()) { if (accessControlAllowOrigins[0] == "*") { // special case: allow everything _denyCredentials = false; @@ -332,10 +336,14 @@ bool HttpCommTask::processRead() { // copy origin string if (_origin[_origin.size() - 1] == '/') { // strip trailing slash - auto result = std::find(accessControlAllowOrigins.begin(), accessControlAllowOrigins.end(), _origin.substr(0, _origin.size() - 1)); + auto result = std::find(accessControlAllowOrigins.begin(), + accessControlAllowOrigins.end(), + _origin.substr(0, _origin.size() - 1)); _denyCredentials = (result == accessControlAllowOrigins.end()); } else { - auto result = std::find(accessControlAllowOrigins.begin(), accessControlAllowOrigins.end(), _origin); + auto result = + std::find(accessControlAllowOrigins.begin(), + accessControlAllowOrigins.end(), _origin); _denyCredentials = (result == accessControlAllowOrigins.end()); } } else { @@ -545,8 +553,7 @@ bool HttpCommTask::processRead() { // not authenticated else { HttpResponse response(GeneralResponse::ResponseCode::UNAUTHORIZED); - std::string realm = - "Bearer token_type=\"JWT\", realm=\"ArangoDB\""; + std::string realm = "Bearer token_type=\"JWT\", realm=\"ArangoDB\""; response.setHeaderNC(StaticStrings::WwwAuthenticate, std::move(realm)); @@ -561,7 +568,7 @@ bool HttpCommTask::processRead() { /// @brief sends more chunked data //////////////////////////////////////////////////////////////////////////////// -void HttpCommTask::sendChunk(StringBuffer* buffer) { +void GeneralCommTask::sendChunk(StringBuffer* buffer) { if (_isChunked) { TRI_ASSERT(buffer != nullptr); @@ -578,7 +585,7 @@ void HttpCommTask::sendChunk(StringBuffer* buffer) { /// @brief chunking is finished //////////////////////////////////////////////////////////////////////////////// -void HttpCommTask::finishedChunked() { +void GeneralCommTask::finishedChunked() { auto buffer = std::make_unique(TRI_UNKNOWN_MEM_ZONE, 6, true); buffer->appendText(TRI_CHAR_LENGTH_PAIR("0\r\n\r\n")); buffer->ensureNullTerminated(); @@ -599,7 +606,7 @@ void HttpCommTask::finishedChunked() { /// @brief task set up complete //////////////////////////////////////////////////////////////////////////////// -void HttpCommTask::setupDone() { +void GeneralCommTask::setupDone() { _setupDone.store(true, std::memory_order_relaxed); } @@ -607,7 +614,7 @@ void HttpCommTask::setupDone() { /// @brief reads data from the socket //////////////////////////////////////////////////////////////////////////////// -void HttpCommTask::addResponse(HttpResponse* response) { +void GeneralCommTask::addResponse(HttpResponse* response) { // CORS response handling if (!_origin.empty()) { // the request contained an Origin header. We have to send back the @@ -706,7 +713,7 @@ void HttpCommTask::addResponse(HttpResponse* response) { /// check the content-length header of a request and fail it is broken //////////////////////////////////////////////////////////////////////////////// -bool HttpCommTask::checkContentLength(bool expectContentLength) { +bool GeneralCommTask::checkContentLength(bool expectContentLength) { int64_t const bodyLength = _request->contentLength(); if (bodyLength < 0) { @@ -749,7 +756,7 @@ bool HttpCommTask::checkContentLength(bool expectContentLength) { /// @brief fills the write buffer //////////////////////////////////////////////////////////////////////////////// -void HttpCommTask::fillWriteBuffer() { +void GeneralCommTask::fillWriteBuffer() { if (!hasWriteBuffer() && !_writeBuffers.empty()) { StringBuffer* buffer = _writeBuffers.front(); _writeBuffers.pop_front(); @@ -767,7 +774,7 @@ void HttpCommTask::fillWriteBuffer() { /// @brief handles CORS options //////////////////////////////////////////////////////////////////////////////// -void HttpCommTask::processCorsOptions() { +void GeneralCommTask::processCorsOptions() { HttpResponse response(GeneralResponse::ResponseCode::OK); response.setHeaderNC(StaticStrings::Allow, StaticStrings::CorsMethods); @@ -807,7 +814,7 @@ void HttpCommTask::processCorsOptions() { /// @brief processes a request //////////////////////////////////////////////////////////////////////////////// -void HttpCommTask::processRequest() { +void GeneralCommTask::processRequest() { // check for deflate bool found; std::string const& acceptEncoding = @@ -837,10 +844,11 @@ void HttpCommTask::processRequest() { } // check for an HLC time stamp - std::string const& timeStamp = _request->header(StaticStrings::HLCHeader, found); + std::string const& timeStamp = + _request->header(StaticStrings::HLCHeader, found); if (found) { - uint64_t timeStampInt - = arangodb::basics::HybridLogicalClock::decodeTimeStampWithCheck( + uint64_t timeStampInt = + arangodb::basics::HybridLogicalClock::decodeTimeStampWithCheck( timeStamp); if (timeStampInt != 0) { TRI_HybridLogicalClock(timeStampInt); @@ -872,7 +880,8 @@ void HttpCommTask::processRequest() { if (_request != nullptr) { bool found; - std::string const& startThread = _request->header(StaticStrings::StartThread, found); + std::string const& startThread = + _request->header(StaticStrings::StartThread, found); if (found) { _startThread = StringUtils::boolean(startThread); @@ -927,7 +936,7 @@ void HttpCommTask::processRequest() { /// @brief clears the request object //////////////////////////////////////////////////////////////////////////////// -void HttpCommTask::clearRequest() { +void GeneralCommTask::clearRequest() { delete _request; _request = nullptr; } @@ -939,7 +948,7 @@ void HttpCommTask::clearRequest() { /// prematurely //////////////////////////////////////////////////////////////////////////////// -void HttpCommTask::resetState(bool close) { +void GeneralCommTask::resetState(bool close) { if (close) { clearRequest(); @@ -985,7 +994,7 @@ void HttpCommTask::resetState(bool close) { _startThread = false; } -bool HttpCommTask::setup(Scheduler* scheduler, EventLoop loop) { +bool GeneralCommTask::setup(Scheduler* scheduler, EventLoop loop) { bool ok = SocketTask::setup(scheduler, loop); if (!ok) { @@ -1000,9 +1009,9 @@ bool HttpCommTask::setup(Scheduler* scheduler, EventLoop loop) { return true; } -void HttpCommTask::cleanup() { SocketTask::cleanup(); } +void GeneralCommTask::cleanup() { SocketTask::cleanup(); } -bool HttpCommTask::handleEvent(EventToken token, EventType events) { +bool GeneralCommTask::handleEvent(EventToken token, EventType events) { bool result = SocketTask::handleEvent(token, events); if (_clientClosed) { @@ -1012,7 +1021,7 @@ bool HttpCommTask::handleEvent(EventToken token, EventType events) { return result; } -void HttpCommTask::signalTask(TaskData* data) { +void GeneralCommTask::signalTask(TaskData* data) { // data response if (data->_type == TaskData::TASK_DATA_RESPONSE) { data->RequestStatisticsAgent::transferTo(this); @@ -1064,7 +1073,7 @@ void HttpCommTask::signalTask(TaskData* data) { } } -bool HttpCommTask::handleRead() { +bool GeneralCommTask::handleRead() { bool res = true; if (!_setupDone.load(std::memory_order_relaxed)) { @@ -1097,7 +1106,7 @@ bool HttpCommTask::handleRead() { return res; } -void HttpCommTask::completedWriteBuffer() { +void GeneralCommTask::completedWriteBuffer() { _writeBuffer = nullptr; _writeLength = 0; @@ -1117,7 +1126,7 @@ void HttpCommTask::completedWriteBuffer() { } } -void HttpCommTask::handleTimeout() { +void GeneralCommTask::handleTimeout() { _clientClosed = true; _server->handleCommunicationClosed(this); } diff --git a/arangod/HttpServer/HttpCommTask.h b/arangod/GeneralServer/GeneralCommTask.h similarity index 91% rename from arangod/HttpServer/HttpCommTask.h rename to arangod/GeneralServer/GeneralCommTask.h index 7e6de125f7..8a47c75f41 100644 --- a/arangod/HttpServer/HttpCommTask.h +++ b/arangod/GeneralServer/GeneralCommTask.h @@ -38,11 +38,11 @@ class HttpRequest; class HttpResponse; namespace rest { -class HttpServer; +class GeneralServer; -class HttpCommTask : public SocketTask, public RequestStatisticsAgent { - HttpCommTask(HttpCommTask const&) = delete; - HttpCommTask const& operator=(HttpCommTask const&) = delete; +class GeneralCommTask : public SocketTask, public RequestStatisticsAgent { + GeneralCommTask(GeneralCommTask const&) = delete; + GeneralCommTask const& operator=(GeneralCommTask const&) = delete; public: static size_t const MaximalHeaderSize; @@ -51,11 +51,11 @@ class HttpCommTask : public SocketTask, public RequestStatisticsAgent { static size_t const RunCompactEvery; public: - HttpCommTask(HttpServer*, TRI_socket_t, ConnectionInfo&&, - double keepAliveTimeout); + GeneralCommTask(GeneralServer*, TRI_socket_t, ConnectionInfo&&, + double keepAliveTimeout); protected: - ~HttpCommTask(); + ~GeneralCommTask(); public: // return whether or not the task desires to start a dispatcher thread @@ -128,11 +128,13 @@ class HttpCommTask : public SocketTask, public RequestStatisticsAgent { ConnectionInfo _connectionInfo; // the underlying server - HttpServer* const _server; + GeneralServer* const _server; // allow method override bool _allowMethodOverride; + char const* _protocol; + private: // write buffers std::deque _writeBuffers; @@ -169,7 +171,7 @@ class HttpCommTask : public SocketTask, public RequestStatisticsAgent { // true if within a chunked response bool _isChunked; - + ////////////////////////////////////////////////////////////////////////////// /// @brief start a separate thread if the task is added to the dispatcher? ////////////////////////////////////////////////////////////////////////////// @@ -205,8 +207,9 @@ class HttpCommTask : public SocketTask, public RequestStatisticsAgent { // authentication real std::string const _authenticationRealm; -}; -} -} + +}; // Commontask +} // rest +} // arango #endif diff --git a/arangod/GeneralServer/GeneralDefinitions.h b/arangod/GeneralServer/GeneralDefinitions.h new file mode 100644 index 0000000000..7d14096f2d --- /dev/null +++ b/arangod/GeneralServer/GeneralDefinitions.h @@ -0,0 +1,9 @@ +#ifndef ARANGOD_GENERALSERVER_GENERALDEFINITONS_H +#define ARANGOD_GENERALSERVER_GENERALDEFINITONS_H 1 + +namespace arangodb { +namespace rest { +enum class ConnectionType { HTTP, HTTPS, VPP, VPPS }; +} // rest +} // arangodb +#endif diff --git a/arangod/HttpServer/HttpListenTask.cpp b/arangod/GeneralServer/GeneralListenTask.cpp similarity index 71% rename from arangod/HttpServer/HttpListenTask.cpp rename to arangod/GeneralServer/GeneralListenTask.cpp index f10c1a4ed5..f668d7beb2 100644 --- a/arangod/HttpServer/HttpListenTask.cpp +++ b/arangod/GeneralServer/GeneralListenTask.cpp @@ -22,9 +22,9 @@ /// @author Achim Brandt //////////////////////////////////////////////////////////////////////////////// -#include "HttpListenTask.h" +#include "GeneralListenTask.h" -#include "HttpServer/HttpServer.h" +#include "GeneralServer/GeneralServer.h" using namespace arangodb; using namespace arangodb::rest; @@ -33,11 +33,14 @@ using namespace arangodb::rest; /// @brief listen to given port //////////////////////////////////////////////////////////////////////////////// -HttpListenTask::HttpListenTask(HttpServer* server, Endpoint* endpoint) - : Task("HttpListenTask"), ListenTask(endpoint), _server(server) {} +GeneralListenTask::GeneralListenTask(GeneralServer* server, Endpoint* endpoint, + ConnectionType connectionType) + : Task("GeneralListenTask"), + ListenTask(endpoint), + _server(server), + _connectionType(connectionType) {} -bool HttpListenTask::handleConnected(TRI_socket_t s, - ConnectionInfo&& info) { - _server->handleConnected(s, std::move(info)); +bool GeneralListenTask::handleConnected(TRI_socket_t s, ConnectionInfo&& info) { + _server->handleConnected(s, std::move(info), _connectionType); return true; } diff --git a/arangod/HttpServer/HttpListenTask.h b/arangod/GeneralServer/GeneralListenTask.h similarity index 82% rename from arangod/HttpServer/HttpListenTask.h rename to arangod/GeneralServer/GeneralListenTask.h index 2713c97463..b60d4f0605 100644 --- a/arangod/HttpServer/HttpListenTask.h +++ b/arangod/GeneralServer/GeneralListenTask.h @@ -26,27 +26,29 @@ #define ARANGOD_HTTP_SERVER_HTTP_LISTEN_TASK_H 1 #include "Scheduler/ListenTask.h" +#include "GeneralServer/GeneralDefinitions.h" namespace arangodb { class Endpoint; namespace rest { -class HttpServer; +class GeneralServer; //////////////////////////////////////////////////////////////////////////////// /// @brief task used to establish connections //////////////////////////////////////////////////////////////////////////////// -class HttpListenTask : public ListenTask { - HttpListenTask(HttpListenTask const&) = delete; - HttpListenTask& operator=(HttpListenTask const&) = delete; +class GeneralListenTask : public ListenTask { + GeneralListenTask(GeneralListenTask const&) = delete; + GeneralListenTask& operator=(GeneralListenTask const&) = delete; public: ////////////////////////////////////////////////////////////////////////////// /// @brief listen to given port ////////////////////////////////////////////////////////////////////////////// - HttpListenTask(HttpServer* server, Endpoint* endpoint); + GeneralListenTask(GeneralServer* server, Endpoint* endpoint, + ConnectionType connectionType); protected: bool handleConnected(TRI_socket_t s, ConnectionInfo&& info) override; @@ -56,7 +58,8 @@ class HttpListenTask : public ListenTask { /// @brief underlying general server ////////////////////////////////////////////////////////////////////////////// - HttpServer* _server; + GeneralServer* _server; + ConnectionType _connectionType; }; } } diff --git a/arangod/HttpServer/HttpServer.cpp b/arangod/GeneralServer/GeneralServer.cpp similarity index 72% rename from arangod/HttpServer/HttpServer.cpp rename to arangod/GeneralServer/GeneralServer.cpp index d1837e6efa..23c6fa78c7 100644 --- a/arangod/HttpServer/HttpServer.cpp +++ b/arangod/GeneralServer/GeneralServer.cpp @@ -22,18 +22,18 @@ /// @author Achim Brandt //////////////////////////////////////////////////////////////////////////////// -#include "HttpServer.h" +#include "GeneralServer.h" #include "Basics/MutexLocker.h" #include "Basics/WorkMonitor.h" #include "Dispatcher/Dispatcher.h" #include "Dispatcher/DispatcherFeature.h" #include "Endpoint/EndpointList.h" -#include "HttpServer/AsyncJobManager.h" -#include "HttpServer/HttpCommTask.h" -#include "HttpServer/HttpListenTask.h" -#include "HttpServer/HttpServerJob.h" -#include "HttpServer/RestHandler.h" +#include "GeneralServer/AsyncJobManager.h" +#include "GeneralServer/GeneralCommTask.h" +#include "GeneralServer/GeneralListenTask.h" +#include "GeneralServer/HttpServerJob.h" +#include "GeneralServer/RestHandler.h" #include "Logger/Logger.h" #include "RestServer/RestServerFeature.h" #include "Scheduler/ListenTask.h" @@ -48,7 +48,7 @@ using namespace arangodb::rest; /// @brief destroys an endpoint server //////////////////////////////////////////////////////////////////////////////// -int HttpServer::sendChunk(uint64_t taskId, std::string const& data) { +int GeneralServer::sendChunk(uint64_t taskId, std::string const& data) { auto taskData = std::make_unique(); taskData->_taskId = taskId; @@ -65,37 +65,51 @@ int HttpServer::sendChunk(uint64_t taskId, std::string const& data) { /// @brief constructs a new general server with dispatcher and job manager //////////////////////////////////////////////////////////////////////////////// -HttpServer::HttpServer( - double keepAliveTimeout, - bool allowMethodOverride, - std::vector const& accessControlAllowOrigins) +GeneralServer::GeneralServer( + double keepAliveTimeout, bool allowMethodOverride, + std::vector const& accessControlAllowOrigins, SSL_CTX* ctx) : _listenTasks(), _endpointList(nullptr), _commTasks(), _keepAliveTimeout(keepAliveTimeout), _allowMethodOverride(allowMethodOverride), - _accessControlAllowOrigins(accessControlAllowOrigins) {} - + _accessControlAllowOrigins(accessControlAllowOrigins), + _ctx(ctx), + _verificationMode(SSL_VERIFY_NONE), + _verificationCallback(nullptr), + _sslAllowed(ctx != nullptr) {} //////////////////////////////////////////////////////////////////////////////// /// @brief destructs a general server //////////////////////////////////////////////////////////////////////////////// -HttpServer::~HttpServer() { stopListening(); } +GeneralServer::~GeneralServer() { stopListening(); } //////////////////////////////////////////////////////////////////////////////// /// @brief generates a suitable communication task //////////////////////////////////////////////////////////////////////////////// -HttpCommTask* HttpServer::createCommTask(TRI_socket_t s, - ConnectionInfo&& info) { - return new HttpCommTask(this, s, std::move(info), _keepAliveTimeout); +GeneralCommTask* GeneralServer::createCommTask(TRI_socket_t s, + ConnectionInfo&& info, + ConnectionType conntype) { + switch (conntype) { + case ConnectionType::VPPS: + return new HttpCommTask(this, s, std::move(info), _keepAliveTimeout); + case ConnectionType::VPP: + return new HttpCommTask(this, s, std::move(info), _keepAliveTimeout); + case ConnectionType::HTTPS: + // check _ctx and friends? REVIEW + return new HttpsCommTask(this, s, std::move(info), _keepAliveTimeout, + _ctx, _verificationMode, _verificationCallback); + default: + return new HttpCommTask(this, s, std::move(info), _keepAliveTimeout); + } } //////////////////////////////////////////////////////////////////////////////// /// @brief add the endpoint list //////////////////////////////////////////////////////////////////////////////// -void HttpServer::setEndpointList(EndpointList const* list) { +void GeneralServer::setEndpointList(EndpointList const* list) { _endpointList = list; } @@ -103,11 +117,8 @@ void HttpServer::setEndpointList(EndpointList const* list) { /// @brief starts listening //////////////////////////////////////////////////////////////////////////////// -void HttpServer::startListening() { - auto endpoints = - _endpointList->matching(Endpoint::TransportType::HTTP, encryptionType()); - - for (auto& it : endpoints) { +void GeneralServer::startListening() { + for (auto& it : _endpointList->allEndpoints()) { LOG(TRACE) << "trying to bind to endpoint '" << it.first << "' for requests"; @@ -118,7 +129,8 @@ void HttpServer::startListening() { } else { LOG(FATAL) << "failed to bind to endpoint '" << it.first << "'. Please check whether another instance is already " - "running using this endpoint and review your endpoints configuration."; + "running using this endpoint and review your endpoints " + "configuration."; FATAL_ERROR_EXIT(); } } @@ -128,7 +140,7 @@ void HttpServer::startListening() { /// @brief stops listening //////////////////////////////////////////////////////////////////////////////// -void HttpServer::stopListening() { +void GeneralServer::stopListening() { for (auto& task : _listenTasks) { SchedulerFeature::SCHEDULER->destroyTask(task); } @@ -140,9 +152,9 @@ void HttpServer::stopListening() { /// @brief removes all listen and comm tasks //////////////////////////////////////////////////////////////////////////////// -void HttpServer::stop() { +void GeneralServer::stop() { while (true) { - HttpCommTask* task = nullptr; + GeneralCommTask* task = nullptr; { MUTEX_LOCKER(mutexLocker, _commTasksLock); @@ -163,8 +175,9 @@ void HttpServer::stop() { /// @brief handles connection request //////////////////////////////////////////////////////////////////////////////// -void HttpServer::handleConnected(TRI_socket_t s, ConnectionInfo&& info) { - HttpCommTask* task = createCommTask(s, std::move(info)); +void GeneralServer::handleConnected(TRI_socket_t s, ConnectionInfo&& info, + ConnectionType connectionType) { + GeneralCommTask* task = createCommTask(s, std::move(info), connectionType); try { MUTEX_LOCKER(mutexLocker, _commTasksLock); @@ -184,7 +197,7 @@ void HttpServer::handleConnected(TRI_socket_t s, ConnectionInfo&& info) { /// @brief handles a connection close //////////////////////////////////////////////////////////////////////////////// -void HttpServer::handleCommunicationClosed(HttpCommTask* task) { +void GeneralServer::handleCommunicationClosed(GeneralCommTask* task) { MUTEX_LOCKER(mutexLocker, _commTasksLock); _commTasks.erase(task); } @@ -193,7 +206,7 @@ void HttpServer::handleCommunicationClosed(HttpCommTask* task) { /// @brief handles a connection failure //////////////////////////////////////////////////////////////////////////////// -void HttpServer::handleCommunicationFailure(HttpCommTask* task) { +void GeneralServer::handleCommunicationFailure(GeneralCommTask* task) { MUTEX_LOCKER(mutexLocker, _commTasksLock); _commTasks.erase(task); } @@ -202,9 +215,9 @@ void HttpServer::handleCommunicationFailure(HttpCommTask* task) { /// @brief create a job for asynchronous execution (using the dispatcher) //////////////////////////////////////////////////////////////////////////////// -bool HttpServer::handleRequestAsync(HttpCommTask* task, - WorkItem::uptr& handler, - uint64_t* jobId) { +bool GeneralServer::handleRequestAsync(GeneralCommTask* task, + WorkItem::uptr& handler, + uint64_t* jobId) { bool startThread = task->startThread(); // extract the coordinator flag @@ -248,8 +261,8 @@ bool HttpServer::handleRequestAsync(HttpCommTask* task, /// @brief executes the handler directly or add it to the queue //////////////////////////////////////////////////////////////////////////////// -bool HttpServer::handleRequest(HttpCommTask* task, - WorkItem::uptr& handler) { +bool GeneralServer::handleRequest(GeneralCommTask* task, + WorkItem::uptr& handler) { // direct handlers if (handler->isDirect()) { HandlerWorkStack work(handler); @@ -264,7 +277,7 @@ bool HttpServer::handleRequest(HttpCommTask* task, std::unique_ptr job = std::make_unique(this, handler); task->RequestStatisticsAgent::transferTo(job.get()); - LOG(TRACE) << "HttpCommTask " << (void*)task << " created HttpServerJob " + LOG(TRACE) << "GeneralCommTask " << (void*)task << " created HttpServerJob " << (void*)job.get(); // add the job to the dispatcher @@ -278,8 +291,32 @@ bool HttpServer::handleRequest(HttpCommTask* task, /// @brief opens a listen port //////////////////////////////////////////////////////////////////////////////// -bool HttpServer::openEndpoint(Endpoint* endpoint) { - ListenTask* task = new HttpListenTask(this, endpoint); +bool GeneralServer::openEndpoint(Endpoint* endpoint) { + ConnectionType connectionType; + + if (endpoint->transport() == Endpoint::TransportType::HTTP) { + if (endpoint->encryption() == Endpoint::EncryptionType::SSL) { + if (!_sslAllowed) { // we should not end up here + LOG(FATAL) << "no ssl context"; + FATAL_ERROR_EXIT(); + } + connectionType = ConnectionType::HTTPS; + } else { + connectionType = ConnectionType::HTTP; + } + } else { + if (endpoint->encryption() == Endpoint::EncryptionType::SSL) { + if (!_sslAllowed) { // we should not end up here + LOG(FATAL) << "no ssl context"; + FATAL_ERROR_EXIT(); + } + connectionType = ConnectionType::VPPS; + } else { + connectionType = ConnectionType::VPP; + } + } + + ListenTask* task = new GeneralListenTask(this, endpoint, connectionType); // ................................................................... // For some reason we have failed in our endeavor to bind to the socket - @@ -305,8 +342,8 @@ bool HttpServer::openEndpoint(Endpoint* endpoint) { /// @brief handle request directly //////////////////////////////////////////////////////////////////////////////// -void HttpServer::handleRequestDirectly(RestHandler* handler, - HttpCommTask* task) { +void GeneralServer::handleRequestDirectly(RestHandler* handler, + GeneralCommTask* task) { task->RequestStatisticsAgent::transferTo(handler); RestHandler::status result = handler->executeFull(); handler->RequestStatisticsAgent::transferTo(task); diff --git a/arangod/HttpServer/HttpServer.h b/arangod/GeneralServer/GeneralServer.h similarity index 60% rename from arangod/HttpServer/HttpServer.h rename to arangod/GeneralServer/GeneralServer.h index d5b9a34641..6e907c76ca 100644 --- a/arangod/HttpServer/HttpServer.h +++ b/arangod/GeneralServer/GeneralServer.h @@ -26,11 +26,14 @@ #ifndef ARANGOD_HTTP_SERVER_HTTP_SERVER_H #define ARANGOD_HTTP_SERVER_HTTP_SERVER_H 1 +#include "GeneralServer/GeneralDefinitions.h" #include "Scheduler/TaskManager.h" - #include "Basics/Mutex.h" #include "Endpoint/ConnectionInfo.h" -#include "HttpServer/RestHandler.h" +#include "GeneralServer/RestHandler.h" +#include "GeneralServer/HttpCommTask.h" +#include "GeneralServer/HttpsCommTask.h" +#include namespace arangodb { class EndpointList; @@ -39,46 +42,45 @@ namespace rest { class AsyncJobManager; class Dispatcher; -class HttpCommTask; +class GeneralCommTask; class HttpServerJob; class Job; class ListenTask; class RestHandlerFactory; -class HttpServer : protected TaskManager { - HttpServer(HttpServer const&) = delete; - HttpServer const& operator=(HttpServer const&) = delete; +class GeneralServer : protected TaskManager { + GeneralServer(GeneralServer const&) = delete; + GeneralServer const& operator=(GeneralServer const&) = delete; public: // destroys an endpoint server static int sendChunk(uint64_t, std::string const&); public: - HttpServer(double keepAliveTimeout, - bool allowMethodOverride, - std::vector const& accessControlAllowOrigins); - virtual ~HttpServer(); + GeneralServer(double keepAliveTimeout, bool allowMethodOverride, + std::vector const& accessControlAllowOrigins, + SSL_CTX* ctx = nullptr); + virtual ~GeneralServer(); public: // returns the protocol - virtual char const* protocol() const { return "http"; } - - // returns the encryption to be used - virtual Endpoint::EncryptionType encryptionType() const { - return Endpoint::EncryptionType::NONE; - } + // virtual char const* protocol() const { return "http"; } // check, if we allow a method override - bool allowMethodOverride() { - return _allowMethodOverride; - } + bool allowMethodOverride() { return _allowMethodOverride; } // generates a suitable communication task - virtual HttpCommTask* createCommTask(TRI_socket_t, ConnectionInfo&&); + virtual GeneralCommTask* createCommTask( + TRI_socket_t, ConnectionInfo&&, ConnectionType = ConnectionType::HTTP); + + void setVerificationMode(int mode) { _verificationMode = mode; } + void setVerificationCallback(int (*func)(int, X509_STORE_CTX*)) { + _verificationCallback = func; + } public: - // list of trusted origin urls for CORS - std::vector const& trustedOrigins() const { + // list of trusted origin urls for CORS + std::vector const& trustedOrigins() const { return _accessControlAllowOrigins; } @@ -95,26 +97,27 @@ class HttpServer : protected TaskManager { void stop(); // handles connection request - void handleConnected(TRI_socket_t s, ConnectionInfo&& info); + void handleConnected(TRI_socket_t s, ConnectionInfo&& info, ConnectionType); // handles a connection close - void handleCommunicationClosed(HttpCommTask*); + void handleCommunicationClosed(GeneralCommTask*); // handles a connection failure - void handleCommunicationFailure(HttpCommTask*); + void handleCommunicationFailure(GeneralCommTask*); // creates a job for asynchronous execution - bool handleRequestAsync(HttpCommTask*, arangodb::WorkItem::uptr&, + bool handleRequestAsync(GeneralCommTask*, + arangodb::WorkItem::uptr&, uint64_t* jobId); // executes the handler directly or add it to the queue - bool handleRequest(HttpCommTask*, arangodb::WorkItem::uptr&); + bool handleRequest(GeneralCommTask*, arangodb::WorkItem::uptr&); protected: // Handler, Job, and Task tuple struct handler_task_job_t { RestHandler* _handler; - HttpCommTask* _task; + GeneralCommTask* _task; HttpServerJob* _job; }; @@ -123,10 +126,10 @@ class HttpServer : protected TaskManager { bool openEndpoint(Endpoint* endpoint); // handle request directly - void handleRequestDirectly(RestHandler* handler, HttpCommTask* task); + void handleRequestDirectly(RestHandler* handler, GeneralCommTask* task); // registers a task - void registerHandler(RestHandler* handler, HttpCommTask* task); + void registerHandler(RestHandler* handler, GeneralCommTask* task); protected: // active listen tasks @@ -139,16 +142,22 @@ class HttpServer : protected TaskManager { arangodb::Mutex _commTasksLock; // active comm tasks - std::unordered_set _commTasks; + std::unordered_set _commTasks; // keep-alive timeout double _keepAliveTimeout; // allow to override the method bool _allowMethodOverride; - - // list of trusted origin urls for CORS + + // list of trusted origin urls for CORS std::vector const _accessControlAllowOrigins; + + private: + SSL_CTX* _ctx; + int _verificationMode; + int (*_verificationCallback)(int, X509_STORE_CTX*); + bool _sslAllowed; }; } } diff --git a/arangod/GeneralServer/HttpCommTask.cpp b/arangod/GeneralServer/HttpCommTask.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/arangod/GeneralServer/HttpCommTask.h b/arangod/GeneralServer/HttpCommTask.h new file mode 100644 index 0000000000..e3e34d7e51 --- /dev/null +++ b/arangod/GeneralServer/HttpCommTask.h @@ -0,0 +1,20 @@ +#ifndef ARANGOD_GENERAL_SERVER_HTTP_COMM_TASK_H +#define ARANGOD_GENERAL_SERVER_HTTP_COMM_TASK_H 1 + +#include "GeneralServer/GeneralCommTask.h" +namespace arangodb { +namespace rest { + +class HttpCommTask : public GeneralCommTask { + public: + HttpCommTask(GeneralServer* serv, TRI_socket_t sock, ConnectionInfo&& info, + double timeout) + : Task("HttpCommTask"), + GeneralCommTask(serv, sock, std::move(info), timeout) { + _protocol = "http"; + } +}; +} // rest +} // arangodb + +#endif diff --git a/arangod/HttpServer/HttpServerJob.cpp b/arangod/GeneralServer/HttpServerJob.cpp similarity index 94% rename from arangod/HttpServer/HttpServerJob.cpp rename to arangod/GeneralServer/HttpServerJob.cpp index 7008ea0730..4dcc1151f7 100644 --- a/arangod/HttpServer/HttpServerJob.cpp +++ b/arangod/GeneralServer/HttpServerJob.cpp @@ -26,10 +26,10 @@ #include "Basics/WorkMonitor.h" #include "Dispatcher/DispatcherQueue.h" -#include "HttpServer/AsyncJobManager.h" -#include "HttpServer/HttpCommTask.h" -#include "HttpServer/HttpServer.h" -#include "HttpServer/RestHandler.h" +#include "GeneralServer/AsyncJobManager.h" +#include "GeneralServer/GeneralCommTask.h" +#include "GeneralServer/GeneralServer.h" +#include "GeneralServer/RestHandler.h" #include "Logger/Logger.h" #include "RestServer/RestServerFeature.h" #include "Scheduler/Scheduler.h" @@ -42,7 +42,7 @@ using namespace arangodb::rest; /// @brief constructs a new server job //////////////////////////////////////////////////////////////////////////////// -HttpServerJob::HttpServerJob(HttpServer* server, +HttpServerJob::HttpServerJob(GeneralServer* server, WorkItem::uptr& handler, bool isAsync) : Job("HttpServerJob"), _server(server), diff --git a/arangod/HttpServer/HttpServerJob.h b/arangod/GeneralServer/HttpServerJob.h similarity index 93% rename from arangod/HttpServer/HttpServerJob.h rename to arangod/GeneralServer/HttpServerJob.h index 99275734c6..e4a6ae388f 100644 --- a/arangod/HttpServer/HttpServerJob.h +++ b/arangod/GeneralServer/HttpServerJob.h @@ -33,14 +33,14 @@ namespace arangodb { namespace rest { class RestHandler; -class HttpServer; +class GeneralServer; class HttpServerJob : public Job { HttpServerJob(HttpServerJob const&) = delete; HttpServerJob& operator=(HttpServerJob const&) = delete; public: - HttpServerJob(HttpServer*, arangodb::WorkItem::uptr&, + HttpServerJob(GeneralServer*, arangodb::WorkItem::uptr&, bool isAsync = false); ~HttpServerJob(); @@ -56,7 +56,7 @@ class HttpServerJob : public Job { void handleError(basics::Exception const&) override; protected: - HttpServer* _server; + GeneralServer* _server; arangodb::WorkItem::uptr _handler; arangodb::WorkDescription* _workDesc; bool _isAsync; diff --git a/arangod/HttpServer/HttpsCommTask.cpp b/arangod/GeneralServer/HttpsCommTask.cpp similarity index 99% rename from arangod/HttpServer/HttpsCommTask.cpp rename to arangod/GeneralServer/HttpsCommTask.cpp index bb046eed80..1c55c2d42d 100644 --- a/arangod/HttpServer/HttpsCommTask.cpp +++ b/arangod/GeneralServer/HttpsCommTask.cpp @@ -23,12 +23,11 @@ //////////////////////////////////////////////////////////////////////////////// #include "HttpsCommTask.h" - #include #include "Basics/StringBuffer.h" #include "Basics/socket-utils.h" -#include "HttpServer/HttpsServer.h" +#include "GeneralServer/GeneralServer.h" #include "Logger/Logger.h" #include "Scheduler/Scheduler.h" #include "Ssl/ssl-helper.h" @@ -40,7 +39,7 @@ using namespace arangodb::rest; /// @brief constructs a new task with a given socket //////////////////////////////////////////////////////////////////////////////// -HttpsCommTask::HttpsCommTask(HttpsServer* server, TRI_socket_t socket, +HttpsCommTask::HttpsCommTask(GeneralServer* server, TRI_socket_t socket, ConnectionInfo&& info, double keepAliveTimeout, SSL_CTX* ctx, int verificationMode, int (*verificationCallback)(int, X509_STORE_CTX*)) diff --git a/arangod/HttpServer/HttpsCommTask.h b/arangod/GeneralServer/HttpsCommTask.h similarity index 97% rename from arangod/HttpServer/HttpsCommTask.h rename to arangod/GeneralServer/HttpsCommTask.h index 6728b10ca7..f11d390999 100644 --- a/arangod/HttpServer/HttpsCommTask.h +++ b/arangod/GeneralServer/HttpsCommTask.h @@ -25,13 +25,13 @@ #ifndef ARANGOD_HTTP_SERVER_HTTPS_COMM_TASK_H #define ARANGOD_HTTP_SERVER_HTTPS_COMM_TASK_H 1 -#include "HttpServer/HttpCommTask.h" +#include "GeneralServer/HttpCommTask.h" #include namespace arangodb { namespace rest { -class HttpsServer; +class GeneralServer; //////////////////////////////////////////////////////////////////////////////// /// @brief https communication @@ -53,7 +53,7 @@ class HttpsCommTask : public HttpCommTask { /// @brief constructs a new task with a given socket ////////////////////////////////////////////////////////////////////////////// - HttpsCommTask(HttpsServer*, TRI_socket_t, ConnectionInfo&&, + HttpsCommTask(GeneralServer*, TRI_socket_t, ConnectionInfo&&, double keepAliveTimeout, SSL_CTX* ctx, int verificationMode, int (*verificationCallback)(int, X509_STORE_CTX*)); diff --git a/arangod/HttpServer/PathHandler.cpp b/arangod/GeneralServer/PathHandler.cpp similarity index 100% rename from arangod/HttpServer/PathHandler.cpp rename to arangod/GeneralServer/PathHandler.cpp diff --git a/arangod/HttpServer/PathHandler.h b/arangod/GeneralServer/PathHandler.h similarity index 95% rename from arangod/HttpServer/PathHandler.h rename to arangod/GeneralServer/PathHandler.h index 010cf0a783..385056ab5f 100644 --- a/arangod/HttpServer/PathHandler.h +++ b/arangod/GeneralServer/PathHandler.h @@ -24,7 +24,7 @@ #ifndef ARANGOD_HTTP_SERVER_PATH_HANDLER_H #define ARANGOD_HTTP_SERVER_PATH_HANDLER_H 1 -#include "HttpServer/RestHandler.h" +#include "GeneralServer/RestHandler.h" namespace arangodb { namespace rest { @@ -53,7 +53,8 @@ class PathHandler : public RestHandler { }; public: - static RestHandler* create(GeneralRequest* request, GeneralResponse* response, void* data) { + static RestHandler* create(GeneralRequest* request, GeneralResponse* response, + void* data) { Options* options = static_cast(data); return new PathHandler(request, response, options); diff --git a/arangod/HttpServer/RestHandler.cpp b/arangod/GeneralServer/RestHandler.cpp similarity index 99% rename from arangod/HttpServer/RestHandler.cpp rename to arangod/GeneralServer/RestHandler.cpp index ceaea5e01c..72596685c1 100644 --- a/arangod/HttpServer/RestHandler.cpp +++ b/arangod/GeneralServer/RestHandler.cpp @@ -61,7 +61,7 @@ RestHandler::status RestHandler::executeFull() { #ifdef USE_DEV_TIMERS TRI_request_statistics_t::STATS = _statistics; #endif - + try { prepareExecute(); @@ -111,7 +111,7 @@ RestHandler::status RestHandler::executeFull() { #ifdef USE_DEV_TIMERS TRI_request_statistics_t::STATS = nullptr; #endif - + return result; } diff --git a/arangod/HttpServer/RestHandler.h b/arangod/GeneralServer/RestHandler.h similarity index 89% rename from arangod/HttpServer/RestHandler.h rename to arangod/GeneralServer/RestHandler.h index 903474dffe..99e0309501 100644 --- a/arangod/HttpServer/RestHandler.h +++ b/arangod/GeneralServer/RestHandler.h @@ -58,9 +58,7 @@ class RestHandler : public RequestStatisticsAgent, public arangodb::WorkItem { virtual bool isDirect() const = 0; // returns the queue name - virtual size_t queue() const { - return Dispatcher::STANDARD_QUEUE; - } + virtual size_t queue() const { return Dispatcher::STANDARD_QUEUE; } // prepares execution of a handler, has to be called before execute virtual void prepareExecute() {} @@ -72,9 +70,7 @@ class RestHandler : public RequestStatisticsAgent, public arangodb::WorkItem { virtual void finalizeExecute() {} // tries to cancel an execution - virtual bool cancel() { - return false; - } + virtual bool cancel() { return false; } // handles error virtual void handleError(basics::Exception const&) = 0; @@ -84,14 +80,10 @@ class RestHandler : public RequestStatisticsAgent, public arangodb::WorkItem { public: // returns the id of the underlying task - uint64_t taskId() const { - return _taskId; - } + uint64_t taskId() const { return _taskId; } // returns the event loop of the underlying task - EventLoop eventLoop() const { - return _loop; - } + EventLoop eventLoop() const { return _loop; } // sets the id of the underlying task or 0 if dettach void setTaskId(uint64_t id, EventLoop); @@ -100,17 +92,13 @@ class RestHandler : public RequestStatisticsAgent, public arangodb::WorkItem { status executeFull(); // return a pointer to the request - GeneralRequest const* request() const { - return _request; - } + GeneralRequest const* request() const { return _request; } // steal the pointer to the request GeneralRequest* stealRequest(); // returns the response - GeneralResponse* response() const { - return _response; - } + GeneralResponse* response() const { return _response; } // steal the response GeneralResponse* stealResponse(); @@ -132,7 +120,7 @@ class RestHandler : public RequestStatisticsAgent, public arangodb::WorkItem { // the request GeneralRequest* _request; -//OBI-TODO make private + // OBI-TODO make private // the response GeneralResponse* _response; }; diff --git a/arangod/HttpServer/RestHandlerFactory.cpp b/arangod/GeneralServer/RestHandlerFactory.cpp similarity index 97% rename from arangod/HttpServer/RestHandlerFactory.cpp rename to arangod/GeneralServer/RestHandlerFactory.cpp index 6f49647d80..888bccb67a 100644 --- a/arangod/HttpServer/RestHandlerFactory.cpp +++ b/arangod/GeneralServer/RestHandlerFactory.cpp @@ -24,7 +24,7 @@ #include "RestHandlerFactory.h" #include "Cluster/ServerState.h" -#include "HttpServer/RestHandler.h" +#include "GeneralServer/RestHandler.h" #include "Logger/Logger.h" #include "Rest/GeneralRequest.h" #include "Rest/RequestContext.h" @@ -63,17 +63,13 @@ class MaintenanceHandler : public RestHandler { RestHandlerFactory::RestHandlerFactory(context_fptr setContext, void* contextData) - : _setContext(setContext), - _contextData(contextData), - _notFound(nullptr) {} + : _setContext(setContext), _contextData(contextData), _notFound(nullptr) {} void RestHandlerFactory::setMaintenance(bool value) { _maintenanceMode.store(value); } -bool RestHandlerFactory::isMaintenance() { - return _maintenanceMode.load(); -} +bool RestHandlerFactory::isMaintenance() { return _maintenanceMode.load(); } //////////////////////////////////////////////////////////////////////////////// /// @brief set request context, wrapper method diff --git a/arangod/HttpServer/RestHandlerFactory.h b/arangod/GeneralServer/RestHandlerFactory.h similarity index 100% rename from arangod/HttpServer/RestHandlerFactory.h rename to arangod/GeneralServer/RestHandlerFactory.h diff --git a/arangod/HttpServer/HttpsServer.cpp b/arangod/HttpServer/HttpsServer.cpp deleted file mode 100644 index b92171e418..0000000000 --- a/arangod/HttpServer/HttpsServer.cpp +++ /dev/null @@ -1,67 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -/// 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 Dr. Frank Celler -//////////////////////////////////////////////////////////////////////////////// - -#include "HttpsServer.h" - -#include "HttpServer/HttpsCommTask.h" - -using namespace arangodb; -using namespace arangodb::rest; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief constructs a new http server -//////////////////////////////////////////////////////////////////////////////// - -HttpsServer::HttpsServer( - double keepAliveTimeout, bool allowMethodOverride, - std::vector const& accessControlAllowOrigins, SSL_CTX* ctx) - : HttpServer(keepAliveTimeout, allowMethodOverride, - accessControlAllowOrigins), - _ctx(ctx), - _verificationMode(SSL_VERIFY_NONE), - _verificationCallback(0) {} - -HttpsServer::~HttpsServer() { - // don't free context here but in dtor of ApplicationEndpointServer - // SSL_CTX_free(ctx); -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief sets the verification mode -//////////////////////////////////////////////////////////////////////////////// - -void HttpsServer::setVerificationMode(int mode) { _verificationMode = mode; } - -//////////////////////////////////////////////////////////////////////////////// -/// @brief sets the verification callback -//////////////////////////////////////////////////////////////////////////////// - -void HttpsServer::setVerificationCallback(int (*func)(int, X509_STORE_CTX*)) { - _verificationCallback = func; -} - -HttpCommTask* HttpsServer::createCommTask(TRI_socket_t s, - ConnectionInfo&& info) { - return new HttpsCommTask(this, s, std::move(info), _keepAliveTimeout, _ctx, - _verificationMode, _verificationCallback); -} diff --git a/arangod/HttpServer/HttpsServer.h b/arangod/HttpServer/HttpsServer.h deleted file mode 100644 index 3e6cf5f349..0000000000 --- a/arangod/HttpServer/HttpsServer.h +++ /dev/null @@ -1,65 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -/// 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 Dr. Frank Celler -//////////////////////////////////////////////////////////////////////////////// - -#ifndef ARANGOD_HTTP_SERVER_HTTPS_SERVER_H -#define ARANGOD_HTTP_SERVER_HTTPS_SERVER_H 1 - -#include "HttpServer/HttpServer.h" - -#include - -namespace arangodb { -namespace rest { - -class HttpsServer : public HttpServer { - public: - HttpsServer(double keepAliveTimeout, bool allowMethodOverride, - std::vector const& accessControlAllowOrigins, - SSL_CTX*); - ~HttpsServer(); - - public: - // sets the verification mode - void setVerificationMode(int mode); - - // sets the verification callback - void setVerificationCallback(int (*func)(int, X509_STORE_CTX*)); - - public: - char const* protocol() const override { return "https"; } - - Endpoint::EncryptionType encryptionType() const override { - return Endpoint::EncryptionType::SSL; - } - - HttpCommTask* createCommTask(TRI_socket_t, ConnectionInfo&&) override; - - private: - SSL_CTX* _ctx; - int _verificationMode; - int (*_verificationCallback)(int, X509_STORE_CTX*); -}; -} -} - -#endif diff --git a/arangod/RestHandler/RestBaseHandler.h b/arangod/RestHandler/RestBaseHandler.h index faf53b9fd1..15d487f0f5 100644 --- a/arangod/RestHandler/RestBaseHandler.h +++ b/arangod/RestHandler/RestBaseHandler.h @@ -24,7 +24,7 @@ #ifndef ARANGOD_REST_HANDLER_REST_BASE_HANDLER_H #define ARANGOD_REST_HANDLER_REST_BASE_HANDLER_H 1 -#include "HttpServer/RestHandler.h" +#include "GeneralServer/RestHandler.h" #include "Rest/GeneralResponse.h" @@ -66,9 +66,8 @@ class RestBaseHandler : public rest::RestHandler { protected: // write result back to client - void writeResult(arangodb::velocypack::Slice const& slice, + void writeResult(arangodb::velocypack::Slice const& slice, arangodb::velocypack::Options const& options); - }; } diff --git a/arangod/RestHandler/RestBatchHandler.cpp b/arangod/RestHandler/RestBatchHandler.cpp index 072a3aa347..b6c38eeaf6 100644 --- a/arangod/RestHandler/RestBatchHandler.cpp +++ b/arangod/RestHandler/RestBatchHandler.cpp @@ -26,8 +26,8 @@ #include "Basics/StaticStrings.h" #include "Basics/StringUtils.h" #include "Logger/Logger.h" -#include "HttpServer/HttpServer.h" -#include "HttpServer/RestHandlerFactory.h" +#include "GeneralServer/GeneralServer.h" +#include "GeneralServer/RestHandlerFactory.h" #include "Rest/HttpRequest.h" #include "RestServer/RestServerFeature.h" diff --git a/arangod/RestHandler/RestJobHandler.cpp b/arangod/RestHandler/RestJobHandler.cpp index ceacd9972b..dc962a1211 100644 --- a/arangod/RestHandler/RestJobHandler.cpp +++ b/arangod/RestHandler/RestJobHandler.cpp @@ -26,7 +26,7 @@ #include "Basics/StringUtils.h" #include "Dispatcher/Dispatcher.h" #include "Dispatcher/DispatcherFeature.h" -#include "HttpServer/AsyncJobManager.h" +#include "GeneralServer/AsyncJobManager.h" #include "Rest/HttpRequest.h" #include "Rest/HttpResponse.h" @@ -40,7 +40,7 @@ using namespace arangodb::rest; RestJobHandler::RestJobHandler(GeneralRequest* request, GeneralResponse* response, AsyncJobManager* jobManager) - : RestBaseHandler(request, response), _jobManager(jobManager) { + : RestBaseHandler(request, response), _jobManager(jobManager) { TRI_ASSERT(jobManager != nullptr); } @@ -129,7 +129,7 @@ void RestJobHandler::putJobMethod() { generateError(GeneralResponse::ResponseCode::SERVER_ERROR, TRI_ERROR_HTTP_NOT_FOUND); } - + bool status = DispatcherFeature::DISPATCHER->cancelJob(jobId); // unknown or already fetched job diff --git a/arangod/RestHandler/RestJobHandler.h b/arangod/RestHandler/RestJobHandler.h index 8425a35241..96c3fcc75c 100644 --- a/arangod/RestHandler/RestJobHandler.h +++ b/arangod/RestHandler/RestJobHandler.h @@ -25,7 +25,7 @@ #define ARANGOD_REST_HANDLER_REST_JOB_HANDLER_H 1 #include "Basics/Common.h" -#include "HttpServer/AsyncJobManager.h" +#include "GeneralServer/AsyncJobManager.h" #include "RestHandler/RestBaseHandler.h" namespace arangodb { diff --git a/arangod/RestHandler/RestPleaseUpgradeHandler.h b/arangod/RestHandler/RestPleaseUpgradeHandler.h index b027ead224..aa448c0fd4 100644 --- a/arangod/RestHandler/RestPleaseUpgradeHandler.h +++ b/arangod/RestHandler/RestPleaseUpgradeHandler.h @@ -24,7 +24,7 @@ #ifndef ARANGOD_REST_HANDLER_REST_PLEASE_UPGRADE_HANDLER_H #define ARANGOD_REST_HANDLER_REST_PLEASE_UPGRADE_HANDLER_H 1 -#include "HttpServer/RestHandler.h" +#include "GeneralServer/RestHandler.h" namespace arangodb { class RestPleaseUpgradeHandler : public rest::RestHandler { diff --git a/arangod/RestHandler/RestReplicationHandler.cpp b/arangod/RestHandler/RestReplicationHandler.cpp index b68ee83451..fba33acf85 100644 --- a/arangod/RestHandler/RestReplicationHandler.cpp +++ b/arangod/RestHandler/RestReplicationHandler.cpp @@ -29,7 +29,7 @@ #include "Basics/files.h" #include "Cluster/ClusterComm.h" #include "Cluster/ClusterMethods.h" -#include "HttpServer/HttpServer.h" +#include "GeneralServer/GeneralServer.h" #include "Indexes/EdgeIndex.h" #include "Indexes/Index.h" #include "Indexes/PrimaryIndex.h" @@ -566,7 +566,8 @@ void RestReplicationHandler::handleCommandBatch() { } // extract ttl - double expires = VelocyPackHelper::getNumericValue(input->slice(), "ttl", 0); + double expires = + VelocyPackHelper::getNumericValue(input->slice(), "ttl", 0); TRI_voc_tick_t id; int res = TRI_InsertBlockerCompactorVocBase(_vocbase, expires, &id); @@ -596,14 +597,15 @@ void RestReplicationHandler::handleCommandBatch() { auto input = _request->toVelocyPackBuilderPtr(&VPackOptions::Defaults); - if (input == nullptr || !input->slice().isObject()){ + if (input == nullptr || !input->slice().isObject()) { generateError(GeneralResponse::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER, "invalid JSON"); return; } // extract ttl - double expires = VelocyPackHelper::getNumericValue(input->slice(), "ttl", 0); + double expires = + VelocyPackHelper::getNumericValue(input->slice(), "ttl", 0); // now extend the blocker int res = TRI_TouchBlockerCompactorVocBase(_vocbase, id, expires); @@ -775,7 +777,6 @@ void RestReplicationHandler::handleCommandBarrier() { //////////////////////////////////////////////////////////////////////////////// void RestReplicationHandler::handleTrampolineCoordinator() { - if (_request == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); } @@ -812,7 +813,7 @@ void RestReplicationHandler::handleTrampolineCoordinator() { ClusterComm* cc = ClusterComm::instance(); HttpRequest* httpRequest = dynamic_cast(_request); - if(httpRequest == nullptr){ + if (httpRequest == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); } @@ -1216,7 +1217,7 @@ void RestReplicationHandler::handleCommandClusterInventory() { TRI_ERROR_CLUSTER_READING_PLAN_AGENCY); } else { VPackSlice colls = result.slice()[0].get(std::vector( - {_agency.prefix(), "Plan", "Collections", dbName})); + {_agency.prefix(), "Plan", "Collections", dbName})); if (!colls.isObject()) { generateError(GeneralResponse::ResponseCode::SERVER_ERROR, TRI_ERROR_CLUSTER_READING_PLAN_AGENCY); @@ -1232,7 +1233,7 @@ void RestReplicationHandler::handleCommandClusterInventory() { if (subResultSlice.isObject()) { if (includeSystem || !arangodb::basics::VelocyPackHelper::getBooleanValue( - subResultSlice, "isSystem", true)) { + subResultSlice, "isSystem", true)) { VPackObjectBuilder b3(&resultBuilder); resultBuilder.add("indexes", subResultSlice.get("indexes")); resultBuilder.add("parameters", subResultSlice); @@ -1245,11 +1246,9 @@ void RestReplicationHandler::handleCommandClusterInventory() { resultBuilder.add("tick", VPackValue(tickString)); resultBuilder.add("state", VPackValue("unused")); } - generateResult(GeneralResponse::ResponseCode::OK, - resultBuilder.slice()); + generateResult(GeneralResponse::ResponseCode::OK, resultBuilder.slice()); } } - } //////////////////////////////////////////////////////////////////////////////// @@ -1626,7 +1625,8 @@ int RestReplicationHandler::processRestoreCollection( int RestReplicationHandler::processRestoreCollectionCoordinator( VPackSlice const& collection, bool dropExisting, bool reuseId, bool force, - uint64_t numberOfShards, std::string& errorMsg, uint64_t replicationFactor) { + uint64_t numberOfShards, std::string& errorMsg, + uint64_t replicationFactor) { if (!collection.isObject()) { errorMsg = "collection declaration is invalid"; @@ -1716,8 +1716,8 @@ int RestReplicationHandler::processRestoreCollectionCoordinator( VPackSlice const replFactorSlice = parameters.get("replicationFactor"); if (replFactorSlice.isInteger()) { - replicationFactor = replFactorSlice.getNumericValue - (); + replicationFactor = + replFactorSlice.getNumericValue(); } if (replicationFactor == 0) { replicationFactor = 1; @@ -1741,9 +1741,9 @@ int RestReplicationHandler::processRestoreCollectionCoordinator( // shards std::vector dbServers; // will be filled - std::map> shardDistribution - = arangodb::distributeShards(numberOfShards, replicationFactor, - dbServers); + std::map> shardDistribution = + arangodb::distributeShards(numberOfShards, replicationFactor, + dbServers); if (shardDistribution.empty()) { errorMsg = "no database servers found in cluster"; return TRI_ERROR_INTERNAL; @@ -1991,7 +1991,8 @@ int RestReplicationHandler::processRestoreIndexesCoordinator( int res = TRI_ERROR_NO_ERROR; for (VPackSlice const& idxDef : VPackArrayIterator(indexes)) { VPackSlice type = idxDef.get("type"); - if (type.isString() && (type.copyString() == "primary" || type.copyString() == "edge")) { + if (type.isString() && + (type.copyString() == "primary" || type.copyString() == "edge")) { // must ignore these types of indexes during restore continue; } @@ -2271,8 +2272,8 @@ int RestReplicationHandler::processRestoreDataBatch( options.ignoreRevs = true; options.isRestore = true; options.waitForSync = false; - OperationResult opRes = trx.remove(collectionName, oldBuilder.slice(), - options); + OperationResult opRes = + trx.remove(collectionName, oldBuilder.slice(), options); if (!opRes.successful()) { return opRes.code; } @@ -3943,9 +3944,10 @@ void RestReplicationHandler::handleCommandHoldReadLockCollection() { } VPackSlice const body = parsedBody->slice(); if (!body.isObject()) { - generateError( - GeneralResponse::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER, - "body needs to be an object with attributes 'collection', 'ttl' and 'id'"); + generateError(GeneralResponse::ResponseCode::BAD, + TRI_ERROR_HTTP_BAD_PARAMETER, + "body needs to be an object with attributes 'collection', " + "'ttl' and 'id'"); return; } VPackSlice const collection = body.get("collection"); @@ -3960,7 +3962,8 @@ void RestReplicationHandler::handleCommandHoldReadLockCollection() { } std::string id = idSlice.copyString(); - auto col = TRI_LookupCollectionByNameVocBase(_vocbase, collection.copyString()); + auto col = + TRI_LookupCollectionByNameVocBase(_vocbase, collection.copyString()); if (col == nullptr) { generateError(GeneralResponse::ResponseCode::SERVER_ERROR, TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND, @@ -4048,16 +4051,15 @@ void RestReplicationHandler::handleCommandCheckHoldReadLockCollection() { } VPackSlice const body = parsedBody->slice(); if (!body.isObject()) { - generateError( - GeneralResponse::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER, - "body needs to be an object with attribute 'id'"); + generateError(GeneralResponse::ResponseCode::BAD, + TRI_ERROR_HTTP_BAD_PARAMETER, + "body needs to be an object with attribute 'id'"); return; } VPackSlice const idSlice = body.get("id"); if (!idSlice.isString()) { generateError(GeneralResponse::ResponseCode::BAD, - TRI_ERROR_HTTP_BAD_PARAMETER, - "'id' needs to be a string"); + TRI_ERROR_HTTP_BAD_PARAMETER, "'id' needs to be a string"); return; } std::string id = idSlice.copyString(); @@ -4096,16 +4098,15 @@ void RestReplicationHandler::handleCommandCancelHoldReadLockCollection() { } VPackSlice const body = parsedBody->slice(); if (!body.isObject()) { - generateError( - GeneralResponse::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER, - "body needs to be an object with attribute 'id'"); + generateError(GeneralResponse::ResponseCode::BAD, + TRI_ERROR_HTTP_BAD_PARAMETER, + "body needs to be an object with attribute 'id'"); return; } VPackSlice const idSlice = body.get("id"); if (!idSlice.isString()) { generateError(GeneralResponse::ResponseCode::BAD, - TRI_ERROR_HTTP_BAD_PARAMETER, - "'id' needs to be a string"); + TRI_ERROR_HTTP_BAD_PARAMETER, "'id' needs to be a string"); return; } std::string id = idSlice.copyString(); diff --git a/arangod/RestHandler/RestUploadHandler.cpp b/arangod/RestHandler/RestUploadHandler.cpp index de3ac01fc3..3ebd699b7e 100644 --- a/arangod/RestHandler/RestUploadHandler.cpp +++ b/arangod/RestHandler/RestUploadHandler.cpp @@ -27,7 +27,7 @@ #include "Basics/StaticStrings.h" #include "Basics/StringUtils.h" #include "Basics/tri-strings.h" -#include "HttpServer/HttpServer.h" +#include "GeneralServer/GeneralServer.h" #include "Logger/Logger.h" #include "Rest/HttpRequest.h" diff --git a/arangod/RestHandler/RestUploadHandler.h b/arangod/RestHandler/RestUploadHandler.h index d5b411defe..fd8003ee68 100644 --- a/arangod/RestHandler/RestUploadHandler.h +++ b/arangod/RestHandler/RestUploadHandler.h @@ -25,7 +25,7 @@ #define ARANGOD_REST_HANDLER_REST_UPLOAD_HANDLER_H 1 #include "Basics/Common.h" -#include "HttpServer/HttpServer.h" +#include "GeneralServer/GeneralServer.h" #include "RestHandler/RestVocbaseBaseHandler.h" namespace arangodb { diff --git a/arangod/RestHandler/WorkMonitorHandler.cpp b/arangod/RestHandler/WorkMonitorHandler.cpp index f9b0a8dfc2..a1114f34f8 100644 --- a/arangod/RestHandler/WorkMonitorHandler.cpp +++ b/arangod/RestHandler/WorkMonitorHandler.cpp @@ -23,7 +23,7 @@ #include "WorkMonitorHandler.h" #include "Basics/StringUtils.h" -#include "HttpServer/RestHandler.h" +#include "GeneralServer/RestHandler.h" #include "Rest/HttpRequest.h" #include "velocypack/Builder.h" #include "velocypack/velocypack-aliases.h" diff --git a/arangod/RestServer/BootstrapFeature.cpp b/arangod/RestServer/BootstrapFeature.cpp index 12e6e933d9..19ed7f3a82 100644 --- a/arangod/RestServer/BootstrapFeature.cpp +++ b/arangod/RestServer/BootstrapFeature.cpp @@ -26,7 +26,7 @@ #include "Cluster/AgencyComm.h" #include "Cluster/ClusterInfo.h" #include "Cluster/ServerState.h" -#include "HttpServer/RestHandlerFactory.h" +#include "GeneralServer/RestHandlerFactory.h" #include "Logger/Logger.h" #include "ProgramOptions/Parameters.h" #include "ProgramOptions/ProgramOptions.h" @@ -41,7 +41,8 @@ using namespace arangodb; using namespace arangodb::application_features; using namespace arangodb::options; -BootstrapFeature::BootstrapFeature(application_features::ApplicationServer* server) +BootstrapFeature::BootstrapFeature( + application_features::ApplicationServer* server) : ApplicationFeature(server, "Bootstrap"), _isReady(false), _bark(false) { startsAfter("Dispatcher"); startsAfter("Endpoint"); @@ -55,9 +56,9 @@ BootstrapFeature::BootstrapFeature(application_features::ApplicationServer* serv startsAfter("RestServer"); } -void BootstrapFeature::collectOptions( - std::shared_ptr options) { - options->addHiddenOption("hund", "make ArangoDB bark on startup", new BooleanParameter(&_bark)); +void BootstrapFeature::collectOptions(std::shared_ptr options) { + options->addHiddenOption("hund", "make ArangoDB bark on startup", + new BooleanParameter(&_bark)); } static void raceForClusterBootstrap() { @@ -68,22 +69,22 @@ static void raceForClusterBootstrap() { AgencyCommResult result = agency.getValues("Bootstrap"); if (!result.successful()) { // Error in communication, note that value not found is not an error - LOG_TOPIC(TRACE, Logger::STARTUP) + LOG_TOPIC(TRACE, Logger::STARTUP) << "raceForClusterBootstrap: no agency communication"; sleep(1); continue; } - VPackSlice value = result.slice()[0].get(std::vector( - {agency.prefix(), "Bootstrap"})); + VPackSlice value = result.slice()[0].get( + std::vector({agency.prefix(), "Bootstrap"})); if (value.isString()) { // key was found and is a string if (value.isEqualString("done")) { // all done, let's get out of here: - LOG_TOPIC(TRACE, Logger::STARTUP) + LOG_TOPIC(TRACE, Logger::STARTUP) << "raceForClusterBootstrap: bootstrap already done"; return; } - LOG_TOPIC(DEBUG, Logger::STARTUP) + LOG_TOPIC(DEBUG, Logger::STARTUP) << "raceForClusterBootstrap: somebody else does the bootstrap"; sleep(1); continue; @@ -94,7 +95,7 @@ static void raceForClusterBootstrap() { b.add(VPackValue(arangodb::ServerState::instance()->getId())); result = agency.casValue("Bootstrap", b.slice(), false, 300, 15); if (!result.successful()) { - LOG_TOPIC(DEBUG, Logger::STARTUP) + LOG_TOPIC(DEBUG, Logger::STARTUP) << "raceForClusterBootstrap: lost race, somebody else will bootstrap"; // Cannot get foot into the door, try again later: sleep(1); @@ -104,19 +105,20 @@ static void raceForClusterBootstrap() { // OK, we handle things now, let's see whether a DBserver is there: auto dbservers = ci->getCurrentDBServers(); if (dbservers.size() == 0) { - LOG_TOPIC(TRACE, Logger::STARTUP) + LOG_TOPIC(TRACE, Logger::STARTUP) << "raceForClusterBootstrap: no DBservers, waiting"; agency.removeValues("Bootstrap", false); sleep(1); continue; } - LOG_TOPIC(DEBUG, Logger::STARTUP) + LOG_TOPIC(DEBUG, Logger::STARTUP) << "raceForClusterBootstrap: race won, we do the bootstrap"; auto vocbase = DatabaseFeature::DATABASE->vocbase(); - V8DealerFeature::DEALER->loadJavascriptFiles(vocbase, "server/bootstrap/cluster-bootstrap.js", 0); + V8DealerFeature::DEALER->loadJavascriptFiles( + vocbase, "server/bootstrap/cluster-bootstrap.js", 0); - LOG_TOPIC(DEBUG, Logger::STARTUP) + LOG_TOPIC(DEBUG, Logger::STARTUP) << "raceForClusterBootstrap: bootstrap done"; b.clear(); @@ -126,7 +128,7 @@ static void raceForClusterBootstrap() { return; } - LOG_TOPIC(TRACE, Logger::STARTUP) + LOG_TOPIC(TRACE, Logger::STARTUP) << "raceForClusterBootstrap: could not indicate success"; sleep(1); @@ -140,11 +142,15 @@ void BootstrapFeature::start() { if (ss->isCoordinator()) { LOG_TOPIC(DEBUG, Logger::STARTUP) << "Racing for cluster bootstrap..."; raceForClusterBootstrap(); - LOG_TOPIC(DEBUG, Logger::STARTUP) << "Running server/bootstrap/coordinator.js"; - V8DealerFeature::DEALER->loadJavascript(vocbase, "server/bootstrap/coordinator.js"); + LOG_TOPIC(DEBUG, Logger::STARTUP) + << "Running server/bootstrap/coordinator.js"; + V8DealerFeature::DEALER->loadJavascript(vocbase, + "server/bootstrap/coordinator.js"); } else if (ss->isDBServer()) { - LOG_TOPIC(DEBUG, Logger::STARTUP) << "Running server/bootstrap/db-server.js"; - V8DealerFeature::DEALER->loadJavascript(vocbase, "server/bootstrap/db-server.js"); + LOG_TOPIC(DEBUG, Logger::STARTUP) + << "Running server/bootstrap/db-server.js"; + V8DealerFeature::DEALER->loadJavascript(vocbase, + "server/bootstrap/db-server.js"); } else { LOG_TOPIC(DEBUG, Logger::STARTUP) << "Running server/server.js"; V8DealerFeature::DEALER->loadJavascript(vocbase, "server/server.js"); @@ -163,13 +169,15 @@ void BootstrapFeature::start() { } void BootstrapFeature::unprepare() { - auto server = ApplicationServer::getFeature("DatabaseServer"); + auto server = + ApplicationServer::getFeature("DatabaseServer"); - TRI_server_t* s = server->SERVER; + TRI_server_t* s = server->SERVER; // notify all currently running queries about the shutdown if (ServerState::instance()->isCoordinator()) { - std::vector ids = TRI_GetIdsCoordinatorDatabaseServer(s, true); + std::vector ids = + TRI_GetIdsCoordinatorDatabaseServer(s, true); for (auto& id : ids) { TRI_vocbase_t* vocbase = TRI_UseByIdCoordinatorDatabaseServer(s, id); @@ -177,7 +185,7 @@ void BootstrapFeature::unprepare() { vocbase->_queries->killAll(true); TRI_ReleaseVocBase(vocbase); } - } + } } else { std::vector names; int res = TRI_GetDatabaseNamesServer(s, names); @@ -193,4 +201,3 @@ void BootstrapFeature::unprepare() { } } } - diff --git a/arangod/RestServer/EndpointFeature.h b/arangod/RestServer/EndpointFeature.h index 6c3558c6eb..22cb4c2074 100644 --- a/arangod/RestServer/EndpointFeature.h +++ b/arangod/RestServer/EndpointFeature.h @@ -30,13 +30,9 @@ #include "Endpoint/EndpointList.h" namespace arangodb { -namespace rest { -class HttpServer; -class HttpsServer; -} class EndpointFeature final : public application_features::ApplicationFeature, - public HttpEndpointProvider { + public HttpEndpointProvider { public: explicit EndpointFeature(application_features::ApplicationServer* server); diff --git a/arangod/RestServer/RestServerFeature.cpp b/arangod/RestServer/RestServerFeature.cpp index b3c132ae87..a95d44a9e6 100644 --- a/arangod/RestServer/RestServerFeature.cpp +++ b/arangod/RestServer/RestServerFeature.cpp @@ -33,9 +33,8 @@ #include "Cluster/RestAgencyCallbacksHandler.h" #include "Cluster/RestShardHandler.h" #include "Dispatcher/DispatcherFeature.h" -#include "HttpServer/HttpServer.h" -#include "HttpServer/HttpsServer.h" -#include "HttpServer/RestHandlerFactory.h" +#include "GeneralServer/GeneralServer.h" +#include "GeneralServer/RestHandlerFactory.h" #include "ProgramOptions/Parameters.h" #include "ProgramOptions/ProgramOptions.h" #include "ProgramOptions/Section.h" @@ -74,6 +73,8 @@ #include "V8Server/V8DealerFeature.h" #include "VocBase/server.h" +#include + using namespace arangodb; using namespace arangodb::rest; using namespace arangodb::options; @@ -203,8 +204,8 @@ void RestServerFeature::validateOptions(std::shared_ptr) { std::remove_if(_accessControlAllowOrigins.begin(), _accessControlAllowOrigins.end(), [](std::string const& value) { - return basics::StringUtils::trim(value).empty(); - }), + return basics::StringUtils::trim(value).empty(); + }), _accessControlAllowOrigins.end()); } @@ -341,40 +342,29 @@ void RestServerFeature::buildServers() { EndpointFeature* endpoint = application_features::ApplicationServer::getFeature( "Endpoint"); - - // unencrypted HTTP endpoints - HttpServer* httpServer = - new HttpServer(_keepAliveTimeout, - _allowMethodOverride, _accessControlAllowOrigins); - - // YYY #warning FRANK filter list auto const& endpointList = endpoint->endpointList(); - httpServer->setEndpointList(&endpointList); - _servers.push_back(httpServer); - // ssl endpoints + // check if endpointList contains ssl featured server + SSL_CTX* sslContext = nullptr; if (endpointList.hasSsl()) { SslServerFeature* ssl = application_features::ApplicationServer::getFeature( "SslServer"); - // check the ssl context if (ssl->sslContext() == nullptr) { LOG(FATAL) << "no ssl context is known, cannot create https server, " "please use the '--ssl.keyfile' option"; FATAL_ERROR_EXIT(); } - - SSL_CTX* sslContext = ssl->sslContext(); - - // https - httpServer = new HttpsServer(_keepAliveTimeout, - _allowMethodOverride, - _accessControlAllowOrigins, sslContext); - - httpServer->setEndpointList(&endpointList); - _servers.push_back(httpServer); + sslContext = ssl->sslContext(); } + + GeneralServer* server = + new GeneralServer(_keepAliveTimeout, _allowMethodOverride, + _accessControlAllowOrigins, sslContext); + + server->setEndpointList(&endpointList); + _servers.push_back(server); } void RestServerFeature::defineHandlers() { diff --git a/arangod/RestServer/RestServerFeature.h b/arangod/RestServer/RestServerFeature.h index 328e5bf5cc..34b8ca18e1 100644 --- a/arangod/RestServer/RestServerFeature.h +++ b/arangod/RestServer/RestServerFeature.h @@ -32,7 +32,7 @@ namespace arangodb { namespace rest { class AsyncJobManager; class RestHandlerFactory; -class HttpServer; +class GeneralServer; } class RestServerThread; @@ -48,11 +48,11 @@ class RestServerFeature final static bool authenticationEnabled() { return REST_SERVER != nullptr && REST_SERVER->authentication(); } - + static bool hasProxyCheck() { return REST_SERVER != nullptr && REST_SERVER->proxyCheck(); } - + static std::vector getTrustedProxies() { if (REST_SERVER == nullptr) { return std::vector(); @@ -92,7 +92,7 @@ class RestServerFeature final bool _proxyCheck; std::vector _trustedProxies; std::vector _accessControlAllowOrigins; - + std::string _jwtSecret; public: @@ -112,7 +112,7 @@ class RestServerFeature final private: std::unique_ptr _handlerFactory; std::unique_ptr _jobManager; - std::vector _servers; + std::vector _servers; }; } diff --git a/arangod/Utils/WorkMonitorArangod.cpp b/arangod/Utils/WorkMonitorArangod.cpp index f5fcdfe669..c7861eb698 100644 --- a/arangod/Utils/WorkMonitorArangod.cpp +++ b/arangod/Utils/WorkMonitorArangod.cpp @@ -30,7 +30,7 @@ #include "Aql/QueryList.h" #include "Basics/StaticStrings.h" #include "Basics/StringBuffer.h" -#include "HttpServer/RestHandler.h" +#include "GeneralServer/RestHandler.h" #include "Logger/Logger.h" #include "Scheduler/Scheduler.h" #include "Scheduler/SchedulerFeature.h" diff --git a/arangod/V8Server/v8-actions.cpp b/arangod/V8Server/v8-actions.cpp index 76f6b791a1..69c1890d15 100644 --- a/arangod/V8Server/v8-actions.cpp +++ b/arangod/V8Server/v8-actions.cpp @@ -35,7 +35,7 @@ #include "Basics/tri-strings.h" #include "Cluster/ClusterComm.h" #include "Cluster/ServerState.h" -#include "HttpServer/HttpServer.h" +#include "GeneralServer/GeneralServer.h" #include "Logger/Logger.h" #include "Rest/GeneralRequest.h" #include "Rest/HttpRequest.h" @@ -403,22 +403,23 @@ static v8::Handle RequestCppToV8(v8::Isolate* isolate, TRI_GET_GLOBAL_STRING(RequestTypeKey); TRI_GET_GLOBAL_STRING(RequestBodyKey); - auto set_request_body_json_or_vpack = [&](){ - if (GeneralRequest::ContentType::JSON == request->contentType()) { - auto httpreq = dynamic_cast(request); - if (httpreq == nullptr) { - THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); - } - std::string const& body = httpreq->body(); - req->ForceSet(RequestBodyKey, TRI_V8_STD_STRING(body)); - } else { - VPackSlice slice = request->payload(); - V8Buffer* buffer = V8Buffer::New( - isolate, slice.startAs(), std::distance(slice.begin(), slice.end())); - v8::Local bufferObject = - v8::Local::New(isolate, buffer->_handle); - req->ForceSet(RequestBodyKey, bufferObject); + auto set_request_body_json_or_vpack = [&]() { + if (GeneralRequest::ContentType::JSON == request->contentType()) { + auto httpreq = dynamic_cast(request); + if (httpreq == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); } + std::string const& body = httpreq->body(); + req->ForceSet(RequestBodyKey, TRI_V8_STD_STRING(body)); + } else { + VPackSlice slice = request->payload(); + V8Buffer* buffer = + V8Buffer::New(isolate, slice.startAs(), + std::distance(slice.begin(), slice.end())); + v8::Local bufferObject = + v8::Local::New(isolate, buffer->_handle); + req->ForceSet(RequestBodyKey, bufferObject); + } }; // copy request type @@ -426,7 +427,7 @@ static v8::Handle RequestCppToV8(v8::Isolate* isolate, case GeneralRequest::RequestType::POST: { TRI_GET_GLOBAL_STRING(PostConstant); req->ForceSet(RequestTypeKey, PostConstant); - //req->ForceSet(RequestBodyKey, TRI_V8_STD_STRING(request->body())); + // req->ForceSet(RequestBodyKey, TRI_V8_STD_STRING(request->body())); set_request_body_json_or_vpack(); break; } @@ -434,7 +435,7 @@ static v8::Handle RequestCppToV8(v8::Isolate* isolate, case GeneralRequest::RequestType::PUT: { TRI_GET_GLOBAL_STRING(PutConstant); req->ForceSet(RequestTypeKey, PutConstant); - //req->ForceSet(RequestBodyKey, TRI_V8_STD_STRING(request->body())); + // req->ForceSet(RequestBodyKey, TRI_V8_STD_STRING(request->body())); set_request_body_json_or_vpack(); break; } @@ -442,7 +443,7 @@ static v8::Handle RequestCppToV8(v8::Isolate* isolate, case GeneralRequest::RequestType::PATCH: { TRI_GET_GLOBAL_STRING(PatchConstant); req->ForceSet(RequestTypeKey, PatchConstant); - //req->ForceSet(RequestBodyKey, TRI_V8_STD_STRING(request->body())); + // req->ForceSet(RequestBodyKey, TRI_V8_STD_STRING(request->body())); set_request_body_json_or_vpack(); break; } @@ -1135,7 +1136,7 @@ static void JS_SendChunk(v8::FunctionCallbackInfo const& args) { TRI_Utf8ValueNFC data(TRI_UNKNOWN_MEM_ZONE, args[1]); - int res = HttpServer::sendChunk(id, *data); + int res = GeneralServer::sendChunk(id, *data); if (res != TRI_ERROR_NO_ERROR && res != TRI_ERROR_TASK_NOT_FOUND) { TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "cannot send chunk"); diff --git a/lib/Endpoint/EndpointList.cpp b/lib/Endpoint/EndpointList.cpp index 14271f59a5..09b747069d 100644 --- a/lib/Endpoint/EndpointList.cpp +++ b/lib/Endpoint/EndpointList.cpp @@ -154,40 +154,40 @@ std::vector EndpointList::all( /// @brief return all endpoints with a certain encryption type //////////////////////////////////////////////////////////////////////////////// -std::map EndpointList::matching( - Endpoint::TransportType transport, - Endpoint::EncryptionType encryption) const { - std::string prefix; - - switch (transport) { - case Endpoint::TransportType::HTTP: - prefix = "http+"; - break; - - case Endpoint::TransportType::VPP: - prefix = "vpp+"; - break; - } - - std::map result; - - for (auto& it : _endpoints) { - std::string const& key = it.first; - - if (encryption == Endpoint::EncryptionType::SSL) { - if (StringUtils::isPrefix(key, prefix + "ssl://")) { - result[key] = it.second; - } - } else { - if (StringUtils::isPrefix(key, prefix + "tcp://") || - StringUtils::isPrefix(key, prefix + "unix://")) { - result[key] = it.second; - } - } - } - - return result; -} +// std::map EndpointList::matching( +// Endpoint::TransportType transport, +// Endpoint::EncryptionType encryption) const { +// std::string prefix; +// +// switch (transport) { +// case Endpoint::TransportType::HTTP: +// prefix = "http+"; +// break; +// +// case Endpoint::TransportType::VPP: +// prefix = "vpp+"; +// break; +// } +// +// std::map result; +// +// for (auto& it : _endpoints) { +// std::string const& key = it.first; +// +// if (encryption == Endpoint::EncryptionType::SSL) { +// if (StringUtils::isPrefix(key, prefix + "ssl://")) { +// result[key] = it.second; +// } +// } else { +// if (StringUtils::isPrefix(key, prefix + "tcp://") || +// StringUtils::isPrefix(key, prefix + "unix://")) { +// result[key] = it.second; +// } +// } +// } +// +// return result; +//} //////////////////////////////////////////////////////////////////////////////// /// @brief return if there is an endpoint with SSL diff --git a/lib/Endpoint/EndpointList.h b/lib/Endpoint/EndpointList.h index ecb9c32468..ac538b1a4c 100644 --- a/lib/Endpoint/EndpointList.h +++ b/lib/Endpoint/EndpointList.h @@ -43,8 +43,9 @@ class EndpointList { bool remove(std::string const&, Endpoint**); std::vector all() const; std::vector all(Endpoint::TransportType transport) const; - std::map matching(Endpoint::TransportType, - Endpoint::EncryptionType) const; + // std::map matching(Endpoint::TransportType, + // Endpoint::EncryptionType) const; + std::map allEndpoints() const { return _endpoints; } bool hasSsl() const; void dump() const; diff --git a/lib/Rest/HttpRequest.h b/lib/Rest/HttpRequest.h index 0ebdabf17e..4135d6cd52 100644 --- a/lib/Rest/HttpRequest.h +++ b/lib/Rest/HttpRequest.h @@ -26,14 +26,15 @@ #define ARANGODB_REST_HTTP_REQUEST_H 1 #include "Rest/GeneralRequest.h" - #include "Endpoint/ConnectionInfo.h" namespace arangodb { class RestBatchHandler; namespace rest { +class GeneralCommTask; class HttpCommTask; +class HttpsCommTask; } namespace velocypack { @@ -43,6 +44,8 @@ struct Options; class HttpRequest : public GeneralRequest { friend class rest::HttpCommTask; + friend class rest::HttpsCommTask; + friend class rest::GeneralCommTask; friend class RestBatchHandler; // TODO must be removed private: @@ -74,7 +77,6 @@ class HttpRequest : public GeneralRequest { // Payload VPackSlice payload(arangodb::velocypack::Options const*) override final; - /// @brief sets a key/value header // this function is called by setHeaders and get offsets to // the found key / value with respective lengths. diff --git a/lib/Rest/HttpResponse.h b/lib/Rest/HttpResponse.h index 9f2663bf72..1a682f91da 100644 --- a/lib/Rest/HttpResponse.h +++ b/lib/Rest/HttpResponse.h @@ -34,11 +34,13 @@ class RestBatchHandler; namespace rest { class HttpCommTask; +class GeneralCommTask; } class HttpResponse : public GeneralResponse { + friend class rest::GeneralCommTask; friend class rest::HttpCommTask; - friend class RestBatchHandler; // TODO must be removed + friend class RestBatchHandler; // TODO must be removed public: static bool HIDE_PRODUCT_HEADER; @@ -67,7 +69,9 @@ class HttpResponse : public GeneralResponse { size_t bodySize() const; /// @brief set type of connection - void setConnectionType(ConnectionType type) override { _connectionType = type; } + void setConnectionType(ConnectionType type) override { + _connectionType = type; + } /// @brief set content-type void setContentType(ContentType type) override { _contentType = type; } @@ -95,7 +99,6 @@ class HttpResponse : public GeneralResponse { bool generateBody, arangodb::velocypack::Options const&) override final; - private: // the body must already be set. deflate is then run on the existing body int deflate(size_t = 16384);