1
0
Fork 0

struggle with ctor

This commit is contained in:
Jan Christoph Uhde 2016-08-01 11:48:30 +02:00
parent 3e6c7617d0
commit ef12d8dc2c
7 changed files with 155 additions and 86 deletions

View File

@ -1275,9 +1275,15 @@ size_t ClusterComm::performSingleRequest(
GeneralRequest::ContentType type = GeneralRequest::ContentType::JSON; GeneralRequest::ContentType type = GeneralRequest::ContentType::JSON;
// Add correct recognition of content type later. // Add correct recognition of content type later.
basics::StringBuffer& buffer = req.result.result->getBody(); basics::StringBuffer& buffer = req.result.result->getBody();
auto answer = new FakeRequest(type, buffer.c_str(), auto answer = new FakeRequest(type, buffer.c_str(),
static_cast<int64_t>(buffer.length())); static_cast<int64_t>(buffer.length()));
answer->setHeaders(req.result.result->getHeaderFields()); answer->setHeaders(req.result.result->getHeaderFields());
auto answer = new HttpRequest::createFakeRequest(
type, buffer.c_str(), static_cast<int64_t>(buffer.length()),
req.result.result->getHeaderFields());
req.result.answer.reset(static_cast<GeneralRequest*>(answer)); req.result.answer.reset(static_cast<GeneralRequest*>(answer));
req.result.answer_code = static_cast<GeneralResponse::ResponseCode>( req.result.answer_code = static_cast<GeneralResponse::ResponseCode>(
req.result.result->getHttpReturnCode()); req.result.result->getHttpReturnCode());

View File

@ -50,7 +50,11 @@ class FakeRequest : public GeneralRequest {
arangodb::velocypack::Options const*) override final; arangodb::velocypack::Options const*) override final;
void setHeaders(std::unordered_map<std::string, std::string> const& headers) { void setHeaders(std::unordered_map<std::string, std::string> 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: private:

View File

@ -36,13 +36,10 @@ std::string GeneralRequest::translateVersion(ProtocolVersion version) {
switch (version) { switch (version) {
case ProtocolVersion::VPP_1_0: case ProtocolVersion::VPP_1_0:
return "VPP/1.0"; return "VPP/1.0";
case ProtocolVersion::HTTP_1_1: case ProtocolVersion::HTTP_1_1:
return "HTTP/1.1"; return "HTTP/1.1";
case ProtocolVersion::HTTP_1_0: case ProtocolVersion::HTTP_1_0:
return "HTTP/1.0"; return "HTTP/1.0";
case ProtocolVersion::UNKNOWN: case ProtocolVersion::UNKNOWN:
default: { return "HTTP/1.0"; } default: { return "HTTP/1.0"; }
} }
@ -210,61 +207,6 @@ void GeneralRequest::addSuffix(std::string&& part) {
_suffix.emplace_back(StringUtils::urlDecode(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 { bool GeneralRequest::velocyPackResponse() const {
// needs only to be used in http case?! // needs only to be used in http case?!
std::string const& result = header(StaticStrings::Accept); std::string const& result = header(StaticStrings::Accept);

View File

@ -48,6 +48,7 @@ class RequestContext;
class GeneralRequest { class GeneralRequest {
GeneralRequest(GeneralRequest const&) = delete; GeneralRequest(GeneralRequest const&) = delete;
GeneralRequest& operator=(GeneralRequest const&) = delete; GeneralRequest& operator=(GeneralRequest const&) = delete;
GeneralRequest(GenerakRequest&&) = default;
public: public:
// VSTREAM_CRED: This method is used for sending Authentication // VSTREAM_CRED: This method is used for sending Authentication
@ -156,24 +157,21 @@ class GeneralRequest {
void addSuffix(std::string&& part); void addSuffix(std::string&& part);
// get value from headers map. The key must be lowercase. // get value from headers map. The key must be lowercase.
std::string const& header(std::string const& key) const; virtual std::string const& header(std::string const& key) const = 0;
std::string const& header(std::string const& key, bool& found) const; virtual std::string const& header(std::string const& key,
bool& found) const = 0;
// return headers map // return headers map
std::unordered_map<std::string, std::string> const& headers() const { virtual std::unordered_map<std::string, std::string> const& headers()
return _headers; const = 0;
}
std::string const& value(std::string const& key) const; virtual std::string const& value(std::string const& key) const = 0;
std::string const& value(std::string const& key, bool& found) const; virtual std::string const& value(std::string const& key,
std::unordered_map<std::string, std::string> values() const { bool& found) const = 0;
return _values; virtual std::unordered_map<std::string, std::string> values() const = 0;
} virtual std::unordered_map<std::string, std::vector<std::string>>
arrayValues() const = 0;
std::unordered_map<std::string, std::vector<std::string>> arrayValues() virtual void setArrayValue(std::string const& key,
const { std::string const& value) = 0;
return _arrayValues;
}
void setArrayValue(std::string const& key, std::string const& value);
bool velocyPackResponse() const; bool velocyPackResponse() const;
@ -193,10 +191,6 @@ class GeneralRequest {
ContentType contentType() const { return _contentType; } 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: protected:
ProtocolVersion _version; ProtocolVersion _version;
char const* _protocol; // http, https or vpp char const* _protocol; // http, https or vpp
@ -217,10 +211,6 @@ class GeneralRequest {
std::string _requestPath; std::string _requestPath;
std::string _prefix; // part of path matched by rest route std::string _prefix; // part of path matched by rest route
std::vector<std::string> _suffix; std::vector<std::string> _suffix;
std::unordered_map<std::string, std::string>
_headers; // gets set by httpRequest: parseHeaders -> setHeaders
std::unordered_map<std::string, std::string> _values;
std::unordered_map<std::string, std::vector<std::string>> _arrayValues;
ContentType _contentType; // UNSET, VPACK, JSON ContentType _contentType; // UNSET, VPACK, JSON
ContentType _contentTypeResponse; ContentType _contentTypeResponse;
}; };

View File

@ -46,7 +46,7 @@ HttpRequest::HttpRequest(ConnectionInfo const& connectionInfo,
_contentLength(0), _contentLength(0),
_header(nullptr), _header(nullptr),
_allowMethodOverride(allowMethodOverride), _allowMethodOverride(allowMethodOverride),
_vpackBuilder(nullptr){ _vpackBuilder(nullptr) {
if (0 < length) { if (0 < length) {
_contentType = ContentType::JSON; _contentType = ContentType::JSON;
_contentTypeResponse = 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<std::string, std::string> 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; } HttpRequest::~HttpRequest() { delete[] _header; }
void HttpRequest::parseHeader(size_t length) { 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) { void HttpRequest::setValues(char* buffer, char* end) {
char* keyBegin = nullptr; char* keyBegin = nullptr;
char* key = nullptr; char* key = nullptr;
@ -714,14 +736,64 @@ VPackSlice HttpRequest::payload(VPackOptions const* options) {
TRI_ASSERT(_vpackBuilder == nullptr); TRI_ASSERT(_vpackBuilder == nullptr);
// check options for nullptr? // check options for nullptr?
if( _contentType == ContentType::JSON) { if (_contentType == ContentType::JSON) {
VPackParser parser(options); VPackParser parser(options);
parser.parse(body()); parser.parse(body());
_vpackBuilder = parser.steal(); _vpackBuilder = parser.steal();
return VPackSlice(_vpackBuilder->slice()); return VPackSlice(_vpackBuilder->slice());
} else /*VPACK*/{ } else /*VPACK*/ {
VPackValidator validator; VPackValidator validator;
validator.validate(body().c_str(), body().length()); validator.validate(body().c_str(), body().length());
return VPackSlice(body().c_str()); 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;
}

View File

@ -51,6 +51,20 @@ class HttpRequest : public GeneralRequest {
private: private:
HttpRequest(ConnectionInfo const&, char const*, size_t, bool); 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<std::string, std::string> headers)
: GeneralRequest(connectionInfo()),
_contentLength(0),
_header(nullptr),
_allowMethodOverride(false),
_vpackBuilder(nullptr),
_body(body),
_headers(headers) {}
public: public:
~HttpRequest(); ~HttpRequest();
@ -65,6 +79,25 @@ class HttpRequest : public GeneralRequest {
// the content length // the content length
int64_t contentLength() const override { return _contentLength; } 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<std::string, std::string> 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<std::string, std::string> values() const override {
return _values;
}
std::unordered_map<std::string, std::vector<std::string>> 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) const;
std::string const& cookieValue(std::string const& key, bool& found) const; std::string const& cookieValue(std::string const& key, bool& found) const;
std::unordered_map<std::string, std::string> cookieValues() const { std::unordered_map<std::string, std::string> cookieValues() const {
@ -87,6 +120,10 @@ class HttpRequest : public GeneralRequest {
/// @brief sets a key-only header /// @brief sets a key-only header
void setHeader(char const* key, size_t keyLength); 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: private:
void parseHeader(size_t length); void parseHeader(size_t length);
void setValues(char* buffer, char* end); 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 // (x-http-method, x-method-override or x-http-method-override) is allowed
bool _allowMethodOverride; bool _allowMethodOverride;
std::shared_ptr<velocypack::Builder> _vpackBuilder; std::shared_ptr<velocypack::Builder> _vpackBuilder;
// previously in base class
std::unordered_map<std::string, std::string>
_headers; // gets set by httpRequest: parseHeaders -> setHeaders
std::unordered_map<std::string, std::string> _values;
std::unordered_map<std::string, std::vector<std::string>> _arrayValues;
private:
static HttpRequest createFakeRequest(
ContentType contentType, char const* body, int64_t contentLength,
std::unordered_map<std::string, std::string>&& headers) {
return HttpRequest(contentType, body, contentLength, std::move(headers));
}
}; };
} }

View File

@ -65,6 +65,11 @@ class VppRequest : public GeneralRequest {
int64_t contentLength() const override { return _contentLength; } int64_t contentLength() const override { return _contentLength; }
void setPayload(VPackBuffer<uint8_t>&& payload) { _payload = payload; } void setPayload(VPackBuffer<uint8_t>&& payload) { _payload = payload; }
std::unordered_map<std::string, std::string> const& headers() const override {
throw std::logic_error("this needs to be implmented");
return std::unordered_map<std::string, std::string>();
}
private: private:
void parseHeader(); // converts _header(vpack) to void parseHeader(); // converts _header(vpack) to
// _headers(map<string,string>) // _headers(map<string,string>)