mirror of https://gitee.com/bigwinds/arangodb
fix errors in vpp protocol
This commit is contained in:
parent
0e5b455159
commit
8f6ff64d00
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "GeneralServer/GeneralServer.h"
|
||||
#include "GeneralServer/GeneralServerFeature.h"
|
||||
#include "GeneralServer/VppCommTask.h"
|
||||
#include "Scheduler/Scheduler.h"
|
||||
#include "Scheduler/SchedulerFeature.h"
|
||||
#include "Ssl/SslServerFeature.h"
|
||||
|
@ -64,11 +65,11 @@ bool GeneralListenTask::handleConnected(TRI_socket_t socket,
|
|||
switch (_connectionType) {
|
||||
case ConnectionType::VPPS:
|
||||
commTask =
|
||||
new HttpCommTask(_server, socket, std::move(info), _keepAliveTimeout);
|
||||
new VppCommTask(_server, socket, std::move(info), _keepAliveTimeout);
|
||||
break;
|
||||
case ConnectionType::VPP:
|
||||
commTask =
|
||||
new HttpCommTask(_server, socket, std::move(info), _keepAliveTimeout);
|
||||
new VppCommTask(_server, socket, std::move(info), _keepAliveTimeout);
|
||||
break;
|
||||
case ConnectionType::HTTPS:
|
||||
commTask = new HttpsCommTask(_server, socket, std::move(info),
|
||||
|
|
|
@ -118,9 +118,17 @@ std::unique_ptr<basics::StringBuffer> createChunkForNetworkMultiFollow(
|
|||
}
|
||||
}
|
||||
|
||||
VppCommTask::VppCommTask(GeneralServer* server, TRI_socket_t sock,
|
||||
ConnectionInfo&& info, double timeout)
|
||||
: Task("VppCommTask"),
|
||||
GeneralCommTask(server, sock, std::move(info), timeout) {
|
||||
_protocol = "vpp";
|
||||
// connectionStatisticsAgentSetVpp();
|
||||
}
|
||||
|
||||
void VppCommTask::addResponse(VppResponse* response, bool isError) {
|
||||
if (isError) {
|
||||
// FIXME
|
||||
// FIXME (obi)
|
||||
// what do we need to do?
|
||||
// clean read buffer? reset process read cursor
|
||||
}
|
||||
|
@ -130,16 +138,17 @@ void VppCommTask::addResponse(VppResponse* response, bool isError) {
|
|||
|
||||
std::vector<VPackSlice> slices;
|
||||
slices.push_back(response_message._header);
|
||||
|
||||
// if payload != Slice()
|
||||
slices.push_back(response_message._payload);
|
||||
|
||||
uint32_t message_length = 0;
|
||||
|
||||
for (auto const& slice : slices) {
|
||||
message_length = slice.byteSize();
|
||||
message_length += slice.byteSize();
|
||||
}
|
||||
|
||||
// FIXME
|
||||
// FIXME (obi)
|
||||
// If the message is big we will create many small chunks in a loop.
|
||||
// For the first tests we just send single Messages
|
||||
StringBuffer tmp(TRI_UNKNOWN_MEM_ZONE, message_length, false);
|
||||
|
@ -177,7 +186,7 @@ VppCommTask::ChunkHeader VppCommTask::readChunkHeader() {
|
|||
cursor += sizeof(header._messageID);
|
||||
|
||||
// extract total len of message
|
||||
if (header._isFirst && header._chunk == 1) {
|
||||
if (header._isFirst && header._chunk > 1) {
|
||||
std::memcpy(&header._messageLength, cursor, sizeof(header._messageLength));
|
||||
cursor += sizeof(header._messageLength);
|
||||
} else {
|
||||
|
@ -233,13 +242,15 @@ bool VppCommTask::processRead() {
|
|||
// CASE 1: message is in one chunk
|
||||
if (chunkHeader._isFirst && chunkHeader._chunk == 1) {
|
||||
std::size_t payloadOffset = findAndValidateVPacks(vpackBegin, chunkEnd);
|
||||
VPackMessage message;
|
||||
message._id = chunkHeader._messageID;
|
||||
message._buffer.append(vpackBegin, std::distance(vpackBegin, chunkEnd));
|
||||
message._header = VPackSlice(message._buffer.data());
|
||||
if (payloadOffset) {
|
||||
message._payload = VPackSlice(message._buffer.data() + payloadOffset);
|
||||
}
|
||||
VPackValidator val;
|
||||
val.validate(message._header.begin(), message._header.byteSize());
|
||||
|
||||
do_execute = true;
|
||||
}
|
||||
// CASE 2: message is in multiple chunks
|
||||
|
@ -308,6 +319,7 @@ bool VppCommTask::processRead() {
|
|||
|
||||
// for now we can handle only one request at a time
|
||||
// lock _request???? REVIEW (fc)
|
||||
LOG(ERR) << message._header.toJson();
|
||||
_request = new VppRequest(_connectionInfo, std::move(message));
|
||||
GeneralServerFeature::HANDLER_FACTORY->setRequestContext(_request);
|
||||
_request->setClientTaskId(_taskId);
|
||||
|
|
|
@ -56,6 +56,7 @@ class VppCommTask : public GeneralCommTask {
|
|||
|
||||
protected:
|
||||
void completedWriteBuffer() override final;
|
||||
virtual void handleChunk(char const*, size_t) {}
|
||||
|
||||
private:
|
||||
// resets the internal state this method can be called to clean up when the
|
||||
|
|
|
@ -86,7 +86,8 @@ std::string Endpoint::unifiedForm(std::string const& specification) {
|
|||
}
|
||||
|
||||
// read protocol from string
|
||||
if (StringUtils::isPrefix(copy, "http+") || StringUtils::isPrefix(copy, "http@")) {
|
||||
if (StringUtils::isPrefix(copy, "http+") ||
|
||||
StringUtils::isPrefix(copy, "http@")) {
|
||||
protocol = TransportType::HTTP;
|
||||
prefix = "http+";
|
||||
copy = copy.substr(5);
|
||||
|
@ -94,7 +95,7 @@ std::string Endpoint::unifiedForm(std::string const& specification) {
|
|||
|
||||
if (StringUtils::isPrefix(copy, "vpp+")) {
|
||||
protocol = TransportType::VPP;
|
||||
prefix = "vsp+";
|
||||
prefix = "vpp+";
|
||||
copy = copy.substr(4);
|
||||
}
|
||||
|
||||
|
@ -159,10 +160,10 @@ std::string Endpoint::unifiedForm(std::string const& specification) {
|
|||
// hostname only
|
||||
|
||||
if (protocol == TransportType::HTTP) {
|
||||
return prefix + copy + ":" + StringUtils::itoa(EndpointIp::_defaultPortHttp);
|
||||
} else {
|
||||
return prefix + copy + ":" +
|
||||
StringUtils::itoa(EndpointIp::_defaultPortVpp);
|
||||
StringUtils::itoa(EndpointIp::_defaultPortHttp);
|
||||
} else {
|
||||
return prefix + copy + ":" + StringUtils::itoa(EndpointIp::_defaultPortVpp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -323,7 +324,8 @@ std::string const Endpoint::defaultEndpoint(TransportType type) {
|
|||
StringUtils::itoa(EndpointIp::_defaultPortVpp);
|
||||
|
||||
default: {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid transport type");
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||
"invalid transport type");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -379,7 +381,8 @@ bool Endpoint::setSocketFlags(TRI_socket_t s) {
|
|||
return true;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, arangodb::Endpoint::TransportType type) {
|
||||
std::ostream& operator<<(std::ostream& stream,
|
||||
arangodb::Endpoint::TransportType type) {
|
||||
switch (type) {
|
||||
case arangodb::Endpoint::TransportType::HTTP:
|
||||
stream << "http";
|
||||
|
@ -391,7 +394,8 @@ std::ostream& operator<<(std::ostream& stream, arangodb::Endpoint::TransportType
|
|||
return stream;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, arangodb::Endpoint::EndpointType type) {
|
||||
std::ostream& operator<<(std::ostream& stream,
|
||||
arangodb::Endpoint::EndpointType type) {
|
||||
switch (type) {
|
||||
case arangodb::Endpoint::EndpointType::SERVER:
|
||||
stream << "server";
|
||||
|
@ -403,7 +407,8 @@ std::ostream& operator<<(std::ostream& stream, arangodb::Endpoint::EndpointType
|
|||
return stream;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, arangodb::Endpoint::EncryptionType type) {
|
||||
std::ostream& operator<<(std::ostream& stream,
|
||||
arangodb::Endpoint::EncryptionType type) {
|
||||
switch (type) {
|
||||
case arangodb::Endpoint::EncryptionType::NONE:
|
||||
stream << "none";
|
||||
|
@ -415,7 +420,8 @@ std::ostream& operator<<(std::ostream& stream, arangodb::Endpoint::EncryptionTyp
|
|||
return stream;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, arangodb::Endpoint::DomainType type) {
|
||||
std::ostream& operator<<(std::ostream& stream,
|
||||
arangodb::Endpoint::DomainType type) {
|
||||
switch (type) {
|
||||
case arangodb::Endpoint::DomainType::UNIX:
|
||||
stream << "unix";
|
||||
|
|
|
@ -63,11 +63,11 @@ class GeneralRequest {
|
|||
enum class RequestType {
|
||||
DELETE_REQ = 0, // windows redefines DELETE
|
||||
GET,
|
||||
HEAD,
|
||||
OPTIONS,
|
||||
POST,
|
||||
PUT,
|
||||
HEAD,
|
||||
PATCH,
|
||||
OPTIONS,
|
||||
VSTREAM_CRED,
|
||||
VSTREAM_REGISTER,
|
||||
VSTREAM_STATUS,
|
||||
|
|
|
@ -182,6 +182,19 @@ class GeneralResponse {
|
|||
arangodb::velocypack::Options const& = arangodb::
|
||||
velocypack::Options::Defaults) = 0;
|
||||
|
||||
virtual void addPayload(VPackSlice const& slice) {
|
||||
_vpackPayloads.emplace_back(slice.byteSize());
|
||||
std::memcpy(&_vpackPayloads.back(), slice.start(), slice.byteSize());
|
||||
};
|
||||
|
||||
virtual void addPayload(VPackBuffer<uint8_t>&& buffer) {
|
||||
_vpackPayloads.push_back(std::move(buffer));
|
||||
};
|
||||
|
||||
virtual void addHeaderInformation(std::string s /* any or variant */){
|
||||
|
||||
};
|
||||
|
||||
// virtual void setPayload(ContentType contentType,
|
||||
// VPackBuffer<uint8_t>&& sliceBuffer,
|
||||
// bool generateBody = true,
|
||||
|
@ -192,6 +205,8 @@ class GeneralResponse {
|
|||
ResponseCode _responseCode; // http response code
|
||||
std::unordered_map<std::string, std::string>
|
||||
_headers; // headers/metadata map
|
||||
|
||||
std::vector<VPackBuffer<uint8_t>> _vpackPayloads;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ struct VPackMessage {
|
|||
VPackMessage(VPackBuffer<uint8_t>&& buff, VPackSlice head, VPackSlice pay,
|
||||
uint64_t id)
|
||||
: _buffer(std::move(buff)), _header(head), _payload(pay), _id(id) {}
|
||||
VPackMessage(VPackMessage&&) = default; // not necessary just to make sure!
|
||||
VPackMessage(VPackMessage&& other) = default;
|
||||
|
||||
VPackBuffer<uint8_t> _buffer;
|
||||
VPackSlice _header;
|
||||
|
|
|
@ -31,12 +31,17 @@
|
|||
#include <velocypack/Validator.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
#include "Basics/conversions.h"
|
||||
#include "Basics/StaticStrings.h"
|
||||
#include "Basics/StringRef.h"
|
||||
#include "Basics/StringUtils.h"
|
||||
#include "Basics/conversions.h"
|
||||
#include "Basics/tri-strings.h"
|
||||
#include "Meta/conversion.h"
|
||||
#include "Logger/Logger.h"
|
||||
|
||||
// TODO (obi)
|
||||
// - REMOVE TRI_ASSERT
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::basics;
|
||||
|
||||
|
@ -60,16 +65,15 @@ VppRequest::VppRequest(ConnectionInfo const& connectionInfo,
|
|||
: GeneralRequest(connectionInfo),
|
||||
_message(std::move(message)),
|
||||
_headers(nullptr) {
|
||||
if (message._payload != VPackSlice::noneSlice()) {
|
||||
_protocol = "vpp";
|
||||
_contentType = ContentType::VPACK;
|
||||
_contentTypeResponse = ContentType::VPACK;
|
||||
_protocol = "vpp";
|
||||
parseHeaderInformation();
|
||||
}
|
||||
_user = "root";
|
||||
}
|
||||
|
||||
VPackSlice VppRequest::payload(VPackOptions const* options) {
|
||||
// TODO - handle options??
|
||||
// TODO (obi)- handle options??
|
||||
return _message._payload;
|
||||
}
|
||||
|
||||
|
@ -78,8 +82,12 @@ std::unordered_map<std::string, std::string> const& VppRequest::headers()
|
|||
if (!_headers) {
|
||||
using namespace std;
|
||||
_headers = make_unique<unordered_map<string, string>>();
|
||||
LOG(ERR) << _message._header.toJson();
|
||||
TRI_ASSERT(_message._header.isObject());
|
||||
for (auto const& it : VPackObjectIterator(_message._header)) {
|
||||
VPackSlice meta = _message._header.get("meta");
|
||||
// TRI_ASSERT(meta.isObject());
|
||||
for (auto const& it : VPackObjectIterator(meta)) {
|
||||
TRI_ASSERT(it.key.isString());
|
||||
_headers->emplace(it.key.copyString(), it.value.copyString());
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +107,13 @@ std::string const& VppRequest::header(std::string const& key) const {
|
|||
|
||||
void VppRequest::parseHeaderInformation() {
|
||||
using namespace std;
|
||||
TRI_ASSERT(_message._header.isObject());
|
||||
auto& vHeader = _message._header;
|
||||
|
||||
TRI_ASSERT(vHeader.isObject());
|
||||
_databaseName = vHeader.get("database").copyString();
|
||||
_requestPath = vHeader.get("request").copyString();
|
||||
_type = meta::toEnum<RequestType>(vHeader.get("requestType").getInt());
|
||||
|
||||
VPackSlice params = _message._header.get("parameter");
|
||||
TRI_ASSERT(params.isObject());
|
||||
for (auto const& it : VPackObjectIterator(params)) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
|
@ -61,6 +61,12 @@ void VppResponse::setPayload(ContentType contentType,
|
|||
arangodb::velocypack::Slice const& slice,
|
||||
bool generateBody, VPackOptions const& options) {
|
||||
if (generateBody) {
|
||||
// addPayload(slice);
|
||||
if (_payload.empty()) {
|
||||
throw std::logic_error("payload should be empty!!");
|
||||
}
|
||||
_payload.append(slice.startAs<char>(),
|
||||
std::distance(slice.begin(), slice.end()));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue