diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000000..387684359d --- /dev/null +++ b/.clang-format @@ -0,0 +1,4 @@ +BasedOnStyle: Google +DerivePointerAlignment: false +PointerAlignment: Left +Standard: Cpp11 diff --git a/CHANGELOG b/CHANGELOG index 12e59f3fd7..d56a42358b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,11 +5,14 @@ v2.8.5 (2016-03-XX) and #1770 (Display ACTUAL query time in aardvark's AQL editor) * Windows: the unhandled exception handler now calls the windows logging - facilities directly without locks. + facilities directly without locks. This fixes lockups on crashes from the logging framework. * improve nullptr handling in logger. +* added new endpoint "srv://" for DNS service records + + v2.8.4 (2016-03-01) ------------------- diff --git a/Makefile.in b/Makefile.in index f257185134..d6366a46a3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -525,12 +525,12 @@ am__lib_libarango_a_SOURCES_DIST = lib/Basics/application-exit.cpp \ lib/Rest/EndpointList.cpp lib/Rest/Endpoint.cpp \ lib/Rest/EndpointIp.cpp lib/Rest/EndpointIpV4.cpp \ lib/Rest/EndpointIpV6.cpp lib/Rest/EndpointUnixDomain.cpp \ - lib/Rest/HttpRequest.cpp lib/Rest/HttpResponse.cpp \ - lib/Rest/InitializeRest.cpp lib/Rest/SslInterface.cpp \ - lib/Rest/Version.cpp lib/Utilities/DummyShell.cpp \ - lib/Utilities/LineEditor.cpp lib/Utilities/ScriptLoader.cpp \ - lib/Utilities/ShellBase.cpp lib/Zip/ioapi.cpp \ - lib/Zip/unzip.cpp lib/Zip/zip.cpp \ + lib/Rest/EndpointSrv.cpp lib/Rest/HttpRequest.cpp \ + lib/Rest/HttpResponse.cpp lib/Rest/InitializeRest.cpp \ + lib/Rest/SslInterface.cpp lib/Rest/Version.cpp \ + lib/Utilities/DummyShell.cpp lib/Utilities/LineEditor.cpp \ + lib/Utilities/ScriptLoader.cpp lib/Utilities/ShellBase.cpp \ + lib/Zip/ioapi.cpp lib/Zip/unzip.cpp lib/Zip/zip.cpp \ 3rdParty/linenoise-ng/src/linenoise.cpp \ 3rdParty/linenoise-ng/src/ConvertUTF.cpp \ 3rdParty/linenoise-ng/src/wcwidth.cpp \ @@ -623,6 +623,7 @@ am_lib_libarango_a_OBJECTS = \ lib/Rest/lib_libarango_a-EndpointIpV4.$(OBJEXT) \ lib/Rest/lib_libarango_a-EndpointIpV6.$(OBJEXT) \ lib/Rest/lib_libarango_a-EndpointUnixDomain.$(OBJEXT) \ + lib/Rest/lib_libarango_a-EndpointSrv.$(OBJEXT) \ lib/Rest/lib_libarango_a-HttpRequest.$(OBJEXT) \ lib/Rest/lib_libarango_a-HttpResponse.$(OBJEXT) \ lib/Rest/lib_libarango_a-InitializeRest.$(OBJEXT) \ @@ -1363,12 +1364,13 @@ lib_libarango_a_SOURCES = lib/Basics/application-exit.cpp \ lib/Rest/EndpointList.cpp lib/Rest/Endpoint.cpp \ lib/Rest/EndpointIp.cpp lib/Rest/EndpointIpV4.cpp \ lib/Rest/EndpointIpV6.cpp lib/Rest/EndpointUnixDomain.cpp \ - lib/Rest/HttpRequest.cpp lib/Rest/HttpResponse.cpp \ - lib/Rest/InitializeRest.cpp lib/Rest/SslInterface.cpp \ - lib/Rest/Version.cpp lib/Utilities/DummyShell.cpp \ - lib/Utilities/LineEditor.cpp lib/Utilities/ScriptLoader.cpp \ - lib/Utilities/ShellBase.cpp lib/Zip/ioapi.cpp \ - lib/Zip/unzip.cpp lib/Zip/zip.cpp $(am__append_3) \ + lib/Rest/EndpointSrv.cpp lib/Rest/HttpRequest.cpp \ + lib/Rest/HttpResponse.cpp lib/Rest/InitializeRest.cpp \ + lib/Rest/SslInterface.cpp lib/Rest/Version.cpp \ + lib/Utilities/DummyShell.cpp lib/Utilities/LineEditor.cpp \ + lib/Utilities/ScriptLoader.cpp lib/Utilities/ShellBase.cpp \ + lib/Zip/ioapi.cpp lib/Zip/unzip.cpp lib/Zip/zip.cpp \ + $(am__append_3) \ 3rdParty/velocypack/src/AttributeTranslator.cpp \ 3rdParty/velocypack/src/Builder.cpp \ 3rdParty/velocypack/src/Collection.cpp \ @@ -3246,6 +3248,8 @@ lib/Rest/lib_libarango_a-EndpointIpV6.$(OBJEXT): \ lib/Rest/$(am__dirstamp) lib/Rest/$(DEPDIR)/$(am__dirstamp) lib/Rest/lib_libarango_a-EndpointUnixDomain.$(OBJEXT): \ lib/Rest/$(am__dirstamp) lib/Rest/$(DEPDIR)/$(am__dirstamp) +lib/Rest/lib_libarango_a-EndpointSrv.$(OBJEXT): \ + lib/Rest/$(am__dirstamp) lib/Rest/$(DEPDIR)/$(am__dirstamp) lib/Rest/lib_libarango_a-HttpRequest.$(OBJEXT): \ lib/Rest/$(am__dirstamp) lib/Rest/$(DEPDIR)/$(am__dirstamp) lib/Rest/lib_libarango_a-HttpResponse.$(OBJEXT): \ @@ -4166,6 +4170,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointIpV4.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointIpV6.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointList.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointSrv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointUnixDomain.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@lib/Rest/$(DEPDIR)/lib_libarango_a-HttpRequest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@lib/Rest/$(DEPDIR)/lib_libarango_a-HttpResponse.Po@am__quote@ @@ -8258,6 +8263,20 @@ lib/Rest/lib_libarango_a-EndpointUnixDomain.obj: lib/Rest/EndpointUnixDomain.cpp @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_libarango_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lib/Rest/lib_libarango_a-EndpointUnixDomain.obj `if test -f 'lib/Rest/EndpointUnixDomain.cpp'; then $(CYGPATH_W) 'lib/Rest/EndpointUnixDomain.cpp'; else $(CYGPATH_W) '$(srcdir)/lib/Rest/EndpointUnixDomain.cpp'; fi` +lib/Rest/lib_libarango_a-EndpointSrv.o: lib/Rest/EndpointSrv.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_libarango_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lib/Rest/lib_libarango_a-EndpointSrv.o -MD -MP -MF lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointSrv.Tpo -c -o lib/Rest/lib_libarango_a-EndpointSrv.o `test -f 'lib/Rest/EndpointSrv.cpp' || echo '$(srcdir)/'`lib/Rest/EndpointSrv.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointSrv.Tpo lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointSrv.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='lib/Rest/EndpointSrv.cpp' object='lib/Rest/lib_libarango_a-EndpointSrv.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_libarango_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lib/Rest/lib_libarango_a-EndpointSrv.o `test -f 'lib/Rest/EndpointSrv.cpp' || echo '$(srcdir)/'`lib/Rest/EndpointSrv.cpp + +lib/Rest/lib_libarango_a-EndpointSrv.obj: lib/Rest/EndpointSrv.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_libarango_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lib/Rest/lib_libarango_a-EndpointSrv.obj -MD -MP -MF lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointSrv.Tpo -c -o lib/Rest/lib_libarango_a-EndpointSrv.obj `if test -f 'lib/Rest/EndpointSrv.cpp'; then $(CYGPATH_W) 'lib/Rest/EndpointSrv.cpp'; else $(CYGPATH_W) '$(srcdir)/lib/Rest/EndpointSrv.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointSrv.Tpo lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointSrv.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='lib/Rest/EndpointSrv.cpp' object='lib/Rest/lib_libarango_a-EndpointSrv.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_libarango_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lib/Rest/lib_libarango_a-EndpointSrv.obj `if test -f 'lib/Rest/EndpointSrv.cpp'; then $(CYGPATH_W) 'lib/Rest/EndpointSrv.cpp'; else $(CYGPATH_W) '$(srcdir)/lib/Rest/EndpointSrv.cpp'; fi` + lib/Rest/lib_libarango_a-HttpRequest.o: lib/Rest/HttpRequest.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_libarango_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lib/Rest/lib_libarango_a-HttpRequest.o -MD -MP -MF lib/Rest/$(DEPDIR)/lib_libarango_a-HttpRequest.Tpo -c -o lib/Rest/lib_libarango_a-HttpRequest.o `test -f 'lib/Rest/HttpRequest.cpp' || echo '$(srcdir)/'`lib/Rest/HttpRequest.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) lib/Rest/$(DEPDIR)/lib_libarango_a-HttpRequest.Tpo lib/Rest/$(DEPDIR)/lib_libarango_a-HttpRequest.Po diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index c66c558b45..5acf2f1f7d 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -139,6 +139,7 @@ add_library( Rest/EndpointIp.cpp Rest/EndpointIpV4.cpp Rest/EndpointIpV6.cpp + Rest/EndpointSrv.cpp Rest/HttpRequest.cpp Rest/HttpResponse.cpp Rest/InitializeRest.cpp diff --git a/lib/Makefile.files b/lib/Makefile.files index b6d9bab504..7878cf7de3 100644 --- a/lib/Makefile.files +++ b/lib/Makefile.files @@ -80,6 +80,7 @@ lib_libarango_a_SOURCES = \ lib/Rest/EndpointIpV4.cpp \ lib/Rest/EndpointIpV6.cpp \ lib/Rest/EndpointUnixDomain.cpp \ + lib/Rest/EndpointSrv.cpp \ lib/Rest/HttpRequest.cpp \ lib/Rest/HttpResponse.cpp \ lib/Rest/InitializeRest.cpp \ diff --git a/lib/Rest/Endpoint.cpp b/lib/Rest/Endpoint.cpp index 35996670fe..1886184d44 100644 --- a/lib/Rest/Endpoint.cpp +++ b/lib/Rest/Endpoint.cpp @@ -39,6 +39,7 @@ #endif #include "Rest/EndpointIpV4.h" #include "Rest/EndpointIpV6.h" +#include "Rest/EndpointSrv.h" using namespace std; using namespace triagens::basics; @@ -116,25 +117,19 @@ std::string Endpoint::getUnifiedForm (const std::string& specification) { return ""; } #endif + else if (StringUtils::isPrefix(copy, "srv://")) { + return copy; + } else if (! StringUtils::isPrefix(copy, "ssl://") && ! StringUtils::isPrefix(copy, "tcp://")) { // invalid type return ""; } - size_t found; - /* - // turn "localhost" into "127.0.0.1" - // technically this is not always correct, but circumvents obvious problems - // when the configuration contains both "127.0.0.1" and "localhost" endpoints - found = copy.find("localhost"); - if (found != string::npos && found >= 6 && found < 10) { - copy = copy.replace(found, strlen("localhost"), "127.0.0.1"); - } - */ - // tcp/ip or ssl + size_t found; string temp = copy.substr(6, copy.length()); // strip tcp:// or ssl:// + if (temp[0] == '[') { // ipv6 found = temp.find("]:", 1); @@ -144,6 +139,7 @@ std::string Endpoint::getUnifiedForm (const std::string& specification) { } found = temp.find("]", 1); + if (found != string::npos && found > 2 && found + 1 == temp.size()) { // hostname only (e.g. [address]) return copy + ":" + StringUtils::itoa(EndpointIp::_defaultPort); @@ -227,7 +223,6 @@ Endpoint* Endpoint::factory (const Endpoint::EndpointType type, EncryptionType encryption = ENCRYPTION_NONE; string domainType = StringUtils::tolower(copy.substr(0, 7)); - if (StringUtils::isPrefix(domainType, "ssl://")) { // ssl encryption = ENCRYPTION_SSL; @@ -246,6 +241,14 @@ Endpoint* Endpoint::factory (const Endpoint::EndpointType type, } #endif + else if (StringUtils::isPrefix(domainType, "srv://")) { + if (type != ENDPOINT_CLIENT) { + return nullptr; + } + + return new EndpointSrv(specification.substr(6)); + } + else if (! StringUtils::isPrefix(domainType, "tcp://")) { // invalid type return nullptr; diff --git a/lib/Rest/Endpoint.h b/lib/Rest/Endpoint.h index 4e8c6c5d6b..c80498dfd7 100644 --- a/lib/Rest/Endpoint.h +++ b/lib/Rest/Endpoint.h @@ -88,7 +88,8 @@ namespace triagens { DOMAIN_UNKNOWN = 0, DOMAIN_UNIX, DOMAIN_IPV4, - DOMAIN_IPV6 + DOMAIN_IPV6, + DOMAIN_SRV }; //////////////////////////////////////////////////////////////////////////////// @@ -205,7 +206,7 @@ namespace triagens { /// @brief return whether the endpoint is connected //////////////////////////////////////////////////////////////////////////////// - bool isConnected () const { + virtual bool isConnected () const { return _connected; } @@ -221,7 +222,7 @@ namespace triagens { /// @brief get the domain type of an endpoint //////////////////////////////////////////////////////////////////////////////// - DomainType getDomainType () const { + virtual DomainType getDomainType () const { return _domainType; } diff --git a/lib/Rest/EndpointIp.cpp b/lib/Rest/EndpointIp.cpp index 474efc2eaa..440dc6780a 100644 --- a/lib/Rest/EndpointIp.cpp +++ b/lib/Rest/EndpointIp.cpp @@ -126,6 +126,7 @@ TRI_socket_t EndpointIp::connectSocket (const struct addrinfo* aip, #ifdef _WIN32 char windowsErrorBuf[256]; #endif + // set address and port char host[NI_MAXHOST]; char serv[NI_MAXSERV]; diff --git a/lib/Rest/EndpointSrv.cpp b/lib/Rest/EndpointSrv.cpp new file mode 100644 index 0000000000..f6e22dd14b --- /dev/null +++ b/lib/Rest/EndpointSrv.cpp @@ -0,0 +1,257 @@ +//////////////////////////////////////////////////////////////////////////////// +/// DISCLAIMER +/// +/// Copyright 2016 ArangoDB 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 +/// @author Copyright 2016, ArangoDB GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +#include "EndpointSrv.h" + +#ifndef _WIN32 + +#define BIND_4_COMPAT 1 // LINUX +#define BIND_8_COMPAT 1 // MACOSX + +#include +#include +#include +#include + +#include "Basics/logging.h" +#include "Rest/EndpointIp.h" + +using namespace triagens::basics; +using namespace triagens::rest; + +#if PACKETSZ > 1024 +#define MAXPACKET PACKETSZ +#else +#define MAXPACKET 1024 +#endif + +union QueryBuffer { + ::HEADER header; + unsigned char buffer[MAXPACKET]; +}; + +struct SrvRecord { + int priority; + int weight; + int port; + std::string name; +}; + +std::vector srvRecords(std::string specification) { + res_init(); + + char const* dname = specification.c_str(); + int nclass = ns_c_in; + int type = ns_t_srv; + + QueryBuffer answer; + int anslen = sizeof(answer); + + int n = res_search(dname, nclass, type, answer.buffer, anslen); + + std::vector services; + + if (n != -1) { + HEADER* hp = &answer.header; + + int qdcount = ntohs(hp->qdcount); + int ancount = ntohs(hp->ancount); + + unsigned char* msg = answer.buffer; + unsigned char* eom = msg + n; + unsigned char* cp = msg + sizeof(HEADER); + + unsigned char hostbuf[256]; + + while (0 < qdcount-- && cp < eom) { + n = dn_expand(msg, eom, cp, (char*)hostbuf, 256); + + if (n < 0) { + LOG_WARNING("DNS record for '%s' is corrupt", specification.c_str()); + return {}; + } + + cp += n + QFIXEDSZ; + } + + // loop through the answer buffer and extract SRV records + while (0 < ancount-- && cp < eom) { + n = dn_expand(msg, eom, cp, (char*)hostbuf, 256); + + if (n < 0) { + LOG_WARNING("DNS record for '%s' is corrupt", specification.c_str()); + return {}; + } + + cp += n; + + int type = _getshort(cp); + cp += 2; + + int nclass = _getshort(cp); + cp += 2; + + int ttl = _getlong(cp); + cp += 4; + + int dlen = _getshort(cp); + cp += 2; + + int priority = _getshort(cp); + cp += 2; + + int weight = _getshort(cp); + cp += 2; + + int port = _getshort(cp); + cp += 2; + + n = dn_expand(msg, eom, cp, (char*)hostbuf, 256); + + if (n < 0) { + LOG_WARNING("DNS record for '%s' is corrupt", specification.c_str()); + break; + } + + cp += n; + + LOG_TRACE("DNS record for '%s': type %d, class %d, ttl %d, len %d, prio %d, " + " weight %d, port %d, host '%s'", specification.c_str(), + type, nclass, ttl, dlen, priority, weight, port, hostbuf); + + if (type != T_SRV) { + continue; + } + + SrvRecord srv; + + srv.weight = weight; + srv.priority = priority; + srv.port = port; + srv.name = (char*)hostbuf; + + services.push_back(srv); + } + } else { + LOG_WARNING("DNS record for '%s' not found", specification.c_str()); + } + + std::sort(services.begin(), services.end(), + [](SrvRecord const& lhs, SrvRecord const& rhs) { + if (lhs.priority != rhs.priority) { + return lhs.priority < rhs.priority; + } + + return lhs.weight > rhs.weight; + }); + + return services; +} + +#else + +std::vector srvRecords(std::string specification) { + return {}; +} + +#endif + +EndpointSrv::EndpointSrv(std::string const& specification) + : Endpoint(ENDPOINT_CLIENT, DOMAIN_SRV, ENCRYPTION_NONE, specification, 0) { + LOG_ERROR("%s", specification.c_str()); +} + +EndpointSrv::~EndpointSrv() {} + +bool EndpointSrv::isConnected() const { + if (_endpoint != nullptr) { + return _endpoint->isConnected(); + } + + return false; +} + +TRI_socket_t EndpointSrv::connect(double connectTimeout, + double requestTimeout) { + LOG_ERROR("connecting to ip endpoint '%s'", _specification.c_str()); + + auto services = srvRecords(_specification); + + TRI_socket_t res; + + for (auto service : services) { + std::string spec = + "tcp://" + service.name + ":" + StringUtils::itoa(service.port); + + _endpoint.reset(Endpoint::clientFactory(spec)); + + res = _endpoint->connect(connectTimeout, requestTimeout); + + if (_endpoint->isConnected()) { + return res; + } + } + + TRI_invalidatesocket(&res); + return res; +} + +void EndpointSrv::disconnect() { + if (_endpoint != nullptr) { + _endpoint->disconnect(); + } +} + +bool EndpointSrv::initIncoming(TRI_socket_t) { return false; } + +int EndpointSrv::getDomain() const { + if (_endpoint != nullptr) { + return _endpoint->getDomain(); + } + + return -1; +} + +int EndpointSrv::getPort() const { + if (_endpoint != nullptr) { + return _endpoint->getPort(); + } + + return -1; +} + +std::string EndpointSrv::getHost() const { + if (_endpoint != nullptr) { + return _endpoint->getHost(); + } + + return ""; +} + +std::string EndpointSrv::getHostString() const { + if (_endpoint != nullptr) { + return _endpoint->getHostString(); + } + + return ""; +} diff --git a/lib/Rest/EndpointSrv.h b/lib/Rest/EndpointSrv.h new file mode 100644 index 0000000000..6f9899da79 --- /dev/null +++ b/lib/Rest/EndpointSrv.h @@ -0,0 +1,53 @@ +//////////////////////////////////////////////////////////////////////////////// +/// DISCLAIMER +/// +/// Copyright 2016 ArangoDB 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 +/// @author Copyright 2016, ArangoDB GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +#ifndef ARANGODB_REST_ENDPOINT_SRV_H +#define ARANGODB_REST_ENDPOINT_SRV_H 1 + +#include "Rest/Endpoint.h" + +namespace triagens { +namespace rest { +class EndpointSrv final : public Endpoint { + public: + explicit EndpointSrv(std::string const&); + + ~EndpointSrv(); + + public: + bool isConnected() const override; + TRI_socket_t connect(double, double) override; + void disconnect() override; + bool initIncoming(TRI_socket_t) override; + int getDomain() const override; + int getPort() const override; + std::string getHost() const override; + std::string getHostString() const override; + + private: + std::unique_ptr _endpoint; +}; +} +} + +#endif