1
0
Fork 0

preparations for velocystream completed

This commit is contained in:
Jan Christoph Uhde 2016-07-21 09:32:00 +02:00
parent 410bd3d95b
commit 5edaf0043a
44 changed files with 477 additions and 530 deletions

View File

@ -185,16 +185,17 @@ add_executable(${BIN_ARANGOD}
FulltextIndex/fulltext-query.cpp FulltextIndex/fulltext-query.cpp
FulltextIndex/fulltext-result.cpp FulltextIndex/fulltext-result.cpp
GeoIndex/GeoIndex.cpp GeoIndex/GeoIndex.cpp
HttpServer/AsyncJobManager.cpp GeneralServer/AsyncJobManager.cpp
HttpServer/HttpCommTask.cpp GeneralServer/HttpCommTask.cpp
HttpServer/HttpListenTask.cpp GeneralServer/HttpServerJob.cpp
HttpServer/HttpServer.cpp GeneralServer/GeneralCommTask.cpp
HttpServer/HttpServerJob.cpp GeneralServer/HttpCommTask.cpp
HttpServer/HttpsCommTask.cpp GeneralServer/HttpsCommTask.cpp
HttpServer/HttpsServer.cpp GeneralServer/GeneralListenTask.cpp
HttpServer/RestHandler.cpp GeneralServer/GeneralServer.cpp
HttpServer/RestHandlerFactory.cpp GeneralServer/RestHandler.cpp
HttpServer/PathHandler.cpp GeneralServer/RestHandlerFactory.cpp
GeneralServer/PathHandler.cpp
Indexes/EdgeIndex.cpp Indexes/EdgeIndex.cpp
Indexes/FulltextIndex.cpp Indexes/FulltextIndex.cpp
Indexes/GeoIndex2.cpp Indexes/GeoIndex2.cpp

View File

@ -39,7 +39,7 @@
#include "Dispatcher/Dispatcher.h" #include "Dispatcher/Dispatcher.h"
#include "Dispatcher/DispatcherFeature.h" #include "Dispatcher/DispatcherFeature.h"
#include "Dispatcher/Job.h" #include "Dispatcher/Job.h"
#include "HttpServer/RestHandlerFactory.h" #include "GeneralServer/RestHandlerFactory.h"
#include "Logger/Logger.h" #include "Logger/Logger.h"
#include "RestServer/RestServerFeature.h" #include "RestServer/RestServerFeature.h"
#include "V8/v8-globals.h" #include "V8/v8-globals.h"
@ -128,30 +128,30 @@ void HeartbeatThread::runDBServer() {
std::function<bool(VPackSlice const& result)> updatePlan = std::function<bool(VPackSlice const& result)> updatePlan =
[&](VPackSlice const& result) { [&](VPackSlice const& result) {
if (!result.isNumber()) { if (!result.isNumber()) {
LOG_TOPIC(ERR, Logger::HEARTBEAT) << "Plan Version is not a number! " LOG_TOPIC(ERR, Logger::HEARTBEAT) << "Plan Version is not a number! "
<< result.toJson(); << result.toJson();
return false; return false;
} }
uint64_t version = result.getNumber<uint64_t>(); uint64_t version = result.getNumber<uint64_t>();
bool doSync = false; bool doSync = false;
{ {
MUTEX_LOCKER(mutexLocker, _statusLock); MUTEX_LOCKER(mutexLocker, _statusLock);
if (version > _desiredVersions.plan) { if (version > _desiredVersions.plan) {
_desiredVersions.plan = version; _desiredVersions.plan = version;
LOG_TOPIC(DEBUG, Logger::HEARTBEAT) LOG_TOPIC(DEBUG, Logger::HEARTBEAT) << "Desired Current Version is now "
<< "Desired Current Version is now " << _desiredVersions.plan; << _desiredVersions.plan;
doSync = true; doSync = true;
} }
} }
if (doSync) { if (doSync) {
syncDBServerStatusQuo(); syncDBServerStatusQuo();
} }
return true; return true;
}; };
auto planAgencyCallback = std::make_shared<AgencyCallback>( auto planAgencyCallback = std::make_shared<AgencyCallback>(
_agency, "Plan/Version", updatePlan, true); _agency, "Plan/Version", updatePlan, true);
@ -610,14 +610,15 @@ bool HeartbeatThread::syncDBServerStatusQuo() {
if (becauseOfCurrent) { if (becauseOfCurrent) {
ci->invalidateCurrent(); ci->invalidateCurrent();
} }
// only warn if the application server is still there and dispatching // only warn if the application server is still there and dispatching
// should succeed // should succeed
bool warn = false; bool warn = false;
application_features::ApplicationServer* server = application_features::ApplicationServer::server; application_features::ApplicationServer* server =
application_features::ApplicationServer::server;
if (server != nullptr) { if (server != nullptr) {
auto state = server->state(); 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::IN_UNPREPARE &&
state != application_features::ServerState::STOPPED && state != application_features::ServerState::STOPPED &&
state != application_features::ServerState::ABORT); state != application_features::ServerState::ABORT);

View File

@ -25,8 +25,8 @@
#include "Basics/ReadLocker.h" #include "Basics/ReadLocker.h"
#include "Basics/WriteLocker.h" #include "Basics/WriteLocker.h"
#include "HttpServer/HttpServerJob.h" #include "GeneralServer/HttpServerJob.h"
#include "HttpServer/RestHandler.h" #include "GeneralServer/RestHandler.h"
#include "Logger/Logger.h" #include "Logger/Logger.h"
#include "Rest/GeneralResponse.h" #include "Rest/GeneralResponse.h"

View File

@ -22,15 +22,15 @@
/// @author Dr. Frank Celler /// @author Dr. Frank Celler
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include "HttpCommTask.h" #include "GeneralCommTask.h"
#include "Basics/HybridLogicalClock.h" #include "Basics/HybridLogicalClock.h"
#include "Basics/MutexLocker.h" #include "Basics/MutexLocker.h"
#include "Basics/StaticStrings.h" #include "Basics/StaticStrings.h"
#include "Basics/StringBuffer.h" #include "Basics/StringBuffer.h"
#include "HttpServer/HttpServer.h" #include "GeneralServer/GeneralServer.h"
#include "HttpServer/RestHandler.h" #include "GeneralServer/RestHandler.h"
#include "HttpServer/RestHandlerFactory.h" #include "GeneralServer/RestHandlerFactory.h"
#include "Logger/Logger.h" #include "Logger/Logger.h"
#include "RestServer/RestServerFeature.h" #include "RestServer/RestServerFeature.h"
#include "Scheduler/Scheduler.h" #include "Scheduler/Scheduler.h"
@ -45,22 +45,24 @@ using namespace arangodb::rest;
/// @brief static initializers /// @brief static initializers
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
size_t const HttpCommTask::MaximalHeaderSize = 1 * 1024 * 1024; // 1 MB size_t const GeneralCommTask::MaximalHeaderSize = 1 * 1024 * 1024; // 1 MB
size_t const HttpCommTask::MaximalBodySize = 512 * 1024 * 1024; // 512 MB size_t const GeneralCommTask::MaximalBodySize = 512 * 1024 * 1024; // 512 MB
size_t const HttpCommTask::MaximalPipelineSize = 512 * 1024 * 1024; // 512 MB size_t const GeneralCommTask::MaximalPipelineSize =
size_t const HttpCommTask::RunCompactEvery = 500; 512 * 1024 * 1024; // 512 MB
size_t const GeneralCommTask::RunCompactEvery = 500;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a new task /// @brief constructs a new task
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
HttpCommTask::HttpCommTask(HttpServer* server, TRI_socket_t socket, GeneralCommTask::GeneralCommTask(GeneralServer* server, TRI_socket_t socket,
ConnectionInfo&& info, double keepAliveTimeout) ConnectionInfo&& info, double keepAliveTimeout)
: Task("HttpCommTask"), : Task("GeneralCommTask"),
SocketTask(socket, keepAliveTimeout), SocketTask(socket, keepAliveTimeout),
_connectionInfo(std::move(info)), _connectionInfo(std::move(info)),
_server(server), _server(server),
_allowMethodOverride(server->allowMethodOverride()), _allowMethodOverride(server->allowMethodOverride()),
_protocol("unknown"),
_writeBuffers(), _writeBuffers(),
_writeBuffersStats(), _writeBuffersStats(),
_readPosition(0), _readPosition(0),
@ -97,7 +99,7 @@ HttpCommTask::HttpCommTask(HttpServer* server, TRI_socket_t socket,
/// @brief destructs a task /// @brief destructs a task
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
HttpCommTask::~HttpCommTask() { GeneralCommTask::~GeneralCommTask() {
LOG(TRACE) << "connection closed, client " LOG(TRACE) << "connection closed, client "
<< TRI_get_fd_or_handle_of_socket(_commSocket); << TRI_get_fd_or_handle_of_socket(_commSocket);
@ -114,7 +116,7 @@ HttpCommTask::~HttpCommTask() {
delete _request; delete _request;
} }
void HttpCommTask::handleResponse(HttpResponse* response) { void GeneralCommTask::handleResponse(HttpResponse* response) {
_requestPending = false; _requestPending = false;
_isChunked = false; _isChunked = false;
_startThread = 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); HttpResponse response(code);
resetState(true); resetState(true);
addResponse(&response); addResponse(&response);
} }
void HttpCommTask::handleSimpleError(GeneralResponse::ResponseCode responseCode, void GeneralCommTask::handleSimpleError(
int errorNum, GeneralResponse::ResponseCode responseCode, int errorNum,
std::string const& errorMessage) { std::string const& errorMessage) {
HttpResponse response(responseCode); HttpResponse response(responseCode);
VPackBuilder builder; VPackBuilder builder;
@ -147,7 +149,8 @@ void HttpCommTask::handleSimpleError(GeneralResponse::ResponseCode responseCode,
builder.close(); builder.close();
try { try {
response.setPayload(_request, builder.slice(), true, VPackOptions::Defaults); response.setPayload(_request, builder.slice(), true,
VPackOptions::Defaults);
clearRequest(); clearRequest();
handleResponse(&response); 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(); auto context = (_request == nullptr) ? nullptr : _request->requestContext();
if (context == nullptr && _request != nullptr) { if (context == nullptr && _request != nullptr) {
@ -181,7 +184,7 @@ GeneralResponse::ResponseCode HttpCommTask::authenticateRequest() {
/// @brief reads data from the socket /// @brief reads data from the socket
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool HttpCommTask::processRead() { bool GeneralCommTask::processRead() {
if (_requestPending || _readBuffer->c_str() == nullptr) { if (_requestPending || _readBuffer->c_str() == nullptr) {
return false; return false;
} }
@ -296,7 +299,7 @@ bool HttpCommTask::processRead() {
// update the connection information, i. e. client and server addresses // update the connection information, i. e. client and server addresses
// and ports // and ports
_request->setProtocol(_server->protocol()); _request->setProtocol(_protocol);
LOG(TRACE) << "server port " << _connectionInfo.serverPort LOG(TRACE) << "server port " << _connectionInfo.serverPort
<< ", client port " << _connectionInfo.clientPort; << ", client port " << _connectionInfo.clientPort;
@ -321,10 +324,11 @@ bool HttpCommTask::processRead() {
// if the request asks to allow credentials, we'll check against the // if the request asks to allow credentials, we'll check against the
// configured whitelist of origins // configured whitelist of origins
std::vector<std::string> const& accessControlAllowOrigins = _server->trustedOrigins(); std::vector<std::string> const& accessControlAllowOrigins =
_server->trustedOrigins();
if (StringUtils::boolean(allowCredentials) && if (StringUtils::boolean(allowCredentials) &&
!accessControlAllowOrigins.empty()) { !accessControlAllowOrigins.empty()) {
if (accessControlAllowOrigins[0] == "*") { if (accessControlAllowOrigins[0] == "*") {
// special case: allow everything // special case: allow everything
_denyCredentials = false; _denyCredentials = false;
@ -332,10 +336,14 @@ bool HttpCommTask::processRead() {
// copy origin string // copy origin string
if (_origin[_origin.size() - 1] == '/') { if (_origin[_origin.size() - 1] == '/') {
// strip trailing slash // 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()); _denyCredentials = (result == accessControlAllowOrigins.end());
} else { } else {
auto result = std::find(accessControlAllowOrigins.begin(), accessControlAllowOrigins.end(), _origin); auto result =
std::find(accessControlAllowOrigins.begin(),
accessControlAllowOrigins.end(), _origin);
_denyCredentials = (result == accessControlAllowOrigins.end()); _denyCredentials = (result == accessControlAllowOrigins.end());
} }
} else { } else {
@ -545,8 +553,7 @@ bool HttpCommTask::processRead() {
// not authenticated // not authenticated
else { else {
HttpResponse response(GeneralResponse::ResponseCode::UNAUTHORIZED); HttpResponse response(GeneralResponse::ResponseCode::UNAUTHORIZED);
std::string realm = std::string realm = "Bearer token_type=\"JWT\", realm=\"ArangoDB\"";
"Bearer token_type=\"JWT\", realm=\"ArangoDB\"";
response.setHeaderNC(StaticStrings::WwwAuthenticate, std::move(realm)); response.setHeaderNC(StaticStrings::WwwAuthenticate, std::move(realm));
@ -561,7 +568,7 @@ bool HttpCommTask::processRead() {
/// @brief sends more chunked data /// @brief sends more chunked data
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void HttpCommTask::sendChunk(StringBuffer* buffer) { void GeneralCommTask::sendChunk(StringBuffer* buffer) {
if (_isChunked) { if (_isChunked) {
TRI_ASSERT(buffer != nullptr); TRI_ASSERT(buffer != nullptr);
@ -578,7 +585,7 @@ void HttpCommTask::sendChunk(StringBuffer* buffer) {
/// @brief chunking is finished /// @brief chunking is finished
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void HttpCommTask::finishedChunked() { void GeneralCommTask::finishedChunked() {
auto buffer = std::make_unique<StringBuffer>(TRI_UNKNOWN_MEM_ZONE, 6, true); auto buffer = std::make_unique<StringBuffer>(TRI_UNKNOWN_MEM_ZONE, 6, true);
buffer->appendText(TRI_CHAR_LENGTH_PAIR("0\r\n\r\n")); buffer->appendText(TRI_CHAR_LENGTH_PAIR("0\r\n\r\n"));
buffer->ensureNullTerminated(); buffer->ensureNullTerminated();
@ -599,7 +606,7 @@ void HttpCommTask::finishedChunked() {
/// @brief task set up complete /// @brief task set up complete
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void HttpCommTask::setupDone() { void GeneralCommTask::setupDone() {
_setupDone.store(true, std::memory_order_relaxed); _setupDone.store(true, std::memory_order_relaxed);
} }
@ -607,7 +614,7 @@ void HttpCommTask::setupDone() {
/// @brief reads data from the socket /// @brief reads data from the socket
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void HttpCommTask::addResponse(HttpResponse* response) { void GeneralCommTask::addResponse(HttpResponse* response) {
// CORS response handling // CORS response handling
if (!_origin.empty()) { if (!_origin.empty()) {
// the request contained an Origin header. We have to send back the // 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 /// 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(); int64_t const bodyLength = _request->contentLength();
if (bodyLength < 0) { if (bodyLength < 0) {
@ -749,7 +756,7 @@ bool HttpCommTask::checkContentLength(bool expectContentLength) {
/// @brief fills the write buffer /// @brief fills the write buffer
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void HttpCommTask::fillWriteBuffer() { void GeneralCommTask::fillWriteBuffer() {
if (!hasWriteBuffer() && !_writeBuffers.empty()) { if (!hasWriteBuffer() && !_writeBuffers.empty()) {
StringBuffer* buffer = _writeBuffers.front(); StringBuffer* buffer = _writeBuffers.front();
_writeBuffers.pop_front(); _writeBuffers.pop_front();
@ -767,7 +774,7 @@ void HttpCommTask::fillWriteBuffer() {
/// @brief handles CORS options /// @brief handles CORS options
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void HttpCommTask::processCorsOptions() { void GeneralCommTask::processCorsOptions() {
HttpResponse response(GeneralResponse::ResponseCode::OK); HttpResponse response(GeneralResponse::ResponseCode::OK);
response.setHeaderNC(StaticStrings::Allow, StaticStrings::CorsMethods); response.setHeaderNC(StaticStrings::Allow, StaticStrings::CorsMethods);
@ -807,7 +814,7 @@ void HttpCommTask::processCorsOptions() {
/// @brief processes a request /// @brief processes a request
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void HttpCommTask::processRequest() { void GeneralCommTask::processRequest() {
// check for deflate // check for deflate
bool found; bool found;
std::string const& acceptEncoding = std::string const& acceptEncoding =
@ -837,10 +844,11 @@ void HttpCommTask::processRequest() {
} }
// check for an HLC time stamp // 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) { if (found) {
uint64_t timeStampInt uint64_t timeStampInt =
= arangodb::basics::HybridLogicalClock::decodeTimeStampWithCheck( arangodb::basics::HybridLogicalClock::decodeTimeStampWithCheck(
timeStamp); timeStamp);
if (timeStampInt != 0) { if (timeStampInt != 0) {
TRI_HybridLogicalClock(timeStampInt); TRI_HybridLogicalClock(timeStampInt);
@ -872,7 +880,8 @@ void HttpCommTask::processRequest() {
if (_request != nullptr) { if (_request != nullptr) {
bool found; bool found;
std::string const& startThread = _request->header(StaticStrings::StartThread, found); std::string const& startThread =
_request->header(StaticStrings::StartThread, found);
if (found) { if (found) {
_startThread = StringUtils::boolean(startThread); _startThread = StringUtils::boolean(startThread);
@ -927,7 +936,7 @@ void HttpCommTask::processRequest() {
/// @brief clears the request object /// @brief clears the request object
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void HttpCommTask::clearRequest() { void GeneralCommTask::clearRequest() {
delete _request; delete _request;
_request = nullptr; _request = nullptr;
} }
@ -939,7 +948,7 @@ void HttpCommTask::clearRequest() {
/// prematurely /// prematurely
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void HttpCommTask::resetState(bool close) { void GeneralCommTask::resetState(bool close) {
if (close) { if (close) {
clearRequest(); clearRequest();
@ -985,7 +994,7 @@ void HttpCommTask::resetState(bool close) {
_startThread = false; _startThread = false;
} }
bool HttpCommTask::setup(Scheduler* scheduler, EventLoop loop) { bool GeneralCommTask::setup(Scheduler* scheduler, EventLoop loop) {
bool ok = SocketTask::setup(scheduler, loop); bool ok = SocketTask::setup(scheduler, loop);
if (!ok) { if (!ok) {
@ -1000,9 +1009,9 @@ bool HttpCommTask::setup(Scheduler* scheduler, EventLoop loop) {
return true; 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); bool result = SocketTask::handleEvent(token, events);
if (_clientClosed) { if (_clientClosed) {
@ -1012,7 +1021,7 @@ bool HttpCommTask::handleEvent(EventToken token, EventType events) {
return result; return result;
} }
void HttpCommTask::signalTask(TaskData* data) { void GeneralCommTask::signalTask(TaskData* data) {
// data response // data response
if (data->_type == TaskData::TASK_DATA_RESPONSE) { if (data->_type == TaskData::TASK_DATA_RESPONSE) {
data->RequestStatisticsAgent::transferTo(this); data->RequestStatisticsAgent::transferTo(this);
@ -1064,7 +1073,7 @@ void HttpCommTask::signalTask(TaskData* data) {
} }
} }
bool HttpCommTask::handleRead() { bool GeneralCommTask::handleRead() {
bool res = true; bool res = true;
if (!_setupDone.load(std::memory_order_relaxed)) { if (!_setupDone.load(std::memory_order_relaxed)) {
@ -1097,7 +1106,7 @@ bool HttpCommTask::handleRead() {
return res; return res;
} }
void HttpCommTask::completedWriteBuffer() { void GeneralCommTask::completedWriteBuffer() {
_writeBuffer = nullptr; _writeBuffer = nullptr;
_writeLength = 0; _writeLength = 0;
@ -1117,7 +1126,7 @@ void HttpCommTask::completedWriteBuffer() {
} }
} }
void HttpCommTask::handleTimeout() { void GeneralCommTask::handleTimeout() {
_clientClosed = true; _clientClosed = true;
_server->handleCommunicationClosed(this); _server->handleCommunicationClosed(this);
} }

View File

@ -38,11 +38,11 @@ class HttpRequest;
class HttpResponse; class HttpResponse;
namespace rest { namespace rest {
class HttpServer; class GeneralServer;
class HttpCommTask : public SocketTask, public RequestStatisticsAgent { class GeneralCommTask : public SocketTask, public RequestStatisticsAgent {
HttpCommTask(HttpCommTask const&) = delete; GeneralCommTask(GeneralCommTask const&) = delete;
HttpCommTask const& operator=(HttpCommTask const&) = delete; GeneralCommTask const& operator=(GeneralCommTask const&) = delete;
public: public:
static size_t const MaximalHeaderSize; static size_t const MaximalHeaderSize;
@ -51,11 +51,11 @@ class HttpCommTask : public SocketTask, public RequestStatisticsAgent {
static size_t const RunCompactEvery; static size_t const RunCompactEvery;
public: public:
HttpCommTask(HttpServer*, TRI_socket_t, ConnectionInfo&&, GeneralCommTask(GeneralServer*, TRI_socket_t, ConnectionInfo&&,
double keepAliveTimeout); double keepAliveTimeout);
protected: protected:
~HttpCommTask(); ~GeneralCommTask();
public: public:
// return whether or not the task desires to start a dispatcher thread // return whether or not the task desires to start a dispatcher thread
@ -128,11 +128,13 @@ class HttpCommTask : public SocketTask, public RequestStatisticsAgent {
ConnectionInfo _connectionInfo; ConnectionInfo _connectionInfo;
// the underlying server // the underlying server
HttpServer* const _server; GeneralServer* const _server;
// allow method override // allow method override
bool _allowMethodOverride; bool _allowMethodOverride;
char const* _protocol;
private: private:
// write buffers // write buffers
std::deque<basics::StringBuffer*> _writeBuffers; std::deque<basics::StringBuffer*> _writeBuffers;
@ -169,7 +171,7 @@ class HttpCommTask : public SocketTask, public RequestStatisticsAgent {
// true if within a chunked response // true if within a chunked response
bool _isChunked; bool _isChunked;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief start a separate thread if the task is added to the dispatcher? /// @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 // authentication real
std::string const _authenticationRealm; std::string const _authenticationRealm;
};
} }; // Commontask
} } // rest
} // arango
#endif #endif

View File

@ -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

View File

@ -22,9 +22,9 @@
/// @author Achim Brandt /// @author Achim Brandt
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include "HttpListenTask.h" #include "GeneralListenTask.h"
#include "HttpServer/HttpServer.h" #include "GeneralServer/GeneralServer.h"
using namespace arangodb; using namespace arangodb;
using namespace arangodb::rest; using namespace arangodb::rest;
@ -33,11 +33,14 @@ using namespace arangodb::rest;
/// @brief listen to given port /// @brief listen to given port
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
HttpListenTask::HttpListenTask(HttpServer* server, Endpoint* endpoint) GeneralListenTask::GeneralListenTask(GeneralServer* server, Endpoint* endpoint,
: Task("HttpListenTask"), ListenTask(endpoint), _server(server) {} ConnectionType connectionType)
: Task("GeneralListenTask"),
ListenTask(endpoint),
_server(server),
_connectionType(connectionType) {}
bool HttpListenTask::handleConnected(TRI_socket_t s, bool GeneralListenTask::handleConnected(TRI_socket_t s, ConnectionInfo&& info) {
ConnectionInfo&& info) { _server->handleConnected(s, std::move(info), _connectionType);
_server->handleConnected(s, std::move(info));
return true; return true;
} }

View File

@ -26,27 +26,29 @@
#define ARANGOD_HTTP_SERVER_HTTP_LISTEN_TASK_H 1 #define ARANGOD_HTTP_SERVER_HTTP_LISTEN_TASK_H 1
#include "Scheduler/ListenTask.h" #include "Scheduler/ListenTask.h"
#include "GeneralServer/GeneralDefinitions.h"
namespace arangodb { namespace arangodb {
class Endpoint; class Endpoint;
namespace rest { namespace rest {
class HttpServer; class GeneralServer;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief task used to establish connections /// @brief task used to establish connections
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class HttpListenTask : public ListenTask { class GeneralListenTask : public ListenTask {
HttpListenTask(HttpListenTask const&) = delete; GeneralListenTask(GeneralListenTask const&) = delete;
HttpListenTask& operator=(HttpListenTask const&) = delete; GeneralListenTask& operator=(GeneralListenTask const&) = delete;
public: public:
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief listen to given port /// @brief listen to given port
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
HttpListenTask(HttpServer* server, Endpoint* endpoint); GeneralListenTask(GeneralServer* server, Endpoint* endpoint,
ConnectionType connectionType);
protected: protected:
bool handleConnected(TRI_socket_t s, ConnectionInfo&& info) override; bool handleConnected(TRI_socket_t s, ConnectionInfo&& info) override;
@ -56,7 +58,8 @@ class HttpListenTask : public ListenTask {
/// @brief underlying general server /// @brief underlying general server
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
HttpServer* _server; GeneralServer* _server;
ConnectionType _connectionType;
}; };
} }
} }

View File

@ -22,18 +22,18 @@
/// @author Achim Brandt /// @author Achim Brandt
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include "HttpServer.h" #include "GeneralServer.h"
#include "Basics/MutexLocker.h" #include "Basics/MutexLocker.h"
#include "Basics/WorkMonitor.h" #include "Basics/WorkMonitor.h"
#include "Dispatcher/Dispatcher.h" #include "Dispatcher/Dispatcher.h"
#include "Dispatcher/DispatcherFeature.h" #include "Dispatcher/DispatcherFeature.h"
#include "Endpoint/EndpointList.h" #include "Endpoint/EndpointList.h"
#include "HttpServer/AsyncJobManager.h" #include "GeneralServer/AsyncJobManager.h"
#include "HttpServer/HttpCommTask.h" #include "GeneralServer/GeneralCommTask.h"
#include "HttpServer/HttpListenTask.h" #include "GeneralServer/GeneralListenTask.h"
#include "HttpServer/HttpServerJob.h" #include "GeneralServer/HttpServerJob.h"
#include "HttpServer/RestHandler.h" #include "GeneralServer/RestHandler.h"
#include "Logger/Logger.h" #include "Logger/Logger.h"
#include "RestServer/RestServerFeature.h" #include "RestServer/RestServerFeature.h"
#include "Scheduler/ListenTask.h" #include "Scheduler/ListenTask.h"
@ -48,7 +48,7 @@ using namespace arangodb::rest;
/// @brief destroys an endpoint server /// @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>(); auto taskData = std::make_unique<TaskData>();
taskData->_taskId = taskId; 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 /// @brief constructs a new general server with dispatcher and job manager
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
HttpServer::HttpServer( GeneralServer::GeneralServer(
double keepAliveTimeout, double keepAliveTimeout, bool allowMethodOverride,
bool allowMethodOverride, std::vector<std::string> const& accessControlAllowOrigins, SSL_CTX* ctx)
std::vector<std::string> const& accessControlAllowOrigins)
: _listenTasks(), : _listenTasks(),
_endpointList(nullptr), _endpointList(nullptr),
_commTasks(), _commTasks(),
_keepAliveTimeout(keepAliveTimeout), _keepAliveTimeout(keepAliveTimeout),
_allowMethodOverride(allowMethodOverride), _allowMethodOverride(allowMethodOverride),
_accessControlAllowOrigins(accessControlAllowOrigins) {} _accessControlAllowOrigins(accessControlAllowOrigins),
_ctx(ctx),
_verificationMode(SSL_VERIFY_NONE),
_verificationCallback(nullptr),
_sslAllowed(ctx != nullptr) {}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief destructs a general server /// @brief destructs a general server
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
HttpServer::~HttpServer() { stopListening(); } GeneralServer::~GeneralServer() { stopListening(); }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief generates a suitable communication task /// @brief generates a suitable communication task
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
HttpCommTask* HttpServer::createCommTask(TRI_socket_t s, GeneralCommTask* GeneralServer::createCommTask(TRI_socket_t s,
ConnectionInfo&& info) { ConnectionInfo&& info,
return new HttpCommTask(this, s, std::move(info), _keepAliveTimeout); 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 /// @brief add the endpoint list
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void HttpServer::setEndpointList(EndpointList const* list) { void GeneralServer::setEndpointList(EndpointList const* list) {
_endpointList = list; _endpointList = list;
} }
@ -103,11 +117,8 @@ void HttpServer::setEndpointList(EndpointList const* list) {
/// @brief starts listening /// @brief starts listening
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void HttpServer::startListening() { void GeneralServer::startListening() {
auto endpoints = for (auto& it : _endpointList->allEndpoints()) {
_endpointList->matching(Endpoint::TransportType::HTTP, encryptionType());
for (auto& it : endpoints) {
LOG(TRACE) << "trying to bind to endpoint '" << it.first LOG(TRACE) << "trying to bind to endpoint '" << it.first
<< "' for requests"; << "' for requests";
@ -118,7 +129,8 @@ void HttpServer::startListening() {
} else { } else {
LOG(FATAL) << "failed to bind to endpoint '" << it.first LOG(FATAL) << "failed to bind to endpoint '" << it.first
<< "'. Please check whether another instance is already " << "'. 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(); FATAL_ERROR_EXIT();
} }
} }
@ -128,7 +140,7 @@ void HttpServer::startListening() {
/// @brief stops listening /// @brief stops listening
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void HttpServer::stopListening() { void GeneralServer::stopListening() {
for (auto& task : _listenTasks) { for (auto& task : _listenTasks) {
SchedulerFeature::SCHEDULER->destroyTask(task); SchedulerFeature::SCHEDULER->destroyTask(task);
} }
@ -140,9 +152,9 @@ void HttpServer::stopListening() {
/// @brief removes all listen and comm tasks /// @brief removes all listen and comm tasks
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void HttpServer::stop() { void GeneralServer::stop() {
while (true) { while (true) {
HttpCommTask* task = nullptr; GeneralCommTask* task = nullptr;
{ {
MUTEX_LOCKER(mutexLocker, _commTasksLock); MUTEX_LOCKER(mutexLocker, _commTasksLock);
@ -163,8 +175,9 @@ void HttpServer::stop() {
/// @brief handles connection request /// @brief handles connection request
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void HttpServer::handleConnected(TRI_socket_t s, ConnectionInfo&& info) { void GeneralServer::handleConnected(TRI_socket_t s, ConnectionInfo&& info,
HttpCommTask* task = createCommTask(s, std::move(info)); ConnectionType connectionType) {
GeneralCommTask* task = createCommTask(s, std::move(info), connectionType);
try { try {
MUTEX_LOCKER(mutexLocker, _commTasksLock); MUTEX_LOCKER(mutexLocker, _commTasksLock);
@ -184,7 +197,7 @@ void HttpServer::handleConnected(TRI_socket_t s, ConnectionInfo&& info) {
/// @brief handles a connection close /// @brief handles a connection close
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void HttpServer::handleCommunicationClosed(HttpCommTask* task) { void GeneralServer::handleCommunicationClosed(GeneralCommTask* task) {
MUTEX_LOCKER(mutexLocker, _commTasksLock); MUTEX_LOCKER(mutexLocker, _commTasksLock);
_commTasks.erase(task); _commTasks.erase(task);
} }
@ -193,7 +206,7 @@ void HttpServer::handleCommunicationClosed(HttpCommTask* task) {
/// @brief handles a connection failure /// @brief handles a connection failure
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void HttpServer::handleCommunicationFailure(HttpCommTask* task) { void GeneralServer::handleCommunicationFailure(GeneralCommTask* task) {
MUTEX_LOCKER(mutexLocker, _commTasksLock); MUTEX_LOCKER(mutexLocker, _commTasksLock);
_commTasks.erase(task); _commTasks.erase(task);
} }
@ -202,9 +215,9 @@ void HttpServer::handleCommunicationFailure(HttpCommTask* task) {
/// @brief create a job for asynchronous execution (using the dispatcher) /// @brief create a job for asynchronous execution (using the dispatcher)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool HttpServer::handleRequestAsync(HttpCommTask* task, bool GeneralServer::handleRequestAsync(GeneralCommTask* task,
WorkItem::uptr<RestHandler>& handler, WorkItem::uptr<RestHandler>& handler,
uint64_t* jobId) { uint64_t* jobId) {
bool startThread = task->startThread(); bool startThread = task->startThread();
// extract the coordinator flag // extract the coordinator flag
@ -248,8 +261,8 @@ bool HttpServer::handleRequestAsync(HttpCommTask* task,
/// @brief executes the handler directly or add it to the queue /// @brief executes the handler directly or add it to the queue
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool HttpServer::handleRequest(HttpCommTask* task, bool GeneralServer::handleRequest(GeneralCommTask* task,
WorkItem::uptr<RestHandler>& handler) { WorkItem::uptr<RestHandler>& handler) {
// direct handlers // direct handlers
if (handler->isDirect()) { if (handler->isDirect()) {
HandlerWorkStack work(handler); HandlerWorkStack work(handler);
@ -264,7 +277,7 @@ bool HttpServer::handleRequest(HttpCommTask* task,
std::unique_ptr<Job> job = std::make_unique<HttpServerJob>(this, handler); std::unique_ptr<Job> job = std::make_unique<HttpServerJob>(this, handler);
task->RequestStatisticsAgent::transferTo(job.get()); task->RequestStatisticsAgent::transferTo(job.get());
LOG(TRACE) << "HttpCommTask " << (void*)task << " created HttpServerJob " LOG(TRACE) << "GeneralCommTask " << (void*)task << " created HttpServerJob "
<< (void*)job.get(); << (void*)job.get();
// add the job to the dispatcher // add the job to the dispatcher
@ -278,8 +291,32 @@ bool HttpServer::handleRequest(HttpCommTask* task,
/// @brief opens a listen port /// @brief opens a listen port
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool HttpServer::openEndpoint(Endpoint* endpoint) { bool GeneralServer::openEndpoint(Endpoint* endpoint) {
ListenTask* task = new HttpListenTask(this, 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 - // 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 /// @brief handle request directly
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void HttpServer::handleRequestDirectly(RestHandler* handler, void GeneralServer::handleRequestDirectly(RestHandler* handler,
HttpCommTask* task) { GeneralCommTask* task) {
task->RequestStatisticsAgent::transferTo(handler); task->RequestStatisticsAgent::transferTo(handler);
RestHandler::status result = handler->executeFull(); RestHandler::status result = handler->executeFull();
handler->RequestStatisticsAgent::transferTo(task); handler->RequestStatisticsAgent::transferTo(task);

View File

@ -26,11 +26,14 @@
#ifndef ARANGOD_HTTP_SERVER_HTTP_SERVER_H #ifndef ARANGOD_HTTP_SERVER_HTTP_SERVER_H
#define ARANGOD_HTTP_SERVER_HTTP_SERVER_H 1 #define ARANGOD_HTTP_SERVER_HTTP_SERVER_H 1
#include "GeneralServer/GeneralDefinitions.h"
#include "Scheduler/TaskManager.h" #include "Scheduler/TaskManager.h"
#include "Basics/Mutex.h" #include "Basics/Mutex.h"
#include "Endpoint/ConnectionInfo.h" #include "Endpoint/ConnectionInfo.h"
#include "HttpServer/RestHandler.h" #include "GeneralServer/RestHandler.h"
#include "GeneralServer/HttpCommTask.h"
#include "GeneralServer/HttpsCommTask.h"
#include <openssl/ssl.h>
namespace arangodb { namespace arangodb {
class EndpointList; class EndpointList;
@ -39,46 +42,45 @@ namespace rest {
class AsyncJobManager; class AsyncJobManager;
class Dispatcher; class Dispatcher;
class HttpCommTask; class GeneralCommTask;
class HttpServerJob; class HttpServerJob;
class Job; class Job;
class ListenTask; class ListenTask;
class RestHandlerFactory; class RestHandlerFactory;
class HttpServer : protected TaskManager { class GeneralServer : protected TaskManager {
HttpServer(HttpServer const&) = delete; GeneralServer(GeneralServer const&) = delete;
HttpServer const& operator=(HttpServer const&) = delete; GeneralServer const& operator=(GeneralServer const&) = delete;
public: public:
// destroys an endpoint server // destroys an endpoint server
static int sendChunk(uint64_t, std::string const&); static int sendChunk(uint64_t, std::string const&);
public: public:
HttpServer(double keepAliveTimeout, GeneralServer(double keepAliveTimeout, bool allowMethodOverride,
bool allowMethodOverride, std::vector<std::string> const& accessControlAllowOrigins,
std::vector<std::string> const& accessControlAllowOrigins); SSL_CTX* ctx = nullptr);
virtual ~HttpServer(); virtual ~GeneralServer();
public: public:
// returns the protocol // returns the protocol
virtual char const* protocol() const { return "http"; } // virtual char const* protocol() const { return "http"; }
// returns the encryption to be used
virtual Endpoint::EncryptionType encryptionType() const {
return Endpoint::EncryptionType::NONE;
}
// check, if we allow a method override // check, if we allow a method override
bool allowMethodOverride() { bool allowMethodOverride() { return _allowMethodOverride; }
return _allowMethodOverride;
}
// generates a suitable communication task // 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: public:
// list of trusted origin urls for CORS // list of trusted origin urls for CORS
std::vector<std::string> const& trustedOrigins() const { std::vector<std::string> const& trustedOrigins() const {
return _accessControlAllowOrigins; return _accessControlAllowOrigins;
} }
@ -95,26 +97,27 @@ class HttpServer : protected TaskManager {
void stop(); void stop();
// handles connection request // handles connection request
void handleConnected(TRI_socket_t s, ConnectionInfo&& info); void handleConnected(TRI_socket_t s, ConnectionInfo&& info, ConnectionType);
// handles a connection close // handles a connection close
void handleCommunicationClosed(HttpCommTask*); void handleCommunicationClosed(GeneralCommTask*);
// handles a connection failure // handles a connection failure
void handleCommunicationFailure(HttpCommTask*); void handleCommunicationFailure(GeneralCommTask*);
// creates a job for asynchronous execution // creates a job for asynchronous execution
bool handleRequestAsync(HttpCommTask*, arangodb::WorkItem::uptr<RestHandler>&, bool handleRequestAsync(GeneralCommTask*,
arangodb::WorkItem::uptr<RestHandler>&,
uint64_t* jobId); uint64_t* jobId);
// executes the handler directly or add it to the queue // executes the handler directly or add it to the queue
bool handleRequest(HttpCommTask*, arangodb::WorkItem::uptr<RestHandler>&); bool handleRequest(GeneralCommTask*, arangodb::WorkItem::uptr<RestHandler>&);
protected: protected:
// Handler, Job, and Task tuple // Handler, Job, and Task tuple
struct handler_task_job_t { struct handler_task_job_t {
RestHandler* _handler; RestHandler* _handler;
HttpCommTask* _task; GeneralCommTask* _task;
HttpServerJob* _job; HttpServerJob* _job;
}; };
@ -123,10 +126,10 @@ class HttpServer : protected TaskManager {
bool openEndpoint(Endpoint* endpoint); bool openEndpoint(Endpoint* endpoint);
// handle request directly // handle request directly
void handleRequestDirectly(RestHandler* handler, HttpCommTask* task); void handleRequestDirectly(RestHandler* handler, GeneralCommTask* task);
// registers a task // registers a task
void registerHandler(RestHandler* handler, HttpCommTask* task); void registerHandler(RestHandler* handler, GeneralCommTask* task);
protected: protected:
// active listen tasks // active listen tasks
@ -139,16 +142,22 @@ class HttpServer : protected TaskManager {
arangodb::Mutex _commTasksLock; arangodb::Mutex _commTasksLock;
// active comm tasks // active comm tasks
std::unordered_set<HttpCommTask*> _commTasks; std::unordered_set<GeneralCommTask*> _commTasks;
// keep-alive timeout // keep-alive timeout
double _keepAliveTimeout; double _keepAliveTimeout;
// allow to override the method // allow to override the method
bool _allowMethodOverride; bool _allowMethodOverride;
// list of trusted origin urls for CORS // list of trusted origin urls for CORS
std::vector<std::string> const _accessControlAllowOrigins; std::vector<std::string> const _accessControlAllowOrigins;
private:
SSL_CTX* _ctx;
int _verificationMode;
int (*_verificationCallback)(int, X509_STORE_CTX*);
bool _sslAllowed;
}; };
} }
} }

View File

View File

@ -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

View File

@ -26,10 +26,10 @@
#include "Basics/WorkMonitor.h" #include "Basics/WorkMonitor.h"
#include "Dispatcher/DispatcherQueue.h" #include "Dispatcher/DispatcherQueue.h"
#include "HttpServer/AsyncJobManager.h" #include "GeneralServer/AsyncJobManager.h"
#include "HttpServer/HttpCommTask.h" #include "GeneralServer/GeneralCommTask.h"
#include "HttpServer/HttpServer.h" #include "GeneralServer/GeneralServer.h"
#include "HttpServer/RestHandler.h" #include "GeneralServer/RestHandler.h"
#include "Logger/Logger.h" #include "Logger/Logger.h"
#include "RestServer/RestServerFeature.h" #include "RestServer/RestServerFeature.h"
#include "Scheduler/Scheduler.h" #include "Scheduler/Scheduler.h"
@ -42,7 +42,7 @@ using namespace arangodb::rest;
/// @brief constructs a new server job /// @brief constructs a new server job
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
HttpServerJob::HttpServerJob(HttpServer* server, HttpServerJob::HttpServerJob(GeneralServer* server,
WorkItem::uptr<RestHandler>& handler, bool isAsync) WorkItem::uptr<RestHandler>& handler, bool isAsync)
: Job("HttpServerJob"), : Job("HttpServerJob"),
_server(server), _server(server),

View File

@ -33,14 +33,14 @@
namespace arangodb { namespace arangodb {
namespace rest { namespace rest {
class RestHandler; class RestHandler;
class HttpServer; class GeneralServer;
class HttpServerJob : public Job { class HttpServerJob : public Job {
HttpServerJob(HttpServerJob const&) = delete; HttpServerJob(HttpServerJob const&) = delete;
HttpServerJob& operator=(HttpServerJob const&) = delete; HttpServerJob& operator=(HttpServerJob const&) = delete;
public: public:
HttpServerJob(HttpServer*, arangodb::WorkItem::uptr<RestHandler>&, HttpServerJob(GeneralServer*, arangodb::WorkItem::uptr<RestHandler>&,
bool isAsync = false); bool isAsync = false);
~HttpServerJob(); ~HttpServerJob();
@ -56,7 +56,7 @@ class HttpServerJob : public Job {
void handleError(basics::Exception const&) override; void handleError(basics::Exception const&) override;
protected: protected:
HttpServer* _server; GeneralServer* _server;
arangodb::WorkItem::uptr<RestHandler> _handler; arangodb::WorkItem::uptr<RestHandler> _handler;
arangodb::WorkDescription* _workDesc; arangodb::WorkDescription* _workDesc;
bool _isAsync; bool _isAsync;

View File

@ -23,12 +23,11 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include "HttpsCommTask.h" #include "HttpsCommTask.h"
#include <openssl/err.h> #include <openssl/err.h>
#include "Basics/StringBuffer.h" #include "Basics/StringBuffer.h"
#include "Basics/socket-utils.h" #include "Basics/socket-utils.h"
#include "HttpServer/HttpsServer.h" #include "GeneralServer/GeneralServer.h"
#include "Logger/Logger.h" #include "Logger/Logger.h"
#include "Scheduler/Scheduler.h" #include "Scheduler/Scheduler.h"
#include "Ssl/ssl-helper.h" #include "Ssl/ssl-helper.h"
@ -40,7 +39,7 @@ using namespace arangodb::rest;
/// @brief constructs a new task with a given socket /// @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, ConnectionInfo&& info, double keepAliveTimeout,
SSL_CTX* ctx, int verificationMode, SSL_CTX* ctx, int verificationMode,
int (*verificationCallback)(int, X509_STORE_CTX*)) int (*verificationCallback)(int, X509_STORE_CTX*))

View File

@ -25,13 +25,13 @@
#ifndef ARANGOD_HTTP_SERVER_HTTPS_COMM_TASK_H #ifndef ARANGOD_HTTP_SERVER_HTTPS_COMM_TASK_H
#define ARANGOD_HTTP_SERVER_HTTPS_COMM_TASK_H 1 #define ARANGOD_HTTP_SERVER_HTTPS_COMM_TASK_H 1
#include "HttpServer/HttpCommTask.h" #include "GeneralServer/HttpCommTask.h"
#include <openssl/ssl.h> #include <openssl/ssl.h>
namespace arangodb { namespace arangodb {
namespace rest { namespace rest {
class HttpsServer; class GeneralServer;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief https communication /// @brief https communication
@ -53,7 +53,7 @@ class HttpsCommTask : public HttpCommTask {
/// @brief constructs a new task with a given socket /// @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, double keepAliveTimeout, SSL_CTX* ctx, int verificationMode,
int (*verificationCallback)(int, X509_STORE_CTX*)); int (*verificationCallback)(int, X509_STORE_CTX*));

View File

@ -24,7 +24,7 @@
#ifndef ARANGOD_HTTP_SERVER_PATH_HANDLER_H #ifndef ARANGOD_HTTP_SERVER_PATH_HANDLER_H
#define ARANGOD_HTTP_SERVER_PATH_HANDLER_H 1 #define ARANGOD_HTTP_SERVER_PATH_HANDLER_H 1
#include "HttpServer/RestHandler.h" #include "GeneralServer/RestHandler.h"
namespace arangodb { namespace arangodb {
namespace rest { namespace rest {
@ -53,7 +53,8 @@ class PathHandler : public RestHandler {
}; };
public: public:
static RestHandler* create(GeneralRequest* request, GeneralResponse* response, void* data) { static RestHandler* create(GeneralRequest* request, GeneralResponse* response,
void* data) {
Options* options = static_cast<Options*>(data); Options* options = static_cast<Options*>(data);
return new PathHandler(request, response, options); return new PathHandler(request, response, options);

View File

@ -61,7 +61,7 @@ RestHandler::status RestHandler::executeFull() {
#ifdef USE_DEV_TIMERS #ifdef USE_DEV_TIMERS
TRI_request_statistics_t::STATS = _statistics; TRI_request_statistics_t::STATS = _statistics;
#endif #endif
try { try {
prepareExecute(); prepareExecute();
@ -111,7 +111,7 @@ RestHandler::status RestHandler::executeFull() {
#ifdef USE_DEV_TIMERS #ifdef USE_DEV_TIMERS
TRI_request_statistics_t::STATS = nullptr; TRI_request_statistics_t::STATS = nullptr;
#endif #endif
return result; return result;
} }

View File

@ -58,9 +58,7 @@ class RestHandler : public RequestStatisticsAgent, public arangodb::WorkItem {
virtual bool isDirect() const = 0; virtual bool isDirect() const = 0;
// returns the queue name // returns the queue name
virtual size_t queue() const { virtual size_t queue() const { return Dispatcher::STANDARD_QUEUE; }
return Dispatcher::STANDARD_QUEUE;
}
// prepares execution of a handler, has to be called before execute // prepares execution of a handler, has to be called before execute
virtual void prepareExecute() {} virtual void prepareExecute() {}
@ -72,9 +70,7 @@ class RestHandler : public RequestStatisticsAgent, public arangodb::WorkItem {
virtual void finalizeExecute() {} virtual void finalizeExecute() {}
// tries to cancel an execution // tries to cancel an execution
virtual bool cancel() { virtual bool cancel() { return false; }
return false;
}
// handles error // handles error
virtual void handleError(basics::Exception const&) = 0; virtual void handleError(basics::Exception const&) = 0;
@ -84,14 +80,10 @@ class RestHandler : public RequestStatisticsAgent, public arangodb::WorkItem {
public: public:
// returns the id of the underlying task // returns the id of the underlying task
uint64_t taskId() const { uint64_t taskId() const { return _taskId; }
return _taskId;
}
// returns the event loop of the underlying task // returns the event loop of the underlying task
EventLoop eventLoop() const { EventLoop eventLoop() const { return _loop; }
return _loop;
}
// sets the id of the underlying task or 0 if dettach // sets the id of the underlying task or 0 if dettach
void setTaskId(uint64_t id, EventLoop); void setTaskId(uint64_t id, EventLoop);
@ -100,17 +92,13 @@ class RestHandler : public RequestStatisticsAgent, public arangodb::WorkItem {
status executeFull(); status executeFull();
// return a pointer to the request // return a pointer to the request
GeneralRequest const* request() const { GeneralRequest const* request() const { return _request; }
return _request;
}
// steal the pointer to the request // steal the pointer to the request
GeneralRequest* stealRequest(); GeneralRequest* stealRequest();
// returns the response // returns the response
GeneralResponse* response() const { GeneralResponse* response() const { return _response; }
return _response;
}
// steal the response // steal the response
GeneralResponse* stealResponse(); GeneralResponse* stealResponse();
@ -132,7 +120,7 @@ class RestHandler : public RequestStatisticsAgent, public arangodb::WorkItem {
// the request // the request
GeneralRequest* _request; GeneralRequest* _request;
//OBI-TODO make private // OBI-TODO make private
// the response // the response
GeneralResponse* _response; GeneralResponse* _response;
}; };

View File

@ -24,7 +24,7 @@
#include "RestHandlerFactory.h" #include "RestHandlerFactory.h"
#include "Cluster/ServerState.h" #include "Cluster/ServerState.h"
#include "HttpServer/RestHandler.h" #include "GeneralServer/RestHandler.h"
#include "Logger/Logger.h" #include "Logger/Logger.h"
#include "Rest/GeneralRequest.h" #include "Rest/GeneralRequest.h"
#include "Rest/RequestContext.h" #include "Rest/RequestContext.h"
@ -63,17 +63,13 @@ class MaintenanceHandler : public RestHandler {
RestHandlerFactory::RestHandlerFactory(context_fptr setContext, RestHandlerFactory::RestHandlerFactory(context_fptr setContext,
void* contextData) void* contextData)
: _setContext(setContext), : _setContext(setContext), _contextData(contextData), _notFound(nullptr) {}
_contextData(contextData),
_notFound(nullptr) {}
void RestHandlerFactory::setMaintenance(bool value) { void RestHandlerFactory::setMaintenance(bool value) {
_maintenanceMode.store(value); _maintenanceMode.store(value);
} }
bool RestHandlerFactory::isMaintenance() { bool RestHandlerFactory::isMaintenance() { return _maintenanceMode.load(); }
return _maintenanceMode.load();
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief set request context, wrapper method /// @brief set request context, wrapper method

View File

@ -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<std::string> 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);
}

View File

@ -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 <openssl/ssl.h>
namespace arangodb {
namespace rest {
class HttpsServer : public HttpServer {
public:
HttpsServer(double keepAliveTimeout, bool allowMethodOverride,
std::vector<std::string> 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

View File

@ -24,7 +24,7 @@
#ifndef ARANGOD_REST_HANDLER_REST_BASE_HANDLER_H #ifndef ARANGOD_REST_HANDLER_REST_BASE_HANDLER_H
#define ARANGOD_REST_HANDLER_REST_BASE_HANDLER_H 1 #define ARANGOD_REST_HANDLER_REST_BASE_HANDLER_H 1
#include "HttpServer/RestHandler.h" #include "GeneralServer/RestHandler.h"
#include "Rest/GeneralResponse.h" #include "Rest/GeneralResponse.h"
@ -66,9 +66,8 @@ class RestBaseHandler : public rest::RestHandler {
protected: protected:
// write result back to client // write result back to client
void writeResult(arangodb::velocypack::Slice const& slice, void writeResult(arangodb::velocypack::Slice const& slice,
arangodb::velocypack::Options const& options); arangodb::velocypack::Options const& options);
}; };
} }

View File

@ -26,8 +26,8 @@
#include "Basics/StaticStrings.h" #include "Basics/StaticStrings.h"
#include "Basics/StringUtils.h" #include "Basics/StringUtils.h"
#include "Logger/Logger.h" #include "Logger/Logger.h"
#include "HttpServer/HttpServer.h" #include "GeneralServer/GeneralServer.h"
#include "HttpServer/RestHandlerFactory.h" #include "GeneralServer/RestHandlerFactory.h"
#include "Rest/HttpRequest.h" #include "Rest/HttpRequest.h"
#include "RestServer/RestServerFeature.h" #include "RestServer/RestServerFeature.h"

View File

@ -26,7 +26,7 @@
#include "Basics/StringUtils.h" #include "Basics/StringUtils.h"
#include "Dispatcher/Dispatcher.h" #include "Dispatcher/Dispatcher.h"
#include "Dispatcher/DispatcherFeature.h" #include "Dispatcher/DispatcherFeature.h"
#include "HttpServer/AsyncJobManager.h" #include "GeneralServer/AsyncJobManager.h"
#include "Rest/HttpRequest.h" #include "Rest/HttpRequest.h"
#include "Rest/HttpResponse.h" #include "Rest/HttpResponse.h"
@ -40,7 +40,7 @@ using namespace arangodb::rest;
RestJobHandler::RestJobHandler(GeneralRequest* request, RestJobHandler::RestJobHandler(GeneralRequest* request,
GeneralResponse* response, GeneralResponse* response,
AsyncJobManager* jobManager) AsyncJobManager* jobManager)
: RestBaseHandler(request, response), _jobManager(jobManager) { : RestBaseHandler(request, response), _jobManager(jobManager) {
TRI_ASSERT(jobManager != nullptr); TRI_ASSERT(jobManager != nullptr);
} }
@ -129,7 +129,7 @@ void RestJobHandler::putJobMethod() {
generateError(GeneralResponse::ResponseCode::SERVER_ERROR, generateError(GeneralResponse::ResponseCode::SERVER_ERROR,
TRI_ERROR_HTTP_NOT_FOUND); TRI_ERROR_HTTP_NOT_FOUND);
} }
bool status = DispatcherFeature::DISPATCHER->cancelJob(jobId); bool status = DispatcherFeature::DISPATCHER->cancelJob(jobId);
// unknown or already fetched job // unknown or already fetched job

View File

@ -25,7 +25,7 @@
#define ARANGOD_REST_HANDLER_REST_JOB_HANDLER_H 1 #define ARANGOD_REST_HANDLER_REST_JOB_HANDLER_H 1
#include "Basics/Common.h" #include "Basics/Common.h"
#include "HttpServer/AsyncJobManager.h" #include "GeneralServer/AsyncJobManager.h"
#include "RestHandler/RestBaseHandler.h" #include "RestHandler/RestBaseHandler.h"
namespace arangodb { namespace arangodb {

View File

@ -24,7 +24,7 @@
#ifndef ARANGOD_REST_HANDLER_REST_PLEASE_UPGRADE_HANDLER_H #ifndef ARANGOD_REST_HANDLER_REST_PLEASE_UPGRADE_HANDLER_H
#define ARANGOD_REST_HANDLER_REST_PLEASE_UPGRADE_HANDLER_H 1 #define ARANGOD_REST_HANDLER_REST_PLEASE_UPGRADE_HANDLER_H 1
#include "HttpServer/RestHandler.h" #include "GeneralServer/RestHandler.h"
namespace arangodb { namespace arangodb {
class RestPleaseUpgradeHandler : public rest::RestHandler { class RestPleaseUpgradeHandler : public rest::RestHandler {

View File

@ -29,7 +29,7 @@
#include "Basics/files.h" #include "Basics/files.h"
#include "Cluster/ClusterComm.h" #include "Cluster/ClusterComm.h"
#include "Cluster/ClusterMethods.h" #include "Cluster/ClusterMethods.h"
#include "HttpServer/HttpServer.h" #include "GeneralServer/GeneralServer.h"
#include "Indexes/EdgeIndex.h" #include "Indexes/EdgeIndex.h"
#include "Indexes/Index.h" #include "Indexes/Index.h"
#include "Indexes/PrimaryIndex.h" #include "Indexes/PrimaryIndex.h"
@ -566,7 +566,8 @@ void RestReplicationHandler::handleCommandBatch() {
} }
// extract ttl // extract ttl
double expires = VelocyPackHelper::getNumericValue<double>(input->slice(), "ttl", 0); double expires =
VelocyPackHelper::getNumericValue<double>(input->slice(), "ttl", 0);
TRI_voc_tick_t id; TRI_voc_tick_t id;
int res = TRI_InsertBlockerCompactorVocBase(_vocbase, expires, &id); int res = TRI_InsertBlockerCompactorVocBase(_vocbase, expires, &id);
@ -596,14 +597,15 @@ void RestReplicationHandler::handleCommandBatch() {
auto input = _request->toVelocyPackBuilderPtr(&VPackOptions::Defaults); auto input = _request->toVelocyPackBuilderPtr(&VPackOptions::Defaults);
if (input == nullptr || !input->slice().isObject()){ if (input == nullptr || !input->slice().isObject()) {
generateError(GeneralResponse::ResponseCode::BAD, generateError(GeneralResponse::ResponseCode::BAD,
TRI_ERROR_HTTP_BAD_PARAMETER, "invalid JSON"); TRI_ERROR_HTTP_BAD_PARAMETER, "invalid JSON");
return; return;
} }
// extract ttl // extract ttl
double expires = VelocyPackHelper::getNumericValue<double>(input->slice(), "ttl", 0); double expires =
VelocyPackHelper::getNumericValue<double>(input->slice(), "ttl", 0);
// now extend the blocker // now extend the blocker
int res = TRI_TouchBlockerCompactorVocBase(_vocbase, id, expires); int res = TRI_TouchBlockerCompactorVocBase(_vocbase, id, expires);
@ -775,7 +777,6 @@ void RestReplicationHandler::handleCommandBarrier() {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void RestReplicationHandler::handleTrampolineCoordinator() { void RestReplicationHandler::handleTrampolineCoordinator() {
if (_request == nullptr) { if (_request == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
} }
@ -812,7 +813,7 @@ void RestReplicationHandler::handleTrampolineCoordinator() {
ClusterComm* cc = ClusterComm::instance(); ClusterComm* cc = ClusterComm::instance();
HttpRequest* httpRequest = dynamic_cast<HttpRequest*>(_request); HttpRequest* httpRequest = dynamic_cast<HttpRequest*>(_request);
if(httpRequest == nullptr){ if (httpRequest == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
} }
@ -1216,7 +1217,7 @@ void RestReplicationHandler::handleCommandClusterInventory() {
TRI_ERROR_CLUSTER_READING_PLAN_AGENCY); TRI_ERROR_CLUSTER_READING_PLAN_AGENCY);
} else { } else {
VPackSlice colls = result.slice()[0].get(std::vector<std::string>( VPackSlice colls = result.slice()[0].get(std::vector<std::string>(
{_agency.prefix(), "Plan", "Collections", dbName})); {_agency.prefix(), "Plan", "Collections", dbName}));
if (!colls.isObject()) { if (!colls.isObject()) {
generateError(GeneralResponse::ResponseCode::SERVER_ERROR, generateError(GeneralResponse::ResponseCode::SERVER_ERROR,
TRI_ERROR_CLUSTER_READING_PLAN_AGENCY); TRI_ERROR_CLUSTER_READING_PLAN_AGENCY);
@ -1232,7 +1233,7 @@ void RestReplicationHandler::handleCommandClusterInventory() {
if (subResultSlice.isObject()) { if (subResultSlice.isObject()) {
if (includeSystem || if (includeSystem ||
!arangodb::basics::VelocyPackHelper::getBooleanValue( !arangodb::basics::VelocyPackHelper::getBooleanValue(
subResultSlice, "isSystem", true)) { subResultSlice, "isSystem", true)) {
VPackObjectBuilder b3(&resultBuilder); VPackObjectBuilder b3(&resultBuilder);
resultBuilder.add("indexes", subResultSlice.get("indexes")); resultBuilder.add("indexes", subResultSlice.get("indexes"));
resultBuilder.add("parameters", subResultSlice); resultBuilder.add("parameters", subResultSlice);
@ -1245,11 +1246,9 @@ void RestReplicationHandler::handleCommandClusterInventory() {
resultBuilder.add("tick", VPackValue(tickString)); resultBuilder.add("tick", VPackValue(tickString));
resultBuilder.add("state", VPackValue("unused")); resultBuilder.add("state", VPackValue("unused"));
} }
generateResult(GeneralResponse::ResponseCode::OK, generateResult(GeneralResponse::ResponseCode::OK, resultBuilder.slice());
resultBuilder.slice());
} }
} }
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -1626,7 +1625,8 @@ int RestReplicationHandler::processRestoreCollection(
int RestReplicationHandler::processRestoreCollectionCoordinator( int RestReplicationHandler::processRestoreCollectionCoordinator(
VPackSlice const& collection, bool dropExisting, bool reuseId, bool force, 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()) { if (!collection.isObject()) {
errorMsg = "collection declaration is invalid"; errorMsg = "collection declaration is invalid";
@ -1716,8 +1716,8 @@ int RestReplicationHandler::processRestoreCollectionCoordinator(
VPackSlice const replFactorSlice = parameters.get("replicationFactor"); VPackSlice const replFactorSlice = parameters.get("replicationFactor");
if (replFactorSlice.isInteger()) { if (replFactorSlice.isInteger()) {
replicationFactor = replFactorSlice.getNumericValue replicationFactor =
<decltype(replicationFactor)>(); replFactorSlice.getNumericValue<decltype(replicationFactor)>();
} }
if (replicationFactor == 0) { if (replicationFactor == 0) {
replicationFactor = 1; replicationFactor = 1;
@ -1741,9 +1741,9 @@ int RestReplicationHandler::processRestoreCollectionCoordinator(
// shards // shards
std::vector<std::string> dbServers; // will be filled std::vector<std::string> dbServers; // will be filled
std::map<std::string, std::vector<std::string>> shardDistribution std::map<std::string, std::vector<std::string>> shardDistribution =
= arangodb::distributeShards(numberOfShards, replicationFactor, arangodb::distributeShards(numberOfShards, replicationFactor,
dbServers); dbServers);
if (shardDistribution.empty()) { if (shardDistribution.empty()) {
errorMsg = "no database servers found in cluster"; errorMsg = "no database servers found in cluster";
return TRI_ERROR_INTERNAL; return TRI_ERROR_INTERNAL;
@ -1991,7 +1991,8 @@ int RestReplicationHandler::processRestoreIndexesCoordinator(
int res = TRI_ERROR_NO_ERROR; int res = TRI_ERROR_NO_ERROR;
for (VPackSlice const& idxDef : VPackArrayIterator(indexes)) { for (VPackSlice const& idxDef : VPackArrayIterator(indexes)) {
VPackSlice type = idxDef.get("type"); 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 // must ignore these types of indexes during restore
continue; continue;
} }
@ -2271,8 +2272,8 @@ int RestReplicationHandler::processRestoreDataBatch(
options.ignoreRevs = true; options.ignoreRevs = true;
options.isRestore = true; options.isRestore = true;
options.waitForSync = false; options.waitForSync = false;
OperationResult opRes = trx.remove(collectionName, oldBuilder.slice(), OperationResult opRes =
options); trx.remove(collectionName, oldBuilder.slice(), options);
if (!opRes.successful()) { if (!opRes.successful()) {
return opRes.code; return opRes.code;
} }
@ -3943,9 +3944,10 @@ void RestReplicationHandler::handleCommandHoldReadLockCollection() {
} }
VPackSlice const body = parsedBody->slice(); VPackSlice const body = parsedBody->slice();
if (!body.isObject()) { if (!body.isObject()) {
generateError( generateError(GeneralResponse::ResponseCode::BAD,
GeneralResponse::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER, TRI_ERROR_HTTP_BAD_PARAMETER,
"body needs to be an object with attributes 'collection', 'ttl' and 'id'"); "body needs to be an object with attributes 'collection', "
"'ttl' and 'id'");
return; return;
} }
VPackSlice const collection = body.get("collection"); VPackSlice const collection = body.get("collection");
@ -3960,7 +3962,8 @@ void RestReplicationHandler::handleCommandHoldReadLockCollection() {
} }
std::string id = idSlice.copyString(); std::string id = idSlice.copyString();
auto col = TRI_LookupCollectionByNameVocBase(_vocbase, collection.copyString()); auto col =
TRI_LookupCollectionByNameVocBase(_vocbase, collection.copyString());
if (col == nullptr) { if (col == nullptr) {
generateError(GeneralResponse::ResponseCode::SERVER_ERROR, generateError(GeneralResponse::ResponseCode::SERVER_ERROR,
TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND, TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND,
@ -4048,16 +4051,15 @@ void RestReplicationHandler::handleCommandCheckHoldReadLockCollection() {
} }
VPackSlice const body = parsedBody->slice(); VPackSlice const body = parsedBody->slice();
if (!body.isObject()) { if (!body.isObject()) {
generateError( generateError(GeneralResponse::ResponseCode::BAD,
GeneralResponse::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER, TRI_ERROR_HTTP_BAD_PARAMETER,
"body needs to be an object with attribute 'id'"); "body needs to be an object with attribute 'id'");
return; return;
} }
VPackSlice const idSlice = body.get("id"); VPackSlice const idSlice = body.get("id");
if (!idSlice.isString()) { if (!idSlice.isString()) {
generateError(GeneralResponse::ResponseCode::BAD, generateError(GeneralResponse::ResponseCode::BAD,
TRI_ERROR_HTTP_BAD_PARAMETER, TRI_ERROR_HTTP_BAD_PARAMETER, "'id' needs to be a string");
"'id' needs to be a string");
return; return;
} }
std::string id = idSlice.copyString(); std::string id = idSlice.copyString();
@ -4096,16 +4098,15 @@ void RestReplicationHandler::handleCommandCancelHoldReadLockCollection() {
} }
VPackSlice const body = parsedBody->slice(); VPackSlice const body = parsedBody->slice();
if (!body.isObject()) { if (!body.isObject()) {
generateError( generateError(GeneralResponse::ResponseCode::BAD,
GeneralResponse::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER, TRI_ERROR_HTTP_BAD_PARAMETER,
"body needs to be an object with attribute 'id'"); "body needs to be an object with attribute 'id'");
return; return;
} }
VPackSlice const idSlice = body.get("id"); VPackSlice const idSlice = body.get("id");
if (!idSlice.isString()) { if (!idSlice.isString()) {
generateError(GeneralResponse::ResponseCode::BAD, generateError(GeneralResponse::ResponseCode::BAD,
TRI_ERROR_HTTP_BAD_PARAMETER, TRI_ERROR_HTTP_BAD_PARAMETER, "'id' needs to be a string");
"'id' needs to be a string");
return; return;
} }
std::string id = idSlice.copyString(); std::string id = idSlice.copyString();

View File

@ -27,7 +27,7 @@
#include "Basics/StaticStrings.h" #include "Basics/StaticStrings.h"
#include "Basics/StringUtils.h" #include "Basics/StringUtils.h"
#include "Basics/tri-strings.h" #include "Basics/tri-strings.h"
#include "HttpServer/HttpServer.h" #include "GeneralServer/GeneralServer.h"
#include "Logger/Logger.h" #include "Logger/Logger.h"
#include "Rest/HttpRequest.h" #include "Rest/HttpRequest.h"

View File

@ -25,7 +25,7 @@
#define ARANGOD_REST_HANDLER_REST_UPLOAD_HANDLER_H 1 #define ARANGOD_REST_HANDLER_REST_UPLOAD_HANDLER_H 1
#include "Basics/Common.h" #include "Basics/Common.h"
#include "HttpServer/HttpServer.h" #include "GeneralServer/GeneralServer.h"
#include "RestHandler/RestVocbaseBaseHandler.h" #include "RestHandler/RestVocbaseBaseHandler.h"
namespace arangodb { namespace arangodb {

View File

@ -23,7 +23,7 @@
#include "WorkMonitorHandler.h" #include "WorkMonitorHandler.h"
#include "Basics/StringUtils.h" #include "Basics/StringUtils.h"
#include "HttpServer/RestHandler.h" #include "GeneralServer/RestHandler.h"
#include "Rest/HttpRequest.h" #include "Rest/HttpRequest.h"
#include "velocypack/Builder.h" #include "velocypack/Builder.h"
#include "velocypack/velocypack-aliases.h" #include "velocypack/velocypack-aliases.h"

View File

@ -26,7 +26,7 @@
#include "Cluster/AgencyComm.h" #include "Cluster/AgencyComm.h"
#include "Cluster/ClusterInfo.h" #include "Cluster/ClusterInfo.h"
#include "Cluster/ServerState.h" #include "Cluster/ServerState.h"
#include "HttpServer/RestHandlerFactory.h" #include "GeneralServer/RestHandlerFactory.h"
#include "Logger/Logger.h" #include "Logger/Logger.h"
#include "ProgramOptions/Parameters.h" #include "ProgramOptions/Parameters.h"
#include "ProgramOptions/ProgramOptions.h" #include "ProgramOptions/ProgramOptions.h"
@ -41,7 +41,8 @@ using namespace arangodb;
using namespace arangodb::application_features; using namespace arangodb::application_features;
using namespace arangodb::options; using namespace arangodb::options;
BootstrapFeature::BootstrapFeature(application_features::ApplicationServer* server) BootstrapFeature::BootstrapFeature(
application_features::ApplicationServer* server)
: ApplicationFeature(server, "Bootstrap"), _isReady(false), _bark(false) { : ApplicationFeature(server, "Bootstrap"), _isReady(false), _bark(false) {
startsAfter("Dispatcher"); startsAfter("Dispatcher");
startsAfter("Endpoint"); startsAfter("Endpoint");
@ -55,9 +56,9 @@ BootstrapFeature::BootstrapFeature(application_features::ApplicationServer* serv
startsAfter("RestServer"); startsAfter("RestServer");
} }
void BootstrapFeature::collectOptions( void BootstrapFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
std::shared_ptr<ProgramOptions> options) { options->addHiddenOption("hund", "make ArangoDB bark on startup",
options->addHiddenOption("hund", "make ArangoDB bark on startup", new BooleanParameter(&_bark)); new BooleanParameter(&_bark));
} }
static void raceForClusterBootstrap() { static void raceForClusterBootstrap() {
@ -68,22 +69,22 @@ static void raceForClusterBootstrap() {
AgencyCommResult result = agency.getValues("Bootstrap"); AgencyCommResult result = agency.getValues("Bootstrap");
if (!result.successful()) { if (!result.successful()) {
// Error in communication, note that value not found is not an error // 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"; << "raceForClusterBootstrap: no agency communication";
sleep(1); sleep(1);
continue; continue;
} }
VPackSlice value = result.slice()[0].get(std::vector<std::string>( VPackSlice value = result.slice()[0].get(
{agency.prefix(), "Bootstrap"})); std::vector<std::string>({agency.prefix(), "Bootstrap"}));
if (value.isString()) { if (value.isString()) {
// key was found and is a string // key was found and is a string
if (value.isEqualString("done")) { if (value.isEqualString("done")) {
// all done, let's get out of here: // all done, let's get out of here:
LOG_TOPIC(TRACE, Logger::STARTUP) LOG_TOPIC(TRACE, Logger::STARTUP)
<< "raceForClusterBootstrap: bootstrap already done"; << "raceForClusterBootstrap: bootstrap already done";
return; return;
} }
LOG_TOPIC(DEBUG, Logger::STARTUP) LOG_TOPIC(DEBUG, Logger::STARTUP)
<< "raceForClusterBootstrap: somebody else does the bootstrap"; << "raceForClusterBootstrap: somebody else does the bootstrap";
sleep(1); sleep(1);
continue; continue;
@ -94,7 +95,7 @@ static void raceForClusterBootstrap() {
b.add(VPackValue(arangodb::ServerState::instance()->getId())); b.add(VPackValue(arangodb::ServerState::instance()->getId()));
result = agency.casValue("Bootstrap", b.slice(), false, 300, 15); result = agency.casValue("Bootstrap", b.slice(), false, 300, 15);
if (!result.successful()) { if (!result.successful()) {
LOG_TOPIC(DEBUG, Logger::STARTUP) LOG_TOPIC(DEBUG, Logger::STARTUP)
<< "raceForClusterBootstrap: lost race, somebody else will bootstrap"; << "raceForClusterBootstrap: lost race, somebody else will bootstrap";
// Cannot get foot into the door, try again later: // Cannot get foot into the door, try again later:
sleep(1); sleep(1);
@ -104,19 +105,20 @@ static void raceForClusterBootstrap() {
// OK, we handle things now, let's see whether a DBserver is there: // OK, we handle things now, let's see whether a DBserver is there:
auto dbservers = ci->getCurrentDBServers(); auto dbservers = ci->getCurrentDBServers();
if (dbservers.size() == 0) { if (dbservers.size() == 0) {
LOG_TOPIC(TRACE, Logger::STARTUP) LOG_TOPIC(TRACE, Logger::STARTUP)
<< "raceForClusterBootstrap: no DBservers, waiting"; << "raceForClusterBootstrap: no DBservers, waiting";
agency.removeValues("Bootstrap", false); agency.removeValues("Bootstrap", false);
sleep(1); sleep(1);
continue; continue;
} }
LOG_TOPIC(DEBUG, Logger::STARTUP) LOG_TOPIC(DEBUG, Logger::STARTUP)
<< "raceForClusterBootstrap: race won, we do the bootstrap"; << "raceForClusterBootstrap: race won, we do the bootstrap";
auto vocbase = DatabaseFeature::DATABASE->vocbase(); 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"; << "raceForClusterBootstrap: bootstrap done";
b.clear(); b.clear();
@ -126,7 +128,7 @@ static void raceForClusterBootstrap() {
return; return;
} }
LOG_TOPIC(TRACE, Logger::STARTUP) LOG_TOPIC(TRACE, Logger::STARTUP)
<< "raceForClusterBootstrap: could not indicate success"; << "raceForClusterBootstrap: could not indicate success";
sleep(1); sleep(1);
@ -140,11 +142,15 @@ void BootstrapFeature::start() {
if (ss->isCoordinator()) { if (ss->isCoordinator()) {
LOG_TOPIC(DEBUG, Logger::STARTUP) << "Racing for cluster bootstrap..."; LOG_TOPIC(DEBUG, Logger::STARTUP) << "Racing for cluster bootstrap...";
raceForClusterBootstrap(); raceForClusterBootstrap();
LOG_TOPIC(DEBUG, Logger::STARTUP) << "Running server/bootstrap/coordinator.js"; LOG_TOPIC(DEBUG, Logger::STARTUP)
V8DealerFeature::DEALER->loadJavascript(vocbase, "server/bootstrap/coordinator.js"); << "Running server/bootstrap/coordinator.js";
V8DealerFeature::DEALER->loadJavascript(vocbase,
"server/bootstrap/coordinator.js");
} else if (ss->isDBServer()) { } else if (ss->isDBServer()) {
LOG_TOPIC(DEBUG, Logger::STARTUP) << "Running server/bootstrap/db-server.js"; LOG_TOPIC(DEBUG, Logger::STARTUP)
V8DealerFeature::DEALER->loadJavascript(vocbase, "server/bootstrap/db-server.js"); << "Running server/bootstrap/db-server.js";
V8DealerFeature::DEALER->loadJavascript(vocbase,
"server/bootstrap/db-server.js");
} else { } else {
LOG_TOPIC(DEBUG, Logger::STARTUP) << "Running server/server.js"; LOG_TOPIC(DEBUG, Logger::STARTUP) << "Running server/server.js";
V8DealerFeature::DEALER->loadJavascript(vocbase, "server/server.js"); V8DealerFeature::DEALER->loadJavascript(vocbase, "server/server.js");
@ -163,13 +169,15 @@ void BootstrapFeature::start() {
} }
void BootstrapFeature::unprepare() { void BootstrapFeature::unprepare() {
auto server = ApplicationServer::getFeature<DatabaseServerFeature>("DatabaseServer"); auto server =
ApplicationServer::getFeature<DatabaseServerFeature>("DatabaseServer");
TRI_server_t* s = server->SERVER; TRI_server_t* s = server->SERVER;
// notify all currently running queries about the shutdown // notify all currently running queries about the shutdown
if (ServerState::instance()->isCoordinator()) { if (ServerState::instance()->isCoordinator()) {
std::vector<TRI_voc_tick_t> ids = TRI_GetIdsCoordinatorDatabaseServer(s, true); std::vector<TRI_voc_tick_t> ids =
TRI_GetIdsCoordinatorDatabaseServer(s, true);
for (auto& id : ids) { for (auto& id : ids) {
TRI_vocbase_t* vocbase = TRI_UseByIdCoordinatorDatabaseServer(s, id); TRI_vocbase_t* vocbase = TRI_UseByIdCoordinatorDatabaseServer(s, id);
@ -177,7 +185,7 @@ void BootstrapFeature::unprepare() {
vocbase->_queries->killAll(true); vocbase->_queries->killAll(true);
TRI_ReleaseVocBase(vocbase); TRI_ReleaseVocBase(vocbase);
} }
} }
} else { } else {
std::vector<std::string> names; std::vector<std::string> names;
int res = TRI_GetDatabaseNamesServer(s, names); int res = TRI_GetDatabaseNamesServer(s, names);
@ -193,4 +201,3 @@ void BootstrapFeature::unprepare() {
} }
} }
} }

View File

@ -30,13 +30,9 @@
#include "Endpoint/EndpointList.h" #include "Endpoint/EndpointList.h"
namespace arangodb { namespace arangodb {
namespace rest {
class HttpServer;
class HttpsServer;
}
class EndpointFeature final : public application_features::ApplicationFeature, class EndpointFeature final : public application_features::ApplicationFeature,
public HttpEndpointProvider { public HttpEndpointProvider {
public: public:
explicit EndpointFeature(application_features::ApplicationServer* server); explicit EndpointFeature(application_features::ApplicationServer* server);

View File

@ -33,9 +33,8 @@
#include "Cluster/RestAgencyCallbacksHandler.h" #include "Cluster/RestAgencyCallbacksHandler.h"
#include "Cluster/RestShardHandler.h" #include "Cluster/RestShardHandler.h"
#include "Dispatcher/DispatcherFeature.h" #include "Dispatcher/DispatcherFeature.h"
#include "HttpServer/HttpServer.h" #include "GeneralServer/GeneralServer.h"
#include "HttpServer/HttpsServer.h" #include "GeneralServer/RestHandlerFactory.h"
#include "HttpServer/RestHandlerFactory.h"
#include "ProgramOptions/Parameters.h" #include "ProgramOptions/Parameters.h"
#include "ProgramOptions/ProgramOptions.h" #include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h" #include "ProgramOptions/Section.h"
@ -74,6 +73,8 @@
#include "V8Server/V8DealerFeature.h" #include "V8Server/V8DealerFeature.h"
#include "VocBase/server.h" #include "VocBase/server.h"
#include <stdexcept>
using namespace arangodb; using namespace arangodb;
using namespace arangodb::rest; using namespace arangodb::rest;
using namespace arangodb::options; using namespace arangodb::options;
@ -203,8 +204,8 @@ void RestServerFeature::validateOptions(std::shared_ptr<ProgramOptions>) {
std::remove_if(_accessControlAllowOrigins.begin(), std::remove_if(_accessControlAllowOrigins.begin(),
_accessControlAllowOrigins.end(), _accessControlAllowOrigins.end(),
[](std::string const& value) { [](std::string const& value) {
return basics::StringUtils::trim(value).empty(); return basics::StringUtils::trim(value).empty();
}), }),
_accessControlAllowOrigins.end()); _accessControlAllowOrigins.end());
} }
@ -341,40 +342,29 @@ void RestServerFeature::buildServers() {
EndpointFeature* endpoint = EndpointFeature* endpoint =
application_features::ApplicationServer::getFeature<EndpointFeature>( application_features::ApplicationServer::getFeature<EndpointFeature>(
"Endpoint"); "Endpoint");
// unencrypted HTTP endpoints
HttpServer* httpServer =
new HttpServer(_keepAliveTimeout,
_allowMethodOverride, _accessControlAllowOrigins);
// YYY #warning FRANK filter list
auto const& endpointList = endpoint->endpointList(); 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()) { if (endpointList.hasSsl()) {
SslServerFeature* ssl = SslServerFeature* ssl =
application_features::ApplicationServer::getFeature<SslServerFeature>( application_features::ApplicationServer::getFeature<SslServerFeature>(
"SslServer"); "SslServer");
// check the ssl context
if (ssl->sslContext() == nullptr) { if (ssl->sslContext() == nullptr) {
LOG(FATAL) << "no ssl context is known, cannot create https server, " LOG(FATAL) << "no ssl context is known, cannot create https server, "
"please use the '--ssl.keyfile' option"; "please use the '--ssl.keyfile' option";
FATAL_ERROR_EXIT(); FATAL_ERROR_EXIT();
} }
sslContext = ssl->sslContext();
SSL_CTX* sslContext = ssl->sslContext();
// https
httpServer = new HttpsServer(_keepAliveTimeout,
_allowMethodOverride,
_accessControlAllowOrigins, sslContext);
httpServer->setEndpointList(&endpointList);
_servers.push_back(httpServer);
} }
GeneralServer* server =
new GeneralServer(_keepAliveTimeout, _allowMethodOverride,
_accessControlAllowOrigins, sslContext);
server->setEndpointList(&endpointList);
_servers.push_back(server);
} }
void RestServerFeature::defineHandlers() { void RestServerFeature::defineHandlers() {

View File

@ -32,7 +32,7 @@ namespace arangodb {
namespace rest { namespace rest {
class AsyncJobManager; class AsyncJobManager;
class RestHandlerFactory; class RestHandlerFactory;
class HttpServer; class GeneralServer;
} }
class RestServerThread; class RestServerThread;
@ -48,11 +48,11 @@ class RestServerFeature final
static bool authenticationEnabled() { static bool authenticationEnabled() {
return REST_SERVER != nullptr && REST_SERVER->authentication(); return REST_SERVER != nullptr && REST_SERVER->authentication();
} }
static bool hasProxyCheck() { static bool hasProxyCheck() {
return REST_SERVER != nullptr && REST_SERVER->proxyCheck(); return REST_SERVER != nullptr && REST_SERVER->proxyCheck();
} }
static std::vector<std::string> getTrustedProxies() { static std::vector<std::string> getTrustedProxies() {
if (REST_SERVER == nullptr) { if (REST_SERVER == nullptr) {
return std::vector<std::string>(); return std::vector<std::string>();
@ -92,7 +92,7 @@ class RestServerFeature final
bool _proxyCheck; bool _proxyCheck;
std::vector<std::string> _trustedProxies; std::vector<std::string> _trustedProxies;
std::vector<std::string> _accessControlAllowOrigins; std::vector<std::string> _accessControlAllowOrigins;
std::string _jwtSecret; std::string _jwtSecret;
public: public:
@ -112,7 +112,7 @@ class RestServerFeature final
private: private:
std::unique_ptr<rest::RestHandlerFactory> _handlerFactory; std::unique_ptr<rest::RestHandlerFactory> _handlerFactory;
std::unique_ptr<rest::AsyncJobManager> _jobManager; std::unique_ptr<rest::AsyncJobManager> _jobManager;
std::vector<rest::HttpServer*> _servers; std::vector<rest::GeneralServer*> _servers;
}; };
} }

View File

@ -30,7 +30,7 @@
#include "Aql/QueryList.h" #include "Aql/QueryList.h"
#include "Basics/StaticStrings.h" #include "Basics/StaticStrings.h"
#include "Basics/StringBuffer.h" #include "Basics/StringBuffer.h"
#include "HttpServer/RestHandler.h" #include "GeneralServer/RestHandler.h"
#include "Logger/Logger.h" #include "Logger/Logger.h"
#include "Scheduler/Scheduler.h" #include "Scheduler/Scheduler.h"
#include "Scheduler/SchedulerFeature.h" #include "Scheduler/SchedulerFeature.h"

View File

@ -35,7 +35,7 @@
#include "Basics/tri-strings.h" #include "Basics/tri-strings.h"
#include "Cluster/ClusterComm.h" #include "Cluster/ClusterComm.h"
#include "Cluster/ServerState.h" #include "Cluster/ServerState.h"
#include "HttpServer/HttpServer.h" #include "GeneralServer/GeneralServer.h"
#include "Logger/Logger.h" #include "Logger/Logger.h"
#include "Rest/GeneralRequest.h" #include "Rest/GeneralRequest.h"
#include "Rest/HttpRequest.h" #include "Rest/HttpRequest.h"
@ -403,22 +403,23 @@ static v8::Handle<v8::Object> RequestCppToV8(v8::Isolate* isolate,
TRI_GET_GLOBAL_STRING(RequestTypeKey); TRI_GET_GLOBAL_STRING(RequestTypeKey);
TRI_GET_GLOBAL_STRING(RequestBodyKey); TRI_GET_GLOBAL_STRING(RequestBodyKey);
auto set_request_body_json_or_vpack = [&](){ auto set_request_body_json_or_vpack = [&]() {
if (GeneralRequest::ContentType::JSON == request->contentType()) { if (GeneralRequest::ContentType::JSON == request->contentType()) {
auto httpreq = dynamic_cast<HttpRequest*>(request); auto httpreq = dynamic_cast<HttpRequest*>(request);
if (httpreq == nullptr) { if (httpreq == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); 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<char>(), std::distance(slice.begin(), slice.end()));
v8::Local<v8::Object> bufferObject =
v8::Local<v8::Object>::New(isolate, buffer->_handle);
req->ForceSet(RequestBodyKey, bufferObject);
} }
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<char>(),
std::distance(slice.begin(), slice.end()));
v8::Local<v8::Object> bufferObject =
v8::Local<v8::Object>::New(isolate, buffer->_handle);
req->ForceSet(RequestBodyKey, bufferObject);
}
}; };
// copy request type // copy request type
@ -426,7 +427,7 @@ static v8::Handle<v8::Object> RequestCppToV8(v8::Isolate* isolate,
case GeneralRequest::RequestType::POST: { case GeneralRequest::RequestType::POST: {
TRI_GET_GLOBAL_STRING(PostConstant); TRI_GET_GLOBAL_STRING(PostConstant);
req->ForceSet(RequestTypeKey, 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(); set_request_body_json_or_vpack();
break; break;
} }
@ -434,7 +435,7 @@ static v8::Handle<v8::Object> RequestCppToV8(v8::Isolate* isolate,
case GeneralRequest::RequestType::PUT: { case GeneralRequest::RequestType::PUT: {
TRI_GET_GLOBAL_STRING(PutConstant); TRI_GET_GLOBAL_STRING(PutConstant);
req->ForceSet(RequestTypeKey, 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(); set_request_body_json_or_vpack();
break; break;
} }
@ -442,7 +443,7 @@ static v8::Handle<v8::Object> RequestCppToV8(v8::Isolate* isolate,
case GeneralRequest::RequestType::PATCH: { case GeneralRequest::RequestType::PATCH: {
TRI_GET_GLOBAL_STRING(PatchConstant); TRI_GET_GLOBAL_STRING(PatchConstant);
req->ForceSet(RequestTypeKey, 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(); set_request_body_json_or_vpack();
break; break;
} }
@ -1135,7 +1136,7 @@ static void JS_SendChunk(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_Utf8ValueNFC data(TRI_UNKNOWN_MEM_ZONE, args[1]); 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) { if (res != TRI_ERROR_NO_ERROR && res != TRI_ERROR_TASK_NOT_FOUND) {
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "cannot send chunk"); TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "cannot send chunk");

View File

@ -154,40 +154,40 @@ std::vector<std::string> EndpointList::all(
/// @brief return all endpoints with a certain encryption type /// @brief return all endpoints with a certain encryption type
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::map<std::string, Endpoint*> EndpointList::matching( // std::map<std::string, Endpoint*> EndpointList::matching(
Endpoint::TransportType transport, // Endpoint::TransportType transport,
Endpoint::EncryptionType encryption) const { // Endpoint::EncryptionType encryption) const {
std::string prefix; // std::string prefix;
//
switch (transport) { // switch (transport) {
case Endpoint::TransportType::HTTP: // case Endpoint::TransportType::HTTP:
prefix = "http+"; // prefix = "http+";
break; // break;
//
case Endpoint::TransportType::VPP: // case Endpoint::TransportType::VPP:
prefix = "vpp+"; // prefix = "vpp+";
break; // break;
} // }
//
std::map<std::string, Endpoint*> result; // std::map<std::string, Endpoint*> result;
//
for (auto& it : _endpoints) { // for (auto& it : _endpoints) {
std::string const& key = it.first; // std::string const& key = it.first;
//
if (encryption == Endpoint::EncryptionType::SSL) { // if (encryption == Endpoint::EncryptionType::SSL) {
if (StringUtils::isPrefix(key, prefix + "ssl://")) { // if (StringUtils::isPrefix(key, prefix + "ssl://")) {
result[key] = it.second; // result[key] = it.second;
} // }
} else { // } else {
if (StringUtils::isPrefix(key, prefix + "tcp://") || // if (StringUtils::isPrefix(key, prefix + "tcp://") ||
StringUtils::isPrefix(key, prefix + "unix://")) { // StringUtils::isPrefix(key, prefix + "unix://")) {
result[key] = it.second; // result[key] = it.second;
} // }
} // }
} // }
//
return result; // return result;
} //}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief return if there is an endpoint with SSL /// @brief return if there is an endpoint with SSL

View File

@ -43,8 +43,9 @@ class EndpointList {
bool remove(std::string const&, Endpoint**); bool remove(std::string const&, Endpoint**);
std::vector<std::string> all() const; std::vector<std::string> all() const;
std::vector<std::string> all(Endpoint::TransportType transport) const; std::vector<std::string> all(Endpoint::TransportType transport) const;
std::map<std::string, Endpoint*> matching(Endpoint::TransportType, // std::map<std::string, Endpoint*> matching(Endpoint::TransportType,
Endpoint::EncryptionType) const; // Endpoint::EncryptionType) const;
std::map<std::string, Endpoint*> allEndpoints() const { return _endpoints; }
bool hasSsl() const; bool hasSsl() const;
void dump() const; void dump() const;

View File

@ -26,14 +26,15 @@
#define ARANGODB_REST_HTTP_REQUEST_H 1 #define ARANGODB_REST_HTTP_REQUEST_H 1
#include "Rest/GeneralRequest.h" #include "Rest/GeneralRequest.h"
#include "Endpoint/ConnectionInfo.h" #include "Endpoint/ConnectionInfo.h"
namespace arangodb { namespace arangodb {
class RestBatchHandler; class RestBatchHandler;
namespace rest { namespace rest {
class GeneralCommTask;
class HttpCommTask; class HttpCommTask;
class HttpsCommTask;
} }
namespace velocypack { namespace velocypack {
@ -43,6 +44,8 @@ struct Options;
class HttpRequest : public GeneralRequest { class HttpRequest : public GeneralRequest {
friend class rest::HttpCommTask; friend class rest::HttpCommTask;
friend class rest::HttpsCommTask;
friend class rest::GeneralCommTask;
friend class RestBatchHandler; // TODO must be removed friend class RestBatchHandler; // TODO must be removed
private: private:
@ -74,7 +77,6 @@ class HttpRequest : public GeneralRequest {
// Payload // Payload
VPackSlice payload(arangodb::velocypack::Options const*) override final; VPackSlice payload(arangodb::velocypack::Options const*) override final;
/// @brief sets a key/value header /// @brief sets a key/value header
// this function is called by setHeaders and get offsets to // this function is called by setHeaders and get offsets to
// the found key / value with respective lengths. // the found key / value with respective lengths.

View File

@ -34,11 +34,13 @@ class RestBatchHandler;
namespace rest { namespace rest {
class HttpCommTask; class HttpCommTask;
class GeneralCommTask;
} }
class HttpResponse : public GeneralResponse { class HttpResponse : public GeneralResponse {
friend class rest::GeneralCommTask;
friend class rest::HttpCommTask; friend class rest::HttpCommTask;
friend class RestBatchHandler; // TODO must be removed friend class RestBatchHandler; // TODO must be removed
public: public:
static bool HIDE_PRODUCT_HEADER; static bool HIDE_PRODUCT_HEADER;
@ -67,7 +69,9 @@ class HttpResponse : public GeneralResponse {
size_t bodySize() const; size_t bodySize() const;
/// @brief set type of connection /// @brief set type of connection
void setConnectionType(ConnectionType type) override { _connectionType = type; } void setConnectionType(ConnectionType type) override {
_connectionType = type;
}
/// @brief set content-type /// @brief set content-type
void setContentType(ContentType type) override { _contentType = type; } void setContentType(ContentType type) override { _contentType = type; }
@ -95,7 +99,6 @@ class HttpResponse : public GeneralResponse {
bool generateBody, bool generateBody,
arangodb::velocypack::Options const&) override final; arangodb::velocypack::Options const&) override final;
private: private:
// the body must already be set. deflate is then run on the existing body // the body must already be set. deflate is then run on the existing body
int deflate(size_t = 16384); int deflate(size_t = 16384);