1
0
Fork 0

added https@ and http@ endpoints, https still unfinished

This commit is contained in:
Jan Steemann 2012-07-23 17:32:59 +02:00
parent abc516f429
commit 9a72ea4496
6 changed files with 212 additions and 142 deletions

View File

@ -54,6 +54,11 @@
#include "HttpServer/ApplicationHttpServer.h"
#include "HttpServer/HttpHandlerFactory.h"
#include "HttpServer/RedirectHandler.h"
#ifdef TRI_OPENSSL_VERSION
#include "HttpsServer/ApplicationHttpsServer.h"
#endif
#include "Logger/Logger.h"
#include "Rest/Initialise.h"
#include "RestHandler/ConnectionStatisticsHandler.h"
@ -372,6 +377,17 @@ void ArangoServer::buildApplicationServer () {
_applicationHttpServer = new ApplicationHttpServer(_applicationScheduler, _applicationDispatcher);
_applicationServer->addFeature(_applicationHttpServer);
#ifdef TRI_OPENSSL_VERSION
// .............................................................................
// an https server
// .............................................................................
_applicationHttpsServer = new ApplicationHttpsServer(_applicationScheduler, _applicationDispatcher);
_applicationServer->addFeature(_applicationHttpsServer);
#endif
// .............................................................................
// daemon and supervisor mode
// .............................................................................
@ -566,14 +582,24 @@ int ArangoServer::startupServer () {
Scheduler* scheduler = _applicationScheduler->scheduler();
// we pass the options be reference, so keep them until shutdown
// we pass the options by reference, so keep them until shutdown
RestActionHandler::action_options_t httpOptions;
httpOptions._vocbase = _vocbase;
httpOptions._queue = "STANDARD";
// add & validate endpoints
for (vector<string>::const_iterator i = _endpoints.begin(); i != _endpoints.end(); ++i) {
bool ok = _endpointList.addHttpEndpoint(*i);
Endpoint* endpoint = Endpoint::serverFactory(*i);
if (endpoint == 0) {
LOGGER_FATAL << "invalid endpoint '" << *i << "'";
cerr << "invalid endpoint '" << *i << "'\n";
exit(EXIT_FAILURE);
}
assert(endpoint);
bool ok = _endpointList.addEndpoint(endpoint->getProtocol(), endpoint);
if (! ok) {
LOGGER_FATAL << "invalid endpoint '" << *i << "'";
cerr << "invalid endpoint '" << *i << "'\n";

View File

@ -175,7 +175,7 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
void startListening () {
EndpointList::ListType endpoints = _endpointList->getHttpEndpoints();
EndpointList::ListType endpoints = _endpointList->getEndpoints(Endpoint::PROTOCOL_HTTP);
for (EndpointList::ListType::const_iterator i = endpoints.begin(); i != endpoints.end(); ++i) {
LOGGER_TRACE << "trying to bind to endpoint '" << (*i)->getSpecification() << "' for requests";

View File

@ -77,13 +77,15 @@ const std::string EndpointIp::_defaultHost = "127.0.0.1";
/// @brief create an endpoint
////////////////////////////////////////////////////////////////////////////////
Endpoint::Endpoint (const EndpointType type,
const EndpointDomainType domainType,
Endpoint::Endpoint (const Endpoint::Type type,
const Endpoint::DomainType domainType,
const Endpoint::Protocol protocol,
const string& specification) :
_connected(false),
_socket(0),
_type(type),
_domainType(domainType),
_protocol(protocol),
_specification(specification) {
}
@ -127,7 +129,7 @@ Endpoint* Endpoint::serverFactory (const string& specification) {
/// @brief create an endpoint object from a string value
////////////////////////////////////////////////////////////////////////////////
Endpoint* Endpoint::factory (const EndpointType type,
Endpoint* Endpoint::factory (const Endpoint::Type type,
const string& specification) {
if (specification.size() < 7) {
return 0;
@ -139,19 +141,46 @@ Endpoint* Endpoint::factory (const EndpointType type,
copy = copy.substr(0, copy.size() - 1);
}
string proto = StringUtils::tolower(copy.substr(0, 7));
if (StringUtils::isPrefix(proto, "unix://")) {
// unix socket
return new EndpointUnix(type, specification, copy.substr(7, copy.size() - 7));
Endpoint::Protocol protocol = PROTOCOL_UNKNOWN;
// read protocol from string
size_t found = copy.find('@');
if (found != string::npos) {
string protoString = copy.substr(0, found);
if (protoString == "https") {
protocol = PROTOCOL_HTTPS;
copy = copy.substr(strlen("https@"));
}
else if (protoString == "pb") {
protocol = PROTOCOL_BINARY;
copy = copy.substr(strlen("pb@"));
}
else if (protoString == "http") {
protocol = PROTOCOL_HTTP;
copy = copy.substr(strlen("http@"));
}
else {
// invalid protocol
return 0;
}
}
else if (! StringUtils::isPrefix(proto, "tcp://")) {
else {
// no protocol specified, use HTTP
protocol = PROTOCOL_HTTP;
}
string domainType = StringUtils::tolower(copy.substr(0, 7));
if (StringUtils::isPrefix(domainType, "unix://")) {
// unix socket
return new EndpointUnix(type, protocol, specification, copy.substr(strlen("unix://")));
}
else if (! StringUtils::isPrefix(domainType, "tcp://")) {
// invalid type
return 0;
}
// tcp/ip
copy = copy.substr(6, copy.length() - 6);
size_t found;
copy = copy.substr(strlen("tcp://"), copy.length());
if (copy[0] == '[') {
// ipv6
@ -160,14 +189,14 @@ Endpoint* Endpoint::factory (const EndpointType type,
// hostname and port (e.g. [address]:port)
uint16_t port = (uint16_t) StringUtils::uint32(copy.substr(found + 2));
return new EndpointIpV6(type, specification, copy.substr(1, found - 1), port);
return new EndpointIpV6(type, protocol, specification, copy.substr(1, found - 1), port);
}
found = copy.find("]", 1);
if (found != string::npos && found + 1 == copy.size()) {
// hostname only (e.g. [address])
return new EndpointIpV6(type, specification, copy.substr(1, found - 1), EndpointIp::_defaultPort);
return new EndpointIpV6(type, protocol, specification, copy.substr(1, found - 1), EndpointIp::_defaultPort);
}
// invalid address specification
@ -181,11 +210,11 @@ Endpoint* Endpoint::factory (const EndpointType type,
// hostname and port
uint16_t port = (uint16_t) StringUtils::uint32(copy.substr(found + 1));
return new EndpointIpV4(type, specification, copy.substr(0, found), port);
return new EndpointIpV4(type, protocol, specification, copy.substr(0, found), port);
}
// hostname only
return new EndpointIpV4(type, specification, copy, EndpointIp::_defaultPort);
return new EndpointIpV4(type, protocol, specification, copy, EndpointIp::_defaultPort);
}
////////////////////////////////////////////////////////////////////////////////
@ -251,10 +280,11 @@ bool Endpoint::setSocketFlags (socket_t _socket) {
/// @brief creates a Unix socket endpoint
////////////////////////////////////////////////////////////////////////////////
EndpointUnix::EndpointUnix (const EndpointType type,
EndpointUnix::EndpointUnix (const Endpoint::Type type,
const Endpoint::Protocol protocol,
string const& specification,
string const& path) :
Endpoint(type, ENDPOINT_UNIX, specification),
Endpoint(type, ENDPOINT_UNIX, protocol, specification),
_path(path) {
}
@ -416,12 +446,13 @@ bool EndpointUnix::initIncoming (socket_t incoming) {
/// @brief creates an IP socket endpoint
////////////////////////////////////////////////////////////////////////////////
EndpointIp::EndpointIp (const EndpointType type,
const EndpointDomainType domainType,
EndpointIp::EndpointIp (const Endpoint::Type type,
const Endpoint::DomainType domainType,
const Endpoint::Protocol protocol,
string const& specification,
string const& host,
const uint16_t port) :
Endpoint(type, domainType, specification), _host(host), _port(port) {
Endpoint(type, domainType, protocol, specification), _host(host), _port(port) {
assert(domainType == ENDPOINT_IPV4 || domainType == ENDPOINT_IPV6);
}
@ -628,11 +659,12 @@ bool EndpointIp::initIncoming (socket_t incoming) {
/// @brief creates an IPv4 socket endpoint
////////////////////////////////////////////////////////////////////////////////
EndpointIpV4::EndpointIpV4 (const EndpointType type,
EndpointIpV4::EndpointIpV4 (const Endpoint::Type type,
const Endpoint::Protocol protocol,
string const& specification,
string const& host,
const uint16_t port) :
EndpointIp(type, ENDPOINT_IPV4, specification, host, port) {
EndpointIp(type, ENDPOINT_IPV4, protocol, specification, host, port) {
}
////////////////////////////////////////////////////////////////////////////////
@ -663,11 +695,12 @@ EndpointIpV4::~EndpointIpV4 () {
/// @brief creates an IPv6 socket endpoint
////////////////////////////////////////////////////////////////////////////////
EndpointIpV6::EndpointIpV6 (const EndpointType type,
EndpointIpV6::EndpointIpV6 (const Endpoint::Type type,
const Endpoint::Protocol protocol,
string const& specification,
string const& host,
const uint16_t port) :
EndpointIp(type, ENDPOINT_IPV6, specification, host, port) {
EndpointIp(type, ENDPOINT_IPV6, protocol, specification, host, port) {
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -49,34 +49,60 @@
namespace triagens {
namespace rest {
////////////////////////////////////////////////////////////////////////////////
/// @brief endpoint types
////////////////////////////////////////////////////////////////////////////////
enum EndpointType {
ENDPOINT_SERVER,
ENDPOINT_CLIENT
};
////////////////////////////////////////////////////////////////////////////////
/// @brief endpoint types
////////////////////////////////////////////////////////////////////////////////
enum EndpointDomainType {
ENDPOINT_UNKNOWN = 0,
#ifdef TRI_HAVE_LINUX_SOCKETS
ENDPOINT_UNIX,
#endif
ENDPOINT_IPV4,
ENDPOINT_IPV6
};
////////////////////////////////////////////////////////////////////////////////
/// @brief endpoint specification
////////////////////////////////////////////////////////////////////////////////
class Endpoint {
// -----------------------------------------------------------------------------
// --SECTION-- typedefs
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Rest
/// @{
////////////////////////////////////////////////////////////////////////////////
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief endpoint types
////////////////////////////////////////////////////////////////////////////////
enum Type {
ENDPOINT_SERVER,
ENDPOINT_CLIENT
};
////////////////////////////////////////////////////////////////////////////////
/// @brief endpoint types
////////////////////////////////////////////////////////////////////////////////
enum DomainType {
ENDPOINT_UNKNOWN = 0,
#ifdef TRI_HAVE_LINUX_SOCKETS
ENDPOINT_UNIX,
#endif
ENDPOINT_IPV4,
ENDPOINT_IPV6
};
////////////////////////////////////////////////////////////////////////////////
/// @brief protocols used for endpoints
////////////////////////////////////////////////////////////////////////////////
enum Protocol {
PROTOCOL_UNKNOWN,
PROTOCOL_HTTP,
PROTOCOL_HTTPS,
PROTOCOL_BINARY
};
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- constructors / destructors
// -----------------------------------------------------------------------------
@ -92,7 +118,10 @@ namespace triagens {
/// @brief creates an endpoint
////////////////////////////////////////////////////////////////////////////////
Endpoint (EndpointType, EndpointDomainType, const string&);
Endpoint (const Type,
const DomainType,
const Protocol,
const string&);
public:
@ -133,7 +162,7 @@ namespace triagens {
/// @brief creates an endpoint from a string value
////////////////////////////////////////////////////////////////////////////////
static Endpoint* factory (const EndpointType type,
static Endpoint* factory (const Type type,
const string&);
////////////////////////////////////////////////////////////////////////////////
@ -184,10 +213,18 @@ namespace triagens {
/// @brief get the type of an endpoint
////////////////////////////////////////////////////////////////////////////////
EndpointType getType () const {
Type getType () const {
return _type;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the protocol of an endpoint
////////////////////////////////////////////////////////////////////////////////
Protocol getProtocol () const {
return _protocol;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the original endpoint specification
////////////////////////////////////////////////////////////////////////////////
@ -251,13 +288,19 @@ namespace triagens {
/// @brief endpoint type
////////////////////////////////////////////////////////////////////////////////
EndpointType _type;
Type _type;
////////////////////////////////////////////////////////////////////////////////
/// @brief endpoint domain type
////////////////////////////////////////////////////////////////////////////////
EndpointDomainType _domainType;
DomainType _domainType;
////////////////////////////////////////////////////////////////////////////////
/// @brief protocol used
////////////////////////////////////////////////////////////////////////////////
Protocol _protocol;
////////////////////////////////////////////////////////////////////////////////
/// @brief original endpoint specification
@ -294,9 +337,10 @@ namespace triagens {
/// @brief creates an endpoint
////////////////////////////////////////////////////////////////////////////////
EndpointUnix (const EndpointType,
string const&,
string const&);
EndpointUnix (const Type,
const Protocol,
string const&,
string const&);
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys an endpoint
@ -419,8 +463,9 @@ namespace triagens {
/// @brief creates an endpoint
////////////////////////////////////////////////////////////////////////////////
EndpointIp (const EndpointType,
const EndpointDomainType,
EndpointIp (const Type,
const DomainType,
const Protocol,
string const&,
string const&,
const uint16_t);
@ -593,7 +638,8 @@ namespace triagens {
/// @brief creates an endpoint
////////////////////////////////////////////////////////////////////////////////
EndpointIpV4 (const EndpointType,
EndpointIpV4 (const Type,
const Protocol,
string const&,
string const&,
const uint16_t);
@ -654,7 +700,8 @@ namespace triagens {
/// @brief creates an endpoint
////////////////////////////////////////////////////////////////////////////////
EndpointIpV6 (const EndpointType,
EndpointIpV6 (const Type,
const Protocol,
string const&,
string const&,
const uint16_t);

View File

@ -48,9 +48,8 @@ using namespace triagens::rest;
/// @brief create an endpoint list
////////////////////////////////////////////////////////////////////////////////
EndpointList::EndpointList () :
_httpEndpoints(),
_binaryEndpoints() {
EndpointList::EndpointList () :
_lists() {
}
////////////////////////////////////////////////////////////////////////////////
@ -58,13 +57,12 @@ EndpointList::EndpointList () :
////////////////////////////////////////////////////////////////////////////////
EndpointList::~EndpointList () {
// free memory
for (ListType::iterator i = _httpEndpoints.begin(); i != _httpEndpoints.end(); ++i) {
delete *i;
}
for (ListType::iterator i = _binaryEndpoints.begin(); i != _binaryEndpoints.end(); ++i) {
delete *i;
for (map<Endpoint::Protocol, ListType>::iterator i = _lists.begin(); i != _lists.end(); ++i) {
for (ListType::iterator i2 = (*i).second.begin(); i2 != (*i).second.end(); ++i2) {
delete *i2;
}
(*i).second.clear();
}
}
@ -86,70 +84,37 @@ EndpointList::~EndpointList () {
////////////////////////////////////////////////////////////////////////////////
void EndpointList::dump () {
for (EndpointList::ListType::const_iterator i = _httpEndpoints.begin(); i != _httpEndpoints.end(); ++i) {
LOGGER_INFO << "using endpoint '" << (*i)->getSpecification() << "' for HTTP requests";
}
for (EndpointList::ListType::const_iterator i = _binaryEndpoints.begin(); i != _binaryEndpoints.end(); ++i) {
LOGGER_INFO << "using endpoint '" << (*i)->getSpecification() << "' for binary requests";
for (map<Endpoint::Protocol, ListType>::const_iterator i = _lists.begin(); i != _lists.end(); ++i) {
for (ListType::const_iterator i2 = (*i).second.begin(); i2 != (*i).second.end(); ++i2) {
LOGGER_INFO << "using endpoint '" << (*i2)->getSpecification() << "' for " << getName((*i).first) << " requests";
}
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return all endpoints for HTTP requests
/// @brief return all endpoints for a specific protocol
////////////////////////////////////////////////////////////////////////////////
EndpointList::ListType EndpointList::getHttpEndpoints () const {
EndpointList::ListType EndpointList::getEndpoints (const Endpoint::Protocol protocol) const {
EndpointList::ListType result;
map<Endpoint::Protocol, EndpointList::ListType>::const_iterator i = _lists.find(protocol);
for (EndpointList::ListType::const_iterator i = _httpEndpoints.begin(); i != _httpEndpoints.end(); ++i) {
result.insert(*i);
if (i != _lists.end()) {
for (ListType::const_iterator i2 = i->second.begin(); i2 != i->second.end(); ++i2) {
result.insert(*i2);
}
}
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return all endpoints for binary requests
/// @brief adds an endpoint for a specific protocol
////////////////////////////////////////////////////////////////////////////////
EndpointList::ListType EndpointList::getBinaryEndpoints () const {
EndpointList::ListType result;
bool EndpointList::addEndpoint (const Endpoint::Protocol protocol, Endpoint* endpoint) {
_lists[protocol].insert(endpoint);
for (EndpointList::ListType::const_iterator i = _binaryEndpoints.begin(); i != _binaryEndpoints.end(); ++i) {
result.insert(*i);
}
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief adds an endpoint for HTTP requests
////////////////////////////////////////////////////////////////////////////////
bool EndpointList::addHttpEndpoint (const string& specification) {
Endpoint* endpoint = Endpoint::serverFactory(specification);
if (endpoint == 0) {
return false;
}
_httpEndpoints.insert(endpoint);
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief adds an endpoint for binary requests
////////////////////////////////////////////////////////////////////////////////
bool EndpointList::addBinaryEndpoint (const string& specification) {
Endpoint* endpoint = Endpoint::serverFactory(specification);
if (endpoint == 0) {
return false;
}
_binaryEndpoints.insert(endpoint);
return true;
}

View File

@ -100,6 +100,23 @@ namespace triagens {
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief return a protocol name
////////////////////////////////////////////////////////////////////////////////
static const string getName (const Endpoint::Protocol protocol) {
switch (protocol) {
case Endpoint::PROTOCOL_BINARY:
return "binary";
case Endpoint::PROTOCOL_HTTPS:
return "https";
case Endpoint::PROTOCOL_HTTP:
return "http";
default:
return "unknown";
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief dump all used endpoints
////////////////////////////////////////////////////////////////////////////////
@ -107,28 +124,16 @@ namespace triagens {
void dump();
////////////////////////////////////////////////////////////////////////////////
/// @brief return all endpoints for HTTP requests
/// @brief return all endpoints for a specific protocol
////////////////////////////////////////////////////////////////////////////////
ListType getHttpEndpoints () const;
ListType getEndpoints (const Endpoint::Protocol) const;
////////////////////////////////////////////////////////////////////////////////
/// @brief return all endpoints for binary requests
/// @brief adds an endpoint for a specific protocol
////////////////////////////////////////////////////////////////////////////////
ListType getBinaryEndpoints () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief adds an endpoint for HTTP requests
////////////////////////////////////////////////////////////////////////////////
bool addHttpEndpoint (const string&);
////////////////////////////////////////////////////////////////////////////////
/// @brief adds an endpoint for binary requests
////////////////////////////////////////////////////////////////////////////////
bool addBinaryEndpoint (const string&);
bool addEndpoint (const Endpoint::Protocol, Endpoint*);
////////////////////////////////////////////////////////////////////////////////
/// @}
@ -146,16 +151,10 @@ namespace triagens {
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief set of endpoints for HTTP requests
/// @brief lists of endpoints
////////////////////////////////////////////////////////////////////////////////
ListType _httpEndpoints;
////////////////////////////////////////////////////////////////////////////////
/// @brief set of endpoints for binary requests
////////////////////////////////////////////////////////////////////////////////
ListType _binaryEndpoints;
map<Endpoint::Protocol, ListType> _lists;
////////////////////////////////////////////////////////////////////////////////
/// @}