8000 add the ability to force the traffic from/to the server to be json, for better sniffeability by dothebart · Pull Request #10239 · arangodb/arangodb · GitHub
[go: up one dir, main page]

Skip to content

add the ability to force the traffic from/to the server to be json, for better sniffeability #10239

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 14, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions arangosh/Shell/ClientFeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ ClientFeature::ClientFeature(application_features::ApplicationServer& server,
bool allowJwtSecret, double connectionTimeout, double requestTimeout)
: HttpEndpointProvider(server, "Client"),
_databaseName("_system"),
_authentication(true),
_askJwtSecret(false),
_endpoint(Endpoint::defaultEndpoint(Endpoint::TransportType::HTTP)),
_username("root"),
_password(""),
Expand All @@ -60,11 +58,14 @@ ClientFeature::ClientFeature(application_features::ApplicationServer& server,
_requestTimeout(requestTimeout),
_maxPacketSize(1024 * 1024 * 1024),
_sslProtocol(TLS_V12),
_allowJwtSecret(allowJwtSecret),
_retries(DEFAULT_RETRIES),
_authentication(true),
_askJwtSecret(false),
_allowJwtSecret(allowJwtSecret),
_warn(false),
_warnConnect(true),
_haveServerPassword(false)
_haveServerPassword(false),
_forceJson(false)
#if _WIN32
,
_codePage(65001), // default to UTF8
Expand Down Expand Up @@ -104,6 +105,10 @@ void ClientFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
"for a password",
new StringParameter(&_password));

options->addOption("--server.force-json",
"force not to use velocypack for better debugability",
new BooleanParameter(&_forceJson));

if (_allowJwtSecret) {
// currently the option is only present for arangosh, but none
// of the other client tools
Expand Down
13 changes: 9 additions & 4 deletions arangosh/Shell/ClientFeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ class ClientFeature final : public HttpEndpointProvider {
void requestTimeout(double value) { _requestTimeout = value; }
uint64_t maxPacketSize() const { return _maxPacketSize; }
uint64_t sslProtocol() const { return _sslProtocol; }

bool forceJson() const { return _forceJson; }
void setForceJson(bool value) { _forceJson = value; }

std::unique_ptr<httpclient::GeneralClientConnection> createConnection();
std::unique_ptr<httpclient::GeneralClientConnection> createConnection(std::string const& definition);
std::unique_ptr<httpclient::SimpleHttpClient> createHttpClient() const;
Expand Down Expand Up @@ -110,8 +112,6 @@ class ClientFeature final : public HttpEndpointProvider {
void loadJwtSecretFile();

std::string _databaseName;
bool _authentication;
bool _askJwtSecret;
std::string _endpoint;
std::string _username;
std::string _password;
Expand All @@ -122,11 +122,16 @@ class ClientFeature final : public HttpEndpointProvider {
uint64_t _maxPacketSize;
uint64_t _sslProtocol;

bool _allowJwtSecret;
size_t _retries;
bool _authentication;
bool _askJwtSecret;

bool _allowJwtSecret;
bool _warn;
bool _warnConnect;
bool _haveServerPassword;
bool _forceJson;

#if _WIN32
uint16_t _codePage;
uint16_t _originalCodePage;
Expand Down
48 changes: 45 additions & 3 deletions arangosh/Shell/V8ClientConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,8 @@ void V8ClientConnection::connect(ClientFeature* client) {

TRI_ASSERT(client);
std::lock_guard<std::recursive_mutex> guard(_lock);

_forceJson = client->forceJson();

_requestTimeout = std::chrono::duration<double>(client->requestTimeout());
_databaseName = client->databaseName();
_builder.endpoint(client->endpoint());
Expand All @@ -239,6 +240,7 @@ void V8ClientConnection::reconnect(ClientFeature* client) {
_requestTimeout = std::chrono::duration<double>(client->requestTimeout());
_databaseName = client->databaseName();
_builder.endpoint(client->endpoint());
_forceJson = client->forceJson();
// check jwtSecret first, as it is empty by default,
// but username defaults to "root" in most configurations
if (!client->jwtSecret().empty()) {
Expand Down Expand Up @@ -1197,6 +1199,39 @@ static void ClientConnection_isConnected(v8::FunctionCallbackInfo<v8::Value> con
TRI_V8_TRY_CATCH_END
}

////////////////////////////////////////////////////////////////////////////////
/// @brief ClientConnection method "forceJson"
////////////////////////////////////////////////////////////////////////////////

static void ClientConnection_forceJson(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate);

// get the connection
V8ClientConnection* v8connection =
TRI_UnwrapClass<V8ClientConnection>(args.Holder(), WRAP_TYPE_CONNECTION, TRI_IGETC);

if (v8connection == nullptr) {
TRI_V8_THROW_EXCEPTION_INTERNAL("connection class corrupted");
}

if (args.Length() != 1) {
TRI_V8_THROW_EXCEPTION_USAGE("forceJson(bool)");
}

v8::Local<v8::External> wrap = v8::Local<v8::External>::Cast(args.Data());
ClientFeature* client = static_cast<ClientFeature*>(wrap->Value());
if (client == nullptr) {
TRI_V8_THROW_EXCEPTION_INTERNAL("connection class corrupted");
}

bool forceJson = TRI_ObjectToBoolean(isolate, args[0]);
v8connection->setForceJson(forceJson);

client->setForceJson(forceJson);
TRI_V8_TRY_CATCH_END
}

////////////////////////////////////////////////////////////////////////////////
/// @brief ClientConnection method "timeout"
////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1507,7 +1542,11 @@ v8::Local<v8::Value> V8ClientConnection::requestData(
}
}
if (req->header.acceptType() == fuerte::ContentType::Unset) {
req->header.acceptType(fuerte::ContentType::VPack);
if (_forceJson) {
req->header.acceptType(fuerte::ContentType::Json);
} else {
req->header.acceptType(fuerte::ContentType::VPack);
}
}
req->timeout(std::chrono::duration_cast<std::chrono::milliseconds>(_requestTimeout));

Expand Down Expand Up @@ -1806,6 +1845,9 @@ void V8ClientConnection::initServer(v8::Isolate* isolate, v8::Local<v8::Context>
connection_proto->Set(isolate, "isConnected",
v8::FunctionTemplate::New(isolate, ClientConnection_isConnected));

connection_proto->Set(isolate, "forceJson",
v8::FunctionTemplate::New(isolate, ClientConnection_forceJson, v8client));

connection_proto->Set(isolate, "reconnect",
v8::FunctionTemplate::New(isolate, ClientConnection_reconnect, v8client));

Expand All @@ -1814,7 +1856,7 @@ void V8ClientConnection::initServer(v8::Isolate* isolate, v8::Local<v8::Context>
v8client));

connection_proto->Set(isolate, "timeout",
v8::FunctionTemplate::New(isolate, ClientConnection_timeout));
v8::FunctionTemplate::New(isolate, ClientConnection_timeout, v8client));

connection_proto->Set(isolate, "toString",
v8::FunctionTemplate::New(isolate, ClientConnection_toString));
Expand Down
2 changes: 2 additions & 0 deletions arangosh/Shell/V8ClientConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class V8ClientConnection {

std::string const& databaseName() const { return _databaseName; }
void setDatabaseName(std::string const& value) { _databaseName = value; }
void setForceJson(bool value) { _forceJson = value; };
std::string username() const { return _builder.user(); }
std::string password() const { return _builder.password(); }
int lastHttpReturnCode() const { return _lastHttpReturnCode; }
Expand Down Expand Up @@ -162,6 +163,7 @@ class V8ClientConnection {
fuerte::ConnectionBuilder _builder;
std::shared_ptr<fuerte::Connection> _connection;
velocypack::Options _vpackOptions;
bool _forceJson;
};
} // namespace arangodb

Expand Down
4 changes: 4 additions & 0 deletions js/client/modules/@arangodb/test-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,10 @@ function runInArangosh (options, instanceInfo, file, addArgs) {

args['javascript.unit-test-filter'] = options.testCase;

if (options.forceJson) {
args['server.force-json'] = true;
}

if (!options.verbose) {
args['log.level'] = 'warning';
}
Expand Down
6 changes: 5 additions & 1 deletion js/client/modules/@arangodb/testing.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* jshint strict: false, sub: true */
/* global print */
/* global print, arango */
'use strict';

// /////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -86,6 +86,7 @@ let optionsDocumentation = [
' - `arangosearch`: if set to true enable the ArangoSearch-related tests',
' - `minPort`: minimum port number to use',
' - `maxPort`: maximum port number to use',
' - `forceJson`: don\'t use vpack - for better debuggeability',
' - `vst`: attempt to connect to the SUT via vst',
' - `dbServers`: number of DB-Servers to use',
' - `coordinators`: number coordinators to use',
Expand Down Expand Up @@ -169,6 +170,7 @@ const optionsDefaults = {
'extraArgs': {},
'extremeVerbosity': false,
'force': true,
'forceJson': false,
'getSockStat': false,
'arangosearch':true,
'loopEternal': false,
Expand Down Expand Up @@ -574,6 +576,8 @@ function unitTest (cases, options) {
};
}

arango.forceJson(options.forceJson);

if ((cases.length === 1) && cases[0] === 'auto') {
return autoTest(options);
} else {
Expand Down
0