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-result.cpp
GeoIndex/GeoIndex.cpp
HttpServer/AsyncJobManager.cpp
HttpServer/HttpCommTask.cpp
HttpServer/HttpListenTask.cpp
HttpServer/HttpServer.cpp
HttpServer/HttpServerJob.cpp
HttpServer/HttpsCommTask.cpp
HttpServer/HttpsServer.cpp
HttpServer/RestHandler.cpp
HttpServer/RestHandlerFactory.cpp
HttpServer/PathHandler.cpp
GeneralServer/AsyncJobManager.cpp
GeneralServer/HttpCommTask.cpp
GeneralServer/HttpServerJob.cpp
GeneralServer/GeneralCommTask.cpp
GeneralServer/HttpCommTask.cpp
GeneralServer/HttpsCommTask.cpp
GeneralServer/GeneralListenTask.cpp
GeneralServer/GeneralServer.cpp
GeneralServer/RestHandler.cpp
GeneralServer/RestHandlerFactory.cpp
GeneralServer/PathHandler.cpp
Indexes/EdgeIndex.cpp
Indexes/FulltextIndex.cpp
Indexes/GeoIndex2.cpp

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -32,7 +32,7 @@ namespace arangodb {
namespace rest {
class AsyncJobManager;
class RestHandlerFactory;
class HttpServer;
class GeneralServer;
}
class RestServerThread;
@ -48,11 +48,11 @@ class RestServerFeature final
static bool authenticationEnabled() {
return REST_SERVER != nullptr && REST_SERVER->authentication();
}
static bool hasProxyCheck() {
return REST_SERVER != nullptr && REST_SERVER->proxyCheck();
}
static std::vector<std::string> getTrustedProxies() {
if (REST_SERVER == nullptr) {
return std::vector<std::string>();
@ -92,7 +92,7 @@ class RestServerFeature final
bool _proxyCheck;
std::vector<std::string> _trustedProxies;
std::vector<std::string> _accessControlAllowOrigins;
std::string _jwtSecret;
public:
@ -112,7 +112,7 @@ class RestServerFeature final
private:
std::unique_ptr<rest::RestHandlerFactory> _handlerFactory;
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 "Basics/StaticStrings.h"
#include "Basics/StringBuffer.h"
#include "HttpServer/RestHandler.h"
#include "GeneralServer/RestHandler.h"
#include "Logger/Logger.h"
#include "Scheduler/Scheduler.h"
#include "Scheduler/SchedulerFeature.h"

View File

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

View File

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

View File

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

View File

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

View File

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