mirror of https://gitee.com/bigwinds/arangodb
Bug fix/foxx vst (#10349)
This commit is contained in:
parent
972e0b2ce0
commit
b6a400aec1
|
@ -47,13 +47,6 @@ void RestAnalyzerHandler::createAnalyzer( // create
|
|||
) {
|
||||
TRI_ASSERT(_request); // ensured by execute()
|
||||
|
||||
if (_request->payload().isEmptyObject()) {
|
||||
generateError(
|
||||
arangodb::rest::ResponseCode::BAD, TRI_ERROR_HTTP_CORRUPTED_JSON
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
auto body = parseVPackBody(success);
|
||||
|
||||
|
@ -61,6 +54,13 @@ void RestAnalyzerHandler::createAnalyzer( // create
|
|||
return; // parseVPackBody(...) calls generateError(...)
|
||||
}
|
||||
|
||||
if (body.isEmptyObject()) {
|
||||
generateError(
|
||||
arangodb::rest::ResponseCode::BAD, TRI_ERROR_HTTP_CORRUPTED_JSON
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!body.isObject()) {
|
||||
generateError(arangodb::Result(
|
||||
TRI_ERROR_BAD_PARAMETER,
|
||||
|
|
|
@ -569,11 +569,6 @@ RestStatus RestCursorHandler::generateCursorResult(rest::ResponseCode code,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
RestStatus RestCursorHandler::createQueryCursor() {
|
||||
if (_request->payload().isEmptyObject()) {
|
||||
generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_CORRUPTED_JSON);
|
||||
return RestStatus::DONE;
|
||||
}
|
||||
|
||||
std::vector<std::string> const& suffixes = _request->suffixes();
|
||||
|
||||
if (!suffixes.empty()) {
|
||||
|
@ -590,6 +585,11 @@ RestStatus RestCursorHandler::createQueryCursor() {
|
|||
return RestStatus::DONE;
|
||||
}
|
||||
|
||||
if (body.isEmptyObject()) {
|
||||
generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_CORRUPTED_JSON);
|
||||
return RestStatus::DONE;
|
||||
}
|
||||
|
||||
// tell RestCursorHandler::finalizeExecute that the request
|
||||
// could be parsed successfully and that it may look at it
|
||||
_isValidForFinalize = true;
|
||||
|
|
|
@ -317,8 +317,6 @@ bool RestImportHandler::createFromJson(std::string const& type) {
|
|||
|
||||
// auto detect import type by peeking at first non-whitespace character
|
||||
|
||||
// json required here
|
||||
TRI_ASSERT(_request->contentType() == ContentType::JSON);
|
||||
VPackStringRef body = _request->rawPayload();
|
||||
|
||||
char const* ptr = body.data();
|
||||
|
@ -373,9 +371,6 @@ bool RestImportHandler::createFromJson(std::string const& type) {
|
|||
VPackBuilder tmpBuilder;
|
||||
|
||||
if (linewise) {
|
||||
// json required here
|
||||
TRI_ASSERT(_request->contentType() == ContentType::JSON);
|
||||
|
||||
// each line is a separate JSON document
|
||||
VPackStringRef body = _request->rawPayload();
|
||||
char const* ptr = body.data();
|
||||
|
|
|
@ -140,12 +140,6 @@ RestStatus RestViewHandler::execute() {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RestViewHandler::createView() {
|
||||
if (_request->payload().isEmptyObject()) {
|
||||
generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_CORRUPTED_JSON);
|
||||
events::CreateView(_vocbase.name(), "", TRI_ERROR_HTTP_CORRUPTED_JSON);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> const& suffixes = _request->suffixes();
|
||||
|
||||
if (!suffixes.empty()) {
|
||||
|
@ -170,6 +164,13 @@ void RestViewHandler::createView() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (body.isEmptyObject()) {
|
||||
generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_CORRUPTED_JSON);
|
||||
events::CreateView(_vocbase.name(), "", TRI_ERROR_HTTP_CORRUPTED_JSON);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
auto nameSlice = body.get(StaticStrings::DataSourceName);
|
||||
auto typeSlice = body.get(StaticStrings::DataSourceType);
|
||||
|
||||
|
|
|
@ -438,6 +438,30 @@ v8::Handle<v8::Object> TRI_RequestCppToV8(v8::Isolate* isolate,
|
|||
TRI_GET_GLOBAL_STRING(RequestBodyKey);
|
||||
|
||||
auto setRequestBodyJsonOrVPack = [&]() {
|
||||
if (rest::ContentType::UNSET == request->contentType()) {
|
||||
bool digesteable = false;
|
||||
try {
|
||||
VPackOptions optionsWithUniquenessCheck = VPackOptions::Defaults;
|
||||
optionsWithUniquenessCheck.checkAttributeUniqueness = true;
|
||||
auto parsed = request->payload(&optionsWithUniquenessCheck);
|
||||
if (parsed.isObject() || parsed.isArray()) {
|
||||
digesteable = true;
|
||||
}
|
||||
} catch ( ... ) {}
|
||||
// ok, no json/vpack after all ;-)
|
||||
auto raw = request->rawPayload();
|
||||
headers[StaticStrings::ContentLength] =
|
||||
StringUtils::itoa(raw.size());
|
||||
V8Buffer* buffer = V8Buffer::New(isolate, raw.data(), raw.size());
|
||||
auto bufObj = v8::Local<v8::Object>::New(isolate, buffer->_handle);
|
||||
TRI_GET_GLOBAL_STRING(RawRequestBodyKey);
|
||||
req->Set(RawRequestBodyKey, bufObj);
|
||||
req->Set(RequestBodyKey, TRI_V8_PAIR_STRING(isolate, raw.data(), raw.size()));
|
||||
if (!digesteable) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (rest::ContentType::JSON == request->contentType()) {
|
||||
VPackStringRef body = request->rawPayload();
|
||||
req->Set(RequestBodyKey, TRI_V8_PAIR_STRING(isolate, body.data(), body.size()));
|
||||
|
@ -456,8 +480,6 @@ v8::Handle<v8::Object> TRI_RequestCppToV8(v8::Isolate* isolate,
|
|||
req->Set(RequestBodyKey, TRI_V8_STD_STRING(isolate, jsonString));
|
||||
headers[StaticStrings::ContentLength] = StringUtils::itoa(jsonString.size());
|
||||
headers[StaticStrings::ContentTypeHeader] = StaticStrings::MimeTypeJson;
|
||||
} else {
|
||||
throw std::logic_error("unhandled request type");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -614,13 +636,14 @@ static void ResponseV8ToCpp(v8::Isolate* isolate, TRI_v8_global_t const* v8g,
|
|||
response->setResponseCode(code);
|
||||
|
||||
// string should not be used
|
||||
std::string contentType = "application/json";
|
||||
std::string contentType = StaticStrings::MimeTypeJsonNoEncoding;
|
||||
bool autoContent = true;
|
||||
TRI_GET_GLOBAL_STRING(ContentTypeKey);
|
||||
if (TRI_HasProperty(context, isolate, res, ContentTypeKey)) {
|
||||
contentType = TRI_ObjectToString(isolate, res->Get(ContentTypeKey));
|
||||
|
||||
if (contentType.find("application/json") == std::string::npos) {
|
||||
if ((contentType.find(StaticStrings::MimeTypeJsonNoEncoding) == std::string::npos) &&
|
||||
(contentType.find(StaticStrings::MimeTypeVPack) == std::string::npos)) {
|
||||
autoContent = false;
|
||||
}
|
||||
switch (response->transportType()) {
|
||||
|
@ -633,7 +656,11 @@ static void ResponseV8ToCpp(v8::Isolate* isolate, TRI_v8_global_t const* v8g,
|
|||
break;
|
||||
|
||||
case Endpoint::TransportType::VST:
|
||||
response->setHeaderNC(arangodb::StaticStrings::ContentTypeHeader, contentType);
|
||||
if (!autoContent) {
|
||||
response->setContentType(contentType);
|
||||
} else {
|
||||
response->setHeaderNC(arangodb::StaticStrings::ContentTypeHeader, contentType);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -751,6 +778,7 @@ static void ResponseV8ToCpp(v8::Isolate* isolate, TRI_v8_global_t const* v8g,
|
|||
out = TRI_ObjectToString(isolate, res->Get(BodyKey)); // should get moved
|
||||
} else {
|
||||
TRI_V8ToVPack(isolate, builder, v8Body, false);
|
||||
response->setContentType(rest::ContentType::VPACK);
|
||||
}
|
||||
} else if (V8Buffer::hasInstance(isolate,
|
||||
v8Body)) { // body form buffer - could
|
||||
|
@ -771,6 +799,7 @@ static void ResponseV8ToCpp(v8::Isolate* isolate, TRI_v8_global_t const* v8g,
|
|||
VPackParser parser(builder); // add json as vpack to the builder
|
||||
parser.parse(out, false);
|
||||
gotJson = true;
|
||||
response->setContentType(rest::ContentType::VPACK);
|
||||
} catch (...) { // do nothing
|
||||
// json could not be converted
|
||||
// there was no json - change content type?
|
||||
|
@ -781,11 +810,12 @@ static void ResponseV8ToCpp(v8::Isolate* isolate, TRI_v8_global_t const* v8g,
|
|||
}
|
||||
|
||||
if (!gotJson) {
|
||||
builder.add(VPackValue(out)); // add output to the builder - when not added via parser
|
||||
// don't go via the builder - when not added via parser
|
||||
buffer.reset();
|
||||
buffer.append(out);
|
||||
}
|
||||
}
|
||||
|
||||
response->setContentType(rest::ContentType::VPACK);
|
||||
response->setPayload(std::move(buffer), true);
|
||||
break;
|
||||
}
|
||||
|
@ -1162,14 +1192,8 @@ static void JS_RawRequestBody(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
|
||||
case Endpoint::TransportType::VST: {
|
||||
if (request != nullptr) {
|
||||
auto slice = request->payload();
|
||||
V8Buffer* buffer = nullptr;
|
||||
if (slice.isNone()) {
|
||||
buffer = V8Buffer::New(isolate, "", 0);
|
||||
} else {
|
||||
std::string bodyStr = slice.toJson();
|
||||
buffer = V8Buffer::New(isolate, bodyStr.c_str(), bodyStr.size());
|
||||
}
|
||||
auto raw = request->rawPayload();
|
||||
V8Buffer* buffer = V8Buffer::New(isolate, raw.data(), raw.size());
|
||||
TRI_V8_RETURN(buffer->_handle);
|
||||
}
|
||||
} break;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "V8ClientConnection.h"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <fuerte/connection.h>
|
||||
#include <fuerte/jwt.h>
|
||||
#include <fuerte/requests.h>
|
||||
|
@ -1524,6 +1525,34 @@ again:
|
|||
req->header.database = _databaseName;
|
||||
req->header.parseArangoPath(location.toString());
|
||||
for (auto& pair : headerFields) {
|
||||
if (boost::iequals(StaticStrings::ContentTypeHeader, pair.first)) {
|
||||
if (pair.second == StaticStrings::MimeTypeVPack) {
|
||||
req->header.contentType(fuerte::ContentType::VPack);
|
||||
} else if ((pair.second.length() >= StaticStrings::MimeTypeJsonNoEncoding.length()) &&
|
||||
(memcmp(pair.second.c_str(),
|
||||
StaticStrings::MimeTypeJsonNoEncoding.c_str(),
|
||||
StaticStrings::MimeTypeJsonNoEncoding.length()) == 0)) {
|
||||
// ignore encoding etc.
|
||||
req->header.contentType(fuerte::ContentType::Json);
|
||||
} else {
|
||||
req->header.contentType(fuerte::ContentType::Custom);
|
||||
}
|
||||
|
||||
} else if (boost::iequals(StaticStrings::Accept, pair.first)) {
|
||||
if (pair.second == StaticStrings::MimeTypeVPack) {
|
||||
req->header.acceptType(fuerte::ContentType::VPack);
|
||||
} else if ((pair.second.length() >= StaticStrings::MimeTypeJsonNoEncoding.length()) &&
|
||||
(memcmp(pair.second.c_str(),
|
||||
StaticStrings::MimeTypeJsonNoEncoding.c_str(),
|
||||
StaticStrings::MimeTypeJsonNoEncoding.length()) == 0)) {
|
||||
// ignore encoding etc.
|
||||
req->header.acceptType(fuerte::ContentType::Json);
|
||||
} else {
|
||||
req->header.acceptType(fuerte::ContentType::Custom);
|
||||
}
|
||||
|
||||
req->header.acceptType(fuerte::ContentType::Custom);
|
||||
}
|
||||
req->header.addMeta(pair.first, pair.second);
|
||||
}
|
||||
if (isFile) {
|
||||
|
@ -1623,6 +1652,11 @@ again:
|
|||
req->header.database = _databaseName;
|
||||
req->header.parseArangoPath(location.toString());
|
||||
for (auto& pair : headerFields) {
|
||||
if (boost::iequals(StaticStrings::ContentTypeHeader, pair.first)) {
|
||||
req->header.contentType(fuerte::ContentType::Custom);
|
||||
} else if (boost::iequals(StaticStrings::Accept, pair.first)) {
|
||||
req->header.acceptType(fuerte::ContentType::Custom);
|
||||
}
|
||||
req->header.addMeta(pair.first, pair.second);
|
||||
}
|
||||
if (body->IsString() || body->IsStringObject()) { // assume JSON
|
||||
|
@ -1815,8 +1849,15 @@ v8::Local<v8::Value> V8ClientConnection::handleResult(v8::Isolate* isolate,
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
// return body as string
|
||||
return TRI_V8_PAIR_STRING(isolate, str, sb.size());
|
||||
if (res->isContentTypeHtml() || res->isContentTypeText()) {
|
||||
// return body as string
|
||||
return TRI_V8_PAIR_STRING(isolate, str, sb.size());
|
||||
}
|
||||
|
||||
V8Buffer* buffer;
|
||||
buffer = V8Buffer::New(isolate, reinterpret_cast<char const*>(sb.data()), sb.size());
|
||||
auto bufObj = v8::Local<v8::Object>::New(isolate, buffer->_handle);
|
||||
return bufObj;
|
||||
}
|
||||
|
||||
// no body
|
||||
|
|
|
@ -1805,14 +1805,6 @@ function launchFinalize(options, instanceInfo, startTime) {
|
|||
device = options.sniffDevice;
|
||||
}
|
||||
|
||||
let pcapFile = fs.join(instanceInfo.rootDir, 'out.pcap');
|
||||
let args = ['-ni', device, '-s0', '-w', pcapFile];
|
||||
for (let port = 0; port < ports.length; port ++) {
|
||||
if (port > 0) {
|
||||
args.push('or');
|
||||
}
|
||||
args.push(ports[port]);
|
||||
}
|
||||
let prog = 'tcpdump';
|
||||
if (platform.substr(0, 3) === 'win') {
|
||||
prog = 'c:/Program Files/Wireshark/tshark.exe';
|
||||
|
@ -1820,6 +1812,21 @@ function launchFinalize(options, instanceInfo, startTime) {
|
|||
if (options.sniffProgram !== undefined) {
|
||||
prog = options.sniffProgram;
|
||||
}
|
||||
|
||||
let pcapFile = fs.join(instanceInfo.rootDir, 'out.pcap');
|
||||
let args;
|
||||
if (prog === 'ngrep') {
|
||||
args = ['-l', '-Wbyline', '-d', device];
|
||||
} else {
|
||||
args = ['-ni', device, '-s0', '-w', pcapFile];
|
||||
}
|
||||
for (let port = 0; port < ports.length; port ++) {
|
||||
if (port > 0) {
|
||||
args.push('or');
|
||||
}
|
||||
args.push(ports[port]);
|
||||
}
|
||||
|
||||
if (options.sniff === 'sudo') {
|
||||
args.unshift(prog);
|
||||
prog = 'sudo';
|
||||
|
|
|
@ -31,7 +31,6 @@ const typeIs = require('type-is').is;
|
|||
const accepts = require('accepts');
|
||||
const parseRange = require('range-parser');
|
||||
const querystring = require('querystring');
|
||||
const getRawBodyBuffer = require('internal').rawRequestBody;
|
||||
const getTrustedProxies = require('internal').trustedProxies;
|
||||
const crypto = require('@arangodb/crypto');
|
||||
const Netmask = require('netmask').Netmask;
|
||||
|
@ -74,7 +73,12 @@ module.exports =
|
|||
this.path = this._url.pathname;
|
||||
this.pathParams = {};
|
||||
this.queryParams = querystring.parse(this._url.query);
|
||||
this.body = getRawBodyBuffer(req);
|
||||
if (req.hasOwnProperty('rawRequestBody')) {
|
||||
this.body = req.rawRequestBody;
|
||||
}
|
||||
else {
|
||||
this.body = req.requestBody;
|
||||
}
|
||||
this.rawBody = this.body;
|
||||
|
||||
this.trustProxy = (
|
||||
|
|
|
@ -217,6 +217,8 @@ std::string const StaticStrings::MimeTypeDump(
|
|||
std::string const StaticStrings::MimeTypeHtml("text/html; charset=utf-8");
|
||||
std::string const StaticStrings::MimeTypeJson(
|
||||
"application/json; charset=utf-8");
|
||||
std::string const StaticStrings::MimeTypeJsonNoEncoding(
|
||||
"application/json");
|
||||
std::string const StaticStrings::MimeTypeText("text/plain; charset=utf-8");
|
||||
std::string const StaticStrings::MimeTypeVPack("application/x-velocypack");
|
||||
std::string const StaticStrings::MultiPartContentType("multipart/form-data");
|
||||
|
|
|
@ -199,6 +199,7 @@ class StaticStrings {
|
|||
static std::string const MimeTypeDump;
|
||||
static std::string const MimeTypeHtml;
|
||||
static std::string const MimeTypeJson;
|
||||
static std::string const MimeTypeJsonNoEncoding;
|
||||
static std::string const MimeTypeText;
|
||||
static std::string const MimeTypeVPack;
|
||||
static std::string const MultiPartContentType;
|
||||
|
|
|
@ -42,7 +42,7 @@ using namespace arangodb::basics;
|
|||
|
||||
static size_t const MinReserveValue = 32;
|
||||
|
||||
void VelocyPackDumper::handleUnsupportedType(VPackSlice const* /*slice*/) {
|
||||
void VelocyPackDumper::handleUnsupportedType(VPackSlice const* slice) {
|
||||
TRI_string_buffer_t* buffer = _buffer->stringBuffer();
|
||||
|
||||
if (options->unsupportedTypeBehavior == VPackOptions::NullifyUnsupportedType) {
|
||||
|
@ -52,7 +52,10 @@ void VelocyPackDumper::handleUnsupportedType(VPackSlice const* /*slice*/) {
|
|||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
TRI_ASSERT(strlen("\"(non-representable type)\"") + 1 < MinReserveValue);
|
||||
#endif
|
||||
TRI_AppendStringUnsafeStringBuffer(buffer, "\"(non-representable type)\"");
|
||||
TRI_AppendStringUnsafeStringBuffer(buffer, "\"(non-representable type ");
|
||||
TRI_AppendStringUnsafeStringBuffer(buffer, slice->typeName());
|
||||
TRI_AppendStringUnsafeStringBuffer(buffer, ")\"");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ HttpRequest::HttpRequest(ConnectionInfo const& connectionInfo, char const* heade
|
|||
_vpackBuilder(nullptr),
|
||||
_version(ProtocolVersion::UNKNOWN),
|
||||
_allowMethodOverride(allowMethodOverride) {
|
||||
_contentType = ContentType::JSON;
|
||||
_contentType = ContentType::UNSET;
|
||||
_contentTypeResponse = ContentType::JSON;
|
||||
if (0 < length) {
|
||||
auto buff = std::make_unique<char[]>(length + 1);
|
||||
|
@ -545,9 +545,19 @@ void HttpRequest::setHeaderV2(std::string key, std::string value) {
|
|||
|
||||
if (key == StaticStrings::Accept && value == StaticStrings::MimeTypeVPack) {
|
||||
_contentTypeResponse = ContentType::VPACK;
|
||||
} else if (key == StaticStrings::ContentTypeHeader && value == StaticStrings::MimeTypeVPack) {
|
||||
_contentType = ContentType::VPACK; // don't insert this header!!
|
||||
return;
|
||||
} else if ((_contentType == ContentType::UNSET) && (key == StaticStrings::ContentTypeHeader)) {
|
||||
if (value == StaticStrings::MimeTypeVPack) {
|
||||
_contentType = ContentType::VPACK; // don't insert this header!!
|
||||
return;
|
||||
}
|
||||
else if ((value.length() >= StaticStrings::MimeTypeJsonNoEncoding.length()) &&
|
||||
(memcmp(value.c_str(),
|
||||
StaticStrings::MimeTypeJsonNoEncoding.c_str(),
|
||||
StaticStrings::MimeTypeJsonNoEncoding.length()) == 0)) {
|
||||
// ignore encoding etc.
|
||||
_contentType = ContentType::JSON;
|
||||
return;
|
||||
}
|
||||
} else if (key == StaticStrings::AcceptEncoding) {
|
||||
// This can be much more elaborated as the can specify weights on encodings
|
||||
// However, for now just toggle on deflate if deflate is requested
|
||||
|
@ -720,13 +730,22 @@ void HttpRequest::setHeader(char const* key, size_t keyLength,
|
|||
// This can be much more elaborated as the can specify weights on encodings
|
||||
// However, for now just toggle on deflate if deflate is requested
|
||||
_acceptEncoding = EncodingType::DEFLATE;
|
||||
} else if (keyLength == StaticStrings::ContentTypeHeader.size() &&
|
||||
valueLength == StaticStrings::MimeTypeVPack.size() &&
|
||||
memcmp(key, StaticStrings::ContentTypeHeader.c_str(), keyLength) == 0 &&
|
||||
memcmp(value, StaticStrings::MimeTypeVPack.c_str(), valueLength) == 0) {
|
||||
_contentType = ContentType::VPACK;
|
||||
// don't insert this header!!
|
||||
return;
|
||||
} else if ((_contentType == ContentType::UNSET) &&
|
||||
(keyLength == StaticStrings::ContentTypeHeader.size()) &&
|
||||
(memcmp(key, StaticStrings::ContentTypeHeader.c_str(), keyLength) == 0)) {
|
||||
if (valueLength == StaticStrings::MimeTypeVPack.size() &&
|
||||
memcmp(value, StaticStrings::MimeTypeVPack.c_str(), valueLength) == 0) {
|
||||
_contentType = ContentType::VPACK;
|
||||
// don't insert this header!!
|
||||
return;
|
||||
}
|
||||
if (valueLength >= StaticStrings::MimeTypeJsonNoEncoding.size() &&
|
||||
memcmp(value, StaticStrings::MimeTypeJsonNoEncoding.c_str(),
|
||||
StaticStrings::MimeTypeJsonNoEncoding.length()) == 0) {
|
||||
_contentType = ContentType::JSON;
|
||||
// don't insert this header!!
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (keyLength == 6 && memcmp(key, "cookie", keyLength) == 0) { // 6 = strlen("cookie")
|
||||
|
@ -890,8 +909,7 @@ VPackStringRef HttpRequest::rawPayload() const {
|
|||
|
||||
VPackSlice HttpRequest::payload(VPackOptions const* options) {
|
||||
TRI_ASSERT(options != nullptr);
|
||||
|
||||
if (_contentType == ContentType::JSON) {
|
||||
if ((_contentType == ContentType::UNSET) || (_contentType == ContentType::JSON)) {
|
||||
if (!_body.empty()) {
|
||||
if (!_vpackBuilder) {
|
||||
VPackParser parser(options);
|
||||
|
|
|
@ -61,7 +61,7 @@ VstRequest::VstRequest(ConnectionInfo const& connectionInfo,
|
|||
_payloadOffset(payloadOffset),
|
||||
_messageId(messageId),
|
||||
_validatedPayload(false) {
|
||||
_contentType = ContentType::VPACK;
|
||||
_contentType = ContentType::UNSET;
|
||||
_contentTypeResponse = ContentType::VPACK;
|
||||
parseHeaderInformation();
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ VPackSlice VstRequest::payload(VPackOptions const* options) {
|
|||
if (_vpackBuilder) {
|
||||
return _vpackBuilder->slice();
|
||||
}
|
||||
} else if (_contentType == ContentType::VPACK) {
|
||||
} else if ((_contentType == ContentType::UNSET) || (_contentType == ContentType::VPACK)) {
|
||||
if (_buffer.size() > _payloadOffset) {
|
||||
uint8_t const* ptr = _buffer.data() + _payloadOffset;
|
||||
if (!_validatedPayload) {
|
||||
|
@ -113,15 +113,25 @@ void VstRequest::setHeader(VPackSlice keySlice, VPackSlice valSlice) {
|
|||
std::string value = valSlice.copyString();
|
||||
std::string key = StringUtils::tolower(keySlice.copyString());
|
||||
std::string val = StringUtils::tolower(value);
|
||||
static const char* mime = "application/json";
|
||||
if (key == StaticStrings::Accept && val.length() >= 16 &&
|
||||
memcmp(val.data(), mime, 16) == 0) {
|
||||
if (key == StaticStrings::Accept &&
|
||||
val.length() == StaticStrings::MimeTypeJsonNoEncoding.length() &&
|
||||
(val == StaticStrings::MimeTypeJsonNoEncoding)) {
|
||||
_contentTypeResponse = ContentType::JSON;
|
||||
return; // don't insert this header!!
|
||||
} else if (key == StaticStrings::ContentTypeHeader && val.length() >= 16 &&
|
||||
memcmp(val.data(), mime, 16) == 0) {
|
||||
_contentType = ContentType::JSON;
|
||||
return; // don't insert this header!!
|
||||
} else if ((_contentType == ContentType::UNSET) &&
|
||||
(key == StaticStrings::ContentTypeHeader)) {
|
||||
if ((val.length() == StaticStrings::MimeTypeVPack.length()) &&
|
||||
(val == StaticStrings::MimeTypeVPack)) {
|
||||
_contentType = ContentType::VPACK;
|
||||
return; // don't insert this header!!
|
||||
}
|
||||
if (val.length() >= StaticStrings::MimeTypeJsonNoEncoding.length() &&
|
||||
memcmp(value.c_str(), StaticStrings::MimeTypeJsonNoEncoding.c_str(),
|
||||
StaticStrings::MimeTypeJsonNoEncoding.length()) == 0) {
|
||||
_contentType = ContentType::JSON;
|
||||
// don't insert this header!!
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// must lower-case the header key
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "Basics/Exceptions.h"
|
||||
#include "Basics/StringBuffer.h"
|
||||
#include "Basics/StringUtils.h"
|
||||
#include "Basics/VelocyPackDumper.h"
|
||||
#include "Basics/VelocyPackHelper.h"
|
||||
#include "Basics/VPackStringBufferAdapter.h"
|
||||
#include "Basics/tri-strings.h"
|
||||
|
@ -56,6 +57,12 @@ void VstResponse::reset(ResponseCode code) {
|
|||
void VstResponse::addPayload(VPackSlice const& slice,
|
||||
VPackOptions const* options,
|
||||
bool resolveExternals) {
|
||||
if (_contentType == rest::ContentType::VPACK &&
|
||||
_contentTypeRequested == rest::ContentType::JSON) {
|
||||
// content type was set by a handler to VPACK but the client requested JSON
|
||||
// as we have a slice at hand we are able to reply with JSON easily
|
||||
_contentType = rest::ContentType::JSON;
|
||||
}
|
||||
if (!options) {
|
||||
options = &VPackOptions::Options::Defaults;
|
||||
}
|
||||
|
@ -69,21 +76,50 @@ void VstResponse::addPayload(VPackSlice const& slice,
|
|||
VPackBuilder builder(tmpBuffer, options);
|
||||
VelocyPackHelper::sanitizeNonClientTypes(slice, VPackSlice::noneSlice(),
|
||||
builder, options, true, true, true);
|
||||
if (_payload.empty()) {
|
||||
_payload = std::move(tmpBuffer);
|
||||
if (_contentType == rest::ContentType::VPACK) {
|
||||
if (_payload.empty()) {
|
||||
_payload = std::move(tmpBuffer);
|
||||
} else {
|
||||
_payload.append(tmpBuffer.data(), tmpBuffer.size());
|
||||
}
|
||||
} else if (_contentType == rest::ContentType::JSON) {
|
||||
VPackSlice finalSlice(tmpBuffer.data());
|
||||
StringBuffer plainBuffer;
|
||||
arangodb::basics::VelocyPackDumper dumper(&plainBuffer, options);
|
||||
dumper.dumpValue(finalSlice);
|
||||
_payload.reset();
|
||||
_payload.append(plainBuffer.data(), plainBuffer.length());
|
||||
} else {
|
||||
_payload.append(tmpBuffer.data(), tmpBuffer.size());
|
||||
_payload.reset();
|
||||
_payload.append(slice.start(), slice.byteSize());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// just copy
|
||||
_payload.append(slice.startAs<char>(), slice.byteSize());
|
||||
if (_contentType == rest::ContentType::VPACK) {
|
||||
// just copy
|
||||
_payload.append(slice.startAs<char>(), slice.byteSize());
|
||||
} else if (_contentType == rest::ContentType::JSON) {
|
||||
StringBuffer plainBuffer;
|
||||
arangodb::basics::VelocyPackDumper dumper(&plainBuffer, options);
|
||||
dumper.dumpValue(slice);
|
||||
_payload.reset();
|
||||
_payload.append(plainBuffer.data(), plainBuffer.length());
|
||||
} else {
|
||||
_payload.reset();
|
||||
_payload.append(slice.start(), slice.byteSize());
|
||||
}
|
||||
}
|
||||
|
||||
void VstResponse::addPayload(VPackBuffer<uint8_t>&& buffer,
|
||||
velocypack::Options const* options, bool resolveExternals) {
|
||||
if (_contentType == rest::ContentType::VPACK &&
|
||||
_contentTypeRequested == rest::ContentType::JSON) {
|
||||
// content type was set by a handler to VPACK but the client wants JSON
|
||||
// as we have a slice at had we are able to reply with JSON
|
||||
_contentType = rest::ContentType::JSON;
|
||||
}
|
||||
if (!options) {
|
||||
options = &VPackOptions::Options::Defaults;
|
||||
}
|
||||
|
@ -98,18 +134,42 @@ void VstResponse::addPayload(VPackBuffer<uint8_t>&& buffer,
|
|||
VPackBuilder builder(tmpBuffer, options);
|
||||
VelocyPackHelper::sanitizeNonClientTypes(input, VPackSlice::noneSlice(),
|
||||
builder, options, true, true, true);
|
||||
if (_payload.empty()) {
|
||||
_payload = std::move(tmpBuffer);
|
||||
if (_contentType == rest::ContentType::VPACK) {
|
||||
if (_payload.empty()) {
|
||||
_payload = std::move(tmpBuffer);
|
||||
} else {
|
||||
_payload.append(tmpBuffer.data(), tmpBuffer.size());
|
||||
}
|
||||
} else if (_contentType == rest::ContentType::JSON) {
|
||||
VPackSlice finalSlice(tmpBuffer.data());
|
||||
StringBuffer plainBuffer;
|
||||
arangodb::basics::VelocyPackDumper dumper(&plainBuffer, options);
|
||||
dumper.dumpValue(finalSlice);
|
||||
_payload.reset();
|
||||
_payload.append(plainBuffer.data(), plainBuffer.length());
|
||||
} else {
|
||||
_payload.append(tmpBuffer.data(), tmpBuffer.size());
|
||||
_payload.reset();
|
||||
_payload = buffer;
|
||||
}
|
||||
return; // done
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_payload.empty()) {
|
||||
_payload = std::move(buffer);
|
||||
if (_contentType == rest::ContentType::VPACK) {
|
||||
if (_payload.empty()) {
|
||||
_payload = std::move(buffer);
|
||||
} else {
|
||||
_payload.append(buffer.data(), buffer.size());
|
||||
}
|
||||
} else if (_contentType == rest::ContentType::JSON) {
|
||||
VPackSlice finalSlice(buffer.data());
|
||||
StringBuffer plainBuffer;
|
||||
arangodb::basics::VelocyPackDumper dumper(&plainBuffer, options);
|
||||
dumper.dumpValue(finalSlice);
|
||||
_payload.reset();
|
||||
_payload.append(plainBuffer.data(), plainBuffer.length());
|
||||
} else {
|
||||
_payload.append(buffer.data(), buffer.size());
|
||||
_payload.reset();
|
||||
_payload = buffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ TRI_v8_global_t::TRI_v8_global_t(v8::Isolate* isolate, size_t id)
|
|||
ProtocolKey(),
|
||||
RawSuffixKey(),
|
||||
RequestBodyKey(),
|
||||
RawRequestBodyKey(),
|
||||
RequestTypeKey(),
|
||||
ResponseCodeKey(),
|
||||
ReturnNewKey(),
|
||||
|
@ -191,6 +192,7 @@ TRI_v8_global_t::TRI_v8_global_t(v8::Isolate* isolate, size_t id)
|
|||
ProtocolKey.Reset(isolate, TRI_V8_ASCII_STRING(isolate, "protocol"));
|
||||
RawSuffixKey.Reset(isolate, TRI_V8_ASCII_STRING(isolate, "rawSuffix"));
|
||||
RequestBodyKey.Reset(isolate, TRI_V8_ASCII_STRING(isolate, "requestBody"));
|
||||
RawRequestBodyKey.Reset(isolate, TRI_V8_ASCII_STRING(isolate, "rawRequestBody"));
|
||||
RequestTypeKey.Reset(isolate, TRI_V8_ASCII_STRING(isolate, "requestType"));
|
||||
ResponseCodeKey.Reset(isolate, TRI_V8_ASCII_STRING(isolate, "responseCode"));
|
||||
ReturnNewKey.Reset(isolate, TRI_V8_ASCII_STRING(isolate, "returnNew"));
|
||||
|
|
|
@ -634,6 +634,9 @@ struct TRI_v8_global_t {
|
|||
/// @brief "requestBody" key name
|
||||
v8::Persistent<v8::String> RequestBodyKey;
|
||||
|
||||
/// @brief "rawRequestBody" key name
|
||||
v8::Persistent<v8::String> RawRequestBodyKey;
|
||||
|
||||
/// @brief "requestType" key name
|
||||
v8::Persistent<v8::String> RequestTypeKey;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,13 @@
|
|||
/* global arango, describe, beforeEach, afterEach, it*/
|
||||
'use strict';
|
||||
|
||||
var expect = require('chai').expect;
|
||||
var FoxxManager = require('org/arangodb/foxx/manager');
|
||||
var fs = require('fs');
|
||||
var internal = require('internal');
|
||||
var basePath = fs.makeAbsolute(fs.join(internal.pathForTesting('common'), 'test-data', 'apps', 'headers'));
|
||||
var origin = arango.getEndpoint().replace(/\+vpp/, '').replace(/^tcp:/, 'http:').replace(/^ssl:/, 'https:');
|
||||
const expect = require('chai').expect;
|
||||
const FoxxManager = require('org/arangodb/foxx/manager');
|
||||
const fs = require('fs');
|
||||
const internal = require('internal');
|
||||
const arango = require('@arangodb').arango;
|
||||
const basePath = fs.makeAbsolute(fs.join(internal.pathForTesting('common'), 'test-data', 'apps', 'headers'));
|
||||
const origin = arango.getEndpoint().replace(/\+vpp/, '').replace(/^tcp:/, 'http:').replace(/^ssl:/, 'https:').replace(/^vst:/, 'http:');
|
||||
|
||||
describe('HTTP headers in Foxx services', function () {
|
||||
describe('Check request-response', function () {
|
||||
|
|
|
@ -34,13 +34,13 @@ const fs = require('fs');
|
|||
const db = require('internal').db;
|
||||
const basePath = fs.makeAbsolute(fs.join(require('internal').pathForTesting('common'), 'test-data', 'apps'));
|
||||
const arango = require('@arangodb').arango;
|
||||
const originalEndpoint = arango.getEndpoint().replace(/localhost/, '127.0.0.1');
|
||||
const origin = arango.getEndpoint().replace(/\+vpp/, '').replace(/^tcp:/, 'http:').replace(/^ssl:/, 'https:').replace(/^vst:/, 'http:');
|
||||
const expect = require('chai').expect;
|
||||
|
||||
describe('Foxx Manager', function () {
|
||||
describe('using different dbs', function () {
|
||||
beforeEach(function () {
|
||||
arango.reconnect(originalEndpoint, '_system', 'root', '');
|
||||
arango.reconnect(origin, '_system', 'root', '');
|
||||
try {
|
||||
db._dropDatabase('tmpFMDB');
|
||||
} catch (err) {
|
||||
|
@ -56,23 +56,23 @@ describe('Foxx Manager', function () {
|
|||
});
|
||||
|
||||
afterEach(function () {
|
||||
arango.reconnect(originalEndpoint, '_system', 'root', '');
|
||||
arango.reconnect(origin, '_system', 'root', '');
|
||||
db._dropDatabase('tmpFMDB');
|
||||
db._dropDatabase('tmpFMDB2');
|
||||
});
|
||||
|
||||
it('should allow to install apps on same mount point', function () {
|
||||
const download = require('internal').download;
|
||||
arango.reconnect(originalEndpoint, 'tmpFMDB', 'root', '');
|
||||
arango.reconnect(origin, 'tmpFMDB', 'root', '');
|
||||
expect(function () {
|
||||
FoxxManager.install(fs.join(basePath, 'itzpapalotl'), '/unittest');
|
||||
}).not.to.throw();
|
||||
arango.reconnect(originalEndpoint, 'tmpFMDB2', 'root', '');
|
||||
arango.reconnect(origin, 'tmpFMDB2', 'root', '');
|
||||
expect(function () {
|
||||
FoxxManager.install(fs.join(basePath, 'minimal-working-manifest'), '/unittest');
|
||||
}).not.to.throw();
|
||||
db._useDatabase('_system');
|
||||
const baseUrl = arango.getEndpoint().replace('tcp://', 'http://') + '/_db';
|
||||
const baseUrl = origin + '/_db';
|
||||
const available = download(baseUrl + '/tmpFMDB/unittest/random');
|
||||
expect(available.code).to.equal(200);
|
||||
const unavailable = download(baseUrl + '/tmpFMDB2/unittest/random');
|
||||
|
@ -87,7 +87,7 @@ describe('Foxx Manager', function () {
|
|||
const mount = '/unittest/upgrade';
|
||||
const setupTeardownApp = fs.join(basePath, 'minimal-working-setup-teardown');
|
||||
const setupApp = fs.join(basePath, 'minimal-working-setup');
|
||||
const url = arango.getEndpoint().replace('tcp://', 'http://') + '/_db/_system' + mount + '/test';
|
||||
const url = origin + '/_db/_system' + mount + '/test';
|
||||
const brokenApp = fs.join(basePath, 'broken-controller-file');
|
||||
|
||||
beforeEach(function () {
|
||||
|
@ -167,7 +167,7 @@ describe('Foxx Manager', function () {
|
|||
const mount = '/unittest/replace';
|
||||
const setupTeardownApp = fs.join(basePath, 'minimal-working-setup-teardown');
|
||||
const setupApp = fs.join(basePath, 'minimal-working-setup');
|
||||
const url = arango.getEndpoint().replace('tcp://', 'http://') + '/_db/_system' + mount + '/test';
|
||||
const url = origin + '/_db/_system' + mount + '/test';
|
||||
const brokenApp = fs.join(basePath, 'broken-controller-file');
|
||||
|
||||
beforeEach(function () {
|
||||
|
|
|
@ -11,6 +11,7 @@ const aql = arangodb.aql;
|
|||
const basePath = fs.makeAbsolute(fs.join(require('internal').pathForTesting('common'), 'test-data', 'apps'));
|
||||
const expect = require('chai').expect;
|
||||
const download = require('internal').download;
|
||||
const origin = arango.getEndpoint().replace(/\+vpp/, '').replace(/^tcp:/, 'http:').replace(/^ssl:/, 'https:').replace(/^vst:/, 'http:');
|
||||
|
||||
describe('Foxx Manager', function () {
|
||||
describe('(CRUD operation) ', function () {
|
||||
|
@ -73,7 +74,7 @@ describe('Foxx Manager', function () {
|
|||
|
||||
it('should be available', function () {
|
||||
FoxxManager.install(setupTeardownApp, mount);
|
||||
const url = `${arango.getEndpoint().replace('tcp://', 'http://')}${mount}/test`;
|
||||
const url = `${origin}${mount}/test`;
|
||||
const res = download(url);
|
||||
expect(res.code).to.equal(200);
|
||||
expect(res.body).to.equal('true');
|
||||
|
@ -235,7 +236,7 @@ describe('Foxx Manager', function () {
|
|||
FoxxManager.install(malformedSetupApp, mount);
|
||||
} catch (e) {
|
||||
}
|
||||
const url = `${arango.getEndpoint().replace('tcp://', 'http://')}${mount}/test`;
|
||||
const url = `${origin}${mount}/test`;
|
||||
const res = download(url);
|
||||
expect(res.code).to.equal(404);
|
||||
});
|
||||
|
@ -276,7 +277,7 @@ describe('Foxx Manager', function () {
|
|||
FoxxManager.install(malformedSetupApp, mount);
|
||||
} catch (e) {
|
||||
}
|
||||
const url = `${arango.getEndpoint().replace('tcp://', 'http://')}${mount}/test`;
|
||||
const url = `${origin}${mount}/test`;
|
||||
const res = download(url);
|
||||
expect(res.code).to.equal(404);
|
||||
});
|
||||
|
@ -322,7 +323,7 @@ describe('Foxx Manager', function () {
|
|||
FoxxManager.install(malformedSetupApp, mount);
|
||||
} catch (e) {
|
||||
}
|
||||
const url = `${arango.getEndpoint().replace('tcp://', 'http://')}${mount}/test`;
|
||||
const url = `${origin}${mount}/test`;
|
||||
const res = download(url);
|
||||
expect(res.code).to.equal(404);
|
||||
});
|
||||
|
@ -352,8 +353,7 @@ describe('Foxx Manager', function () {
|
|||
|
||||
it('should be available after install', function () {
|
||||
FoxxManager.install(setupHealApp, mount);
|
||||
let endpoint = arango.getEndpoint().replace('tcp://', 'http://');
|
||||
const url = endpoint + mount;
|
||||
const url = origin + mount;
|
||||
const res = download(url);
|
||||
expect(res.code).to.equal(200);
|
||||
expect(res.body).to.equal('true');
|
||||
|
@ -362,8 +362,7 @@ describe('Foxx Manager', function () {
|
|||
it('should be available after replace', function () {
|
||||
{ // set up some service
|
||||
FoxxManager.install(setupMinimalApp, mount);
|
||||
let endpoint = arango.getEndpoint().replace('tcp://', 'http://');
|
||||
const url = endpoint + mount;
|
||||
const url = origin + mount;
|
||||
const res = download(url);
|
||||
expect(res.code).to.equal(200);
|
||||
expect(JSON.parse(res.body)).to.deep.equal({hello: 'world'});
|
||||
|
@ -371,8 +370,7 @@ describe('Foxx Manager', function () {
|
|||
|
||||
{ // replace it and call heal() during setup
|
||||
FoxxManager.replace(setupHealApp, mount);
|
||||
let endpoint = arango.getEndpoint().replace('tcp://', 'http://');
|
||||
const url = endpoint + mount;
|
||||
const url = origin + mount;
|
||||
const res = download(url);
|
||||
expect(res.code).to.equal(200);
|
||||
expect(res.body).to.equal('true');
|
||||
|
@ -382,8 +380,7 @@ describe('Foxx Manager', function () {
|
|||
it('should be available after upgrade', function () {
|
||||
{ // set up some service
|
||||
FoxxManager.install(setupMinimalApp, mount);
|
||||
let endpoint = arango.getEndpoint().replace('tcp://', 'http://');
|
||||
const url = endpoint + mount;
|
||||
const url = origin + mount;
|
||||
const res = download(url);
|
||||
expect(res.code).to.equal(200);
|
||||
expect(JSON.parse(res.body)).to.deep.equal({hello: 'world'});
|
||||
|
@ -391,8 +388,7 @@ describe('Foxx Manager', function () {
|
|||
|
||||
{ // upgrade it and call heal() during setup
|
||||
FoxxManager.upgrade(setupHealApp, mount);
|
||||
let endpoint = arango.getEndpoint().replace('tcp://', 'http://');
|
||||
const url = endpoint + mount;
|
||||
const url = origin + mount;
|
||||
const res = download(url);
|
||||
expect(res.code).to.equal(200);
|
||||
expect(res.body).to.equal('true');
|
||||
|
|
|
@ -7,7 +7,8 @@ const fs = require('fs');
|
|||
const internal = require('internal');
|
||||
const basePath = fs.makeAbsolute(fs.join(internal.pathForTesting('common'), 'test-data', 'apps'));
|
||||
const arango = require('@arangodb').arango;
|
||||
const baseUrl = arango.getEndpoint().replace('tcp://', 'http://') + '/_db/_system';
|
||||
const origin = arango.getEndpoint().replace(/\+vpp/, '').replace(/^tcp:/, 'http:').replace(/^ssl:/, 'https:').replace(/^vst:/, 'http:');
|
||||
const baseUrl = origin + '/_db/_system';
|
||||
|
||||
describe('Foxx service path handling', () => {
|
||||
const mount = '/unittest/paths';
|
||||
|
|
|
@ -40,6 +40,7 @@ const request = require('@arangodb/request');
|
|||
|
||||
const arangodb = require('@arangodb');
|
||||
const arango = require('@arangodb').arango;
|
||||
const origin = arango.getEndpoint().replace(/\+vpp/, '').replace(/^tcp:/, 'http:').replace(/^ssl:/, 'https:').replace(/^vst:/, 'http:');
|
||||
const aql = arangodb.aql;
|
||||
const db = internal.db;
|
||||
|
||||
|
@ -53,7 +54,7 @@ describe('Foxx service', () => {
|
|||
});
|
||||
afterEach(() => {
|
||||
waitForJob();
|
||||
download(`${arango.getEndpoint().replace('tcp://', 'http://')}/${mount}`, '', {
|
||||
download(`${origin}/${mount}`, '', {
|
||||
method: 'delete'
|
||||
});
|
||||
if (db._collection('foxx_queue_test')) {
|
||||
|
@ -65,7 +66,7 @@ describe('Foxx service', () => {
|
|||
FOR queue IN _queues
|
||||
RETURN queue
|
||||
`).toArray();
|
||||
const res = download(`${arango.getEndpoint().replace('tcp://', 'http://')}/${mount}`, '', {
|
||||
const res = download(`${origin}/${mount}`, '', {
|
||||
method: 'post'
|
||||
});
|
||||
expect(res.code).to.equal(204);
|
||||
|
@ -80,12 +81,12 @@ describe('Foxx service', () => {
|
|||
FOR queue IN _queues
|
||||
RETURN queue
|
||||
`).toArray();
|
||||
let res = download(`${arango.getEndpoint().replace('tcp://', 'http://')}/${mount}`, '', {
|
||||
let res = download(`${origin}/${mount}`, '', {
|
||||
method: 'post'
|
||||
});
|
||||
expect(res.code).to.equal(204);
|
||||
waitForJob();
|
||||
res = download(`${arango.getEndpoint().replace('tcp://', 'http://')}/${mount}`, '', {
|
||||
res = download(`${origin}/${mount}`, '', {
|
||||
method: 'post'
|
||||
});
|
||||
expect(res.code).to.equal(204);
|
||||
|
@ -96,7 +97,7 @@ describe('Foxx service', () => {
|
|||
expect(queuesAfter.length - queuesBefore.length).to.equal(1);
|
||||
});
|
||||
it('should support jobs running in the queue', () => {
|
||||
let res = download(`${arango.getEndpoint().replace('tcp://', 'http://')}/${mount}`, '', {
|
||||
let res = download(`${origin}/${mount}`, '', {
|
||||
method: 'post'
|
||||
});
|
||||
expect(res.code).to.equal(204);
|
||||
|
@ -109,7 +110,7 @@ describe('Foxx service', () => {
|
|||
expect(jobResult.length).to.equal(1);
|
||||
});
|
||||
it('should support repeating job running in the queue', () => {
|
||||
let res = request.post(`${arango.getEndpoint().replace('tcp://', 'http://')}/${mount}`, {
|
||||
let res = request.post(`${origin}/${mount}`, {
|
||||
body: JSON.stringify({repeatTimes: 2})
|
||||
});
|
||||
expect(res.statusCode).to.equal(204);
|
||||
|
|
|
@ -240,14 +240,7 @@ function iResearchFeatureAqlTestSuite () {
|
|||
|
||||
// force server-side V8 garbage collection
|
||||
if (db._connection !== undefined) { // client test
|
||||
let url = require('internal').arango.getEndpoint().replace('tcp', 'http');
|
||||
url += '/_admin/execute?returnAsJSON=true';
|
||||
let options = require('@arangodb/process-utils').makeAuthorizationHeaders({
|
||||
username: 'root',
|
||||
password: ''
|
||||
});
|
||||
options.method = 'POST';
|
||||
require('internal').download(url, 'require("internal").wait(0.1, true);', options);
|
||||
arango.POST('/_admin/execute?returnAsJSON=true', 'require("internal").wait(0.1, true);');
|
||||
} else {
|
||||
require("internal").wait(0.1, true);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue