From ef12d8dc2c41870e583b914acde7eaefa0f2be5c Mon Sep 17 00:00:00 2001 From: Jan Christoph Uhde Date: Mon, 1 Aug 2016 11:48:30 +0200 Subject: [PATCH] struggle with ctor --- arangod/Cluster/ClusterComm.cpp | 6 +++ lib/Rest/FakeRequest.h | 6 ++- lib/Rest/GeneralRequest.cpp | 58 ------------------------ lib/Rest/GeneralRequest.h | 38 ++++++---------- lib/Rest/HttpRequest.cpp | 78 +++++++++++++++++++++++++++++++-- lib/Rest/HttpRequest.h | 50 +++++++++++++++++++++ lib/Rest/VppRequest.h | 5 +++ 7 files changed, 155 insertions(+), 86 deletions(-) diff --git a/arangod/Cluster/ClusterComm.cpp b/arangod/Cluster/ClusterComm.cpp index 21806fcae3..44f707b898 100644 --- a/arangod/Cluster/ClusterComm.cpp +++ b/arangod/Cluster/ClusterComm.cpp @@ -1275,9 +1275,15 @@ size_t ClusterComm::performSingleRequest( GeneralRequest::ContentType type = GeneralRequest::ContentType::JSON; // Add correct recognition of content type later. basics::StringBuffer& buffer = req.result.result->getBody(); + auto answer = new FakeRequest(type, buffer.c_str(), static_cast(buffer.length())); answer->setHeaders(req.result.result->getHeaderFields()); + + auto answer = new HttpRequest::createFakeRequest( + type, buffer.c_str(), static_cast(buffer.length()), + req.result.result->getHeaderFields()); + req.result.answer.reset(static_cast(answer)); req.result.answer_code = static_cast( req.result.result->getHttpReturnCode()); diff --git a/lib/Rest/FakeRequest.h b/lib/Rest/FakeRequest.h index 2ed4be6402..1b386e5315 100644 --- a/lib/Rest/FakeRequest.h +++ b/lib/Rest/FakeRequest.h @@ -50,7 +50,11 @@ class FakeRequest : public GeneralRequest { arangodb::velocypack::Options const*) override final; void setHeaders(std::unordered_map const& headers) { - _headers = headers; // this is from the base class + throw std::logic_error("the base class has no headers anymore."); + // add a new ctor to HttpRequest that is cheaper in order to wrap simple + // http request + // and remove The Fake request + //_headers = headers; // this is from the base class } private: diff --git a/lib/Rest/GeneralRequest.cpp b/lib/Rest/GeneralRequest.cpp index d2750ed7ce..70a9fd8616 100644 --- a/lib/Rest/GeneralRequest.cpp +++ b/lib/Rest/GeneralRequest.cpp @@ -36,13 +36,10 @@ std::string GeneralRequest::translateVersion(ProtocolVersion version) { switch (version) { case ProtocolVersion::VPP_1_0: return "VPP/1.0"; - case ProtocolVersion::HTTP_1_1: return "HTTP/1.1"; - case ProtocolVersion::HTTP_1_0: return "HTTP/1.0"; - case ProtocolVersion::UNKNOWN: default: { return "HTTP/1.0"; } } @@ -210,61 +207,6 @@ void GeneralRequest::addSuffix(std::string&& part) { _suffix.emplace_back(StringUtils::urlDecode(part)); } -std::string const& GeneralRequest::header(std::string const& key) const { - auto it = _headers.find(key); - - if (it == _headers.end()) { - return StaticStrings::Empty; - } - - return it->second; -} - -std::string const& GeneralRequest::header(std::string const& key, - bool& found) const { - auto it = _headers.find(key); - - if (it == _headers.end()) { - found = false; - return StaticStrings::Empty; - } - - found = true; - return it->second; -} - -std::string const& GeneralRequest::value(std::string const& key) const { - if (!_values.empty()) { - auto it = _values.find(key); - - if (it != _values.end()) { - return it->second; - } - } - - return StaticStrings::Empty; -} - -std::string const& GeneralRequest::value(std::string const& key, - bool& found) const { - if (!_values.empty()) { - auto it = _values.find(key); - - if (it != _values.end()) { - found = true; - return it->second; - } - } - - found = false; - return StaticStrings::Empty; -} - -void GeneralRequest::setArrayValue(char* key, size_t length, - char const* value) { - _arrayValues[std::string(key, length)].emplace_back(value); -} - bool GeneralRequest::velocyPackResponse() const { // needs only to be used in http case?! std::string const& result = header(StaticStrings::Accept); diff --git a/lib/Rest/GeneralRequest.h b/lib/Rest/GeneralRequest.h index e30429d4a3..73dfb19fcb 100644 --- a/lib/Rest/GeneralRequest.h +++ b/lib/Rest/GeneralRequest.h @@ -48,6 +48,7 @@ class RequestContext; class GeneralRequest { GeneralRequest(GeneralRequest const&) = delete; GeneralRequest& operator=(GeneralRequest const&) = delete; + GeneralRequest(GenerakRequest&&) = default; public: // VSTREAM_CRED: This method is used for sending Authentication @@ -156,24 +157,21 @@ class GeneralRequest { void addSuffix(std::string&& part); // get value from headers map. The key must be lowercase. - std::string const& header(std::string const& key) const; - std::string const& header(std::string const& key, bool& found) const; + virtual std::string const& header(std::string const& key) const = 0; + virtual std::string const& header(std::string const& key, + bool& found) const = 0; // return headers map - std::unordered_map const& headers() const { - return _headers; - } + virtual std::unordered_map const& headers() + const = 0; - std::string const& value(std::string const& key) const; - std::string const& value(std::string const& key, bool& found) const; - std::unordered_map values() const { - return _values; - } - - std::unordered_map> arrayValues() - const { - return _arrayValues; - } - void setArrayValue(std::string const& key, std::string const& value); + virtual std::string const& value(std::string const& key) const = 0; + virtual std::string const& value(std::string const& key, + bool& found) const = 0; + virtual std::unordered_map values() const = 0; + virtual std::unordered_map> + arrayValues() const = 0; + virtual void setArrayValue(std::string const& key, + std::string const& value) = 0; bool velocyPackResponse() const; @@ -193,10 +191,6 @@ class GeneralRequest { ContentType contentType() const { return _contentType; } - protected: - void setValue(char const* key, char const* value); - void setArrayValue(char* key, size_t length, char const* value); - protected: ProtocolVersion _version; char const* _protocol; // http, https or vpp @@ -217,10 +211,6 @@ class GeneralRequest { std::string _requestPath; std::string _prefix; // part of path matched by rest route std::vector _suffix; - std::unordered_map - _headers; // gets set by httpRequest: parseHeaders -> setHeaders - std::unordered_map _values; - std::unordered_map> _arrayValues; ContentType _contentType; // UNSET, VPACK, JSON ContentType _contentTypeResponse; }; diff --git a/lib/Rest/HttpRequest.cpp b/lib/Rest/HttpRequest.cpp index 0832ae306e..628ef996e1 100644 --- a/lib/Rest/HttpRequest.cpp +++ b/lib/Rest/HttpRequest.cpp @@ -46,7 +46,7 @@ HttpRequest::HttpRequest(ConnectionInfo const& connectionInfo, _contentLength(0), _header(nullptr), _allowMethodOverride(allowMethodOverride), - _vpackBuilder(nullptr){ + _vpackBuilder(nullptr) { if (0 < length) { _contentType = ContentType::JSON; _contentTypeResponse = ContentType::JSON; @@ -57,6 +57,24 @@ HttpRequest::HttpRequest(ConnectionInfo const& connectionInfo, } } +HttpRequest::HttpRequest(ContentType contentType, char const* body, + int64_t contentLength + std::map headers) + : GeneralRequest(connectionInfo()), + _contentLength(0), + _header(nullptr), + _allowMethodOverride(false), + _vpackBuilder(nullptr), + _body(body), + _headers(headres) {} +} +FakeRequest::FakeRequest(ContentType contentType, char const* body, + int64_t contentLength) + : GeneralRequest(ConnectionInfo()), + _contentType(contentType), + _body(body), + _contentLength(contentLength) {} + HttpRequest::~HttpRequest() { delete[] _header; } void HttpRequest::parseHeader(size_t length) { @@ -409,6 +427,10 @@ void HttpRequest::parseHeader(size_t length) { } } +void HttpRequest::setArrayValue(char* key, size_t length, char const* value) { + _arrayValues[std::string(key, length)].emplace_back(value); +} + void HttpRequest::setValues(char* buffer, char* end) { char* keyBegin = nullptr; char* key = nullptr; @@ -714,14 +736,64 @@ VPackSlice HttpRequest::payload(VPackOptions const* options) { TRI_ASSERT(_vpackBuilder == nullptr); // check options for nullptr? - if( _contentType == ContentType::JSON) { + if (_contentType == ContentType::JSON) { VPackParser parser(options); parser.parse(body()); _vpackBuilder = parser.steal(); return VPackSlice(_vpackBuilder->slice()); - } else /*VPACK*/{ + } else /*VPACK*/ { VPackValidator validator; validator.validate(body().c_str(), body().length()); return VPackSlice(body().c_str()); } } + +std::string const& HttpRequest::header(std::string const& key) const { + auto it = _headers.find(key); + + if (it == _headers.end()) { + return StaticStrings::Empty; + } + + return it->second; +} + +std::string const& HttpRequest::header(std::string const& key, + bool& found) const { + auto it = _headers.find(key); + + if (it == _headers.end()) { + found = false; + return StaticStrings::Empty; + } + + found = true; + return it->second; +} + +std::string const& HttpRequest::value(std::string const& key) const { + if (!_values.empty()) { + auto it = _values.find(key); + + if (it != _values.end()) { + return it->second; + } + } + + return StaticStrings::Empty; +} + +std::string const& HttpRequest::value(std::string const& key, + bool& found) const { + if (!_values.empty()) { + auto it = _values.find(key); + + if (it != _values.end()) { + found = true; + return it->second; + } + } + + found = false; + return StaticStrings::Empty; +} diff --git a/lib/Rest/HttpRequest.h b/lib/Rest/HttpRequest.h index cea4655d4f..6bfdd6a371 100644 --- a/lib/Rest/HttpRequest.h +++ b/lib/Rest/HttpRequest.h @@ -51,6 +51,20 @@ class HttpRequest : public GeneralRequest { private: HttpRequest(ConnectionInfo const&, char const*, size_t, bool); + // should only be called by createFakeRequest + // as the Request is not fully constructed + // HACK HACK HACK + // this is just to avoid the FakeRequest class + HttpRequest(ContentType contentType, char const* body, int64_t contentLength, + std::unordered_map headers) + : GeneralRequest(connectionInfo()), + _contentLength(0), + _header(nullptr), + _allowMethodOverride(false), + _vpackBuilder(nullptr), + _body(body), + _headers(headers) {} + public: ~HttpRequest(); @@ -65,6 +79,25 @@ class HttpRequest : public GeneralRequest { // the content length int64_t contentLength() const override { return _contentLength; } + // get value from headers map. The key must be lowercase. + std::string const& header(std::string const& key) const override; + std::string const& header(std::string const& key, bool& found) const override; + std::unordered_map const& headers() const override { + return _headers; + } + + std::string const& value(std::string const& key) const override; + std::string const& value(std::string const& key, bool& found) const override; + std::unordered_map values() const override { + return _values; + } + + std::unordered_map> arrayValues() + const override { + return _arrayValues; + } + void setArrayValue(std::string const& key, std::string const& value) override; + std::string const& cookieValue(std::string const& key) const; std::string const& cookieValue(std::string const& key, bool& found) const; std::unordered_map cookieValues() const { @@ -87,6 +120,10 @@ class HttpRequest : public GeneralRequest { /// @brief sets a key-only header void setHeader(char const* key, size_t keyLength); + protected: + void setValue(char const* key, char const* value); + void setArrayValue(char* key, size_t length, char const* value); + private: void parseHeader(size_t length); void setValues(char* buffer, char* end); @@ -103,6 +140,19 @@ class HttpRequest : public GeneralRequest { // (x-http-method, x-method-override or x-http-method-override) is allowed bool _allowMethodOverride; std::shared_ptr _vpackBuilder; + + // previously in base class + std::unordered_map + _headers; // gets set by httpRequest: parseHeaders -> setHeaders + std::unordered_map _values; + std::unordered_map> _arrayValues; + + private: + static HttpRequest createFakeRequest( + ContentType contentType, char const* body, int64_t contentLength, + std::unordered_map&& headers) { + return HttpRequest(contentType, body, contentLength, std::move(headers)); + } }; } diff --git a/lib/Rest/VppRequest.h b/lib/Rest/VppRequest.h index e42139e195..42f731b7be 100644 --- a/lib/Rest/VppRequest.h +++ b/lib/Rest/VppRequest.h @@ -65,6 +65,11 @@ class VppRequest : public GeneralRequest { int64_t contentLength() const override { return _contentLength; } void setPayload(VPackBuffer&& payload) { _payload = payload; } + std::unordered_map const& headers() const override { + throw std::logic_error("this needs to be implmented"); + return std::unordered_map(); + } + private: void parseHeader(); // converts _header(vpack) to // _headers(map)