From 6c475bbe1e64ef07803cfc9476b77f0b5c695271 Mon Sep 17 00:00:00 2001 From: Dominik Franek Date: Thu, 24 Jan 2019 22:45:49 +1300 Subject: [PATCH] Don't require crypto package anymore as it is built-in by default. * Change the way how random bytes are generated, not using the crypto package, but built-in Class. update dependency on ws package to version 6+... * remove requiring the ws package * update how WebSockets are called. fix to use better library for creating UUID v4... better use of standard Buffer of Browser instead of Buffer class from NodeJS (not available in Browsers) Don't require crypto package anymore as it is built-in by default. * Change the way how random bytes are generated, not using the crypto package, but built-in Class. update dependency on ws package to version 6+... * remove requiring the ws package * update how WebSockets are called. (cherry picked from commit b016cd1) update dependency on ws package to version 6+... * remove requiring the ws package * update how WebSockets are called. Update README.asciidoc update WS handling so that correct response is parsed. fix for wrong check in handling Message Revert "Update README.asciidoc" This reverts commit 0ba06a3 as it was unintentioanlly comitted to where PR will be created clean the console.log used for debugging only trying to fix the failing Travis build --- .../lib/driver/connection.js | 111 ++++++++++-------- .../gremlin-javascript/lib/utils.js | 19 +-- .../gremlin-javascript/package.json | 12 +- 3 files changed, 69 insertions(+), 73 deletions(-) diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js index cf46475344f..e4c4a0d746a 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/connection.js @@ -23,7 +23,6 @@ 'use strict'; const EventEmitter = require('events'); -const WebSocket = require('ws'); const util = require('util'); const utils = require('../utils'); const serializer = require('../structure/io/graph-serializer'); @@ -120,38 +119,33 @@ class Connection extends EventEmitter { this.emit('log', `ws open`); - this._ws = new WebSocket(this.url, { - headers: this.options.headers, - ca: this.options.ca, - cert: this.options.cert, - pfx: this.options.pfx, - rejectUnauthorized: this.options.rejectUnauthorized - }); + this._ws = new WebSocket(this.url); - this._ws.on('message', (data) => this._handleMessage(data)); - this._ws.on('close', (code, message) => this._handleClose(code, message)); + this._ws.onmessage = (data => this._handleMessage(data)); + this._ws.onerror = (err => this._handleError(err)); + this._ws.onclose = ((code, message) => this._handleClose(code, message)); - this._ws.on('pong', () => { + this._ws.pong = (() => { this.emit('log', 'ws pong received'); - if (this._pongTimeout) { - clearTimeout(this._pongTimeout); - this._pongTimeout = null; - } - }); - this._ws.on('ping', () => { + if (this._pongTimeout) { + clearTimeout(this._pongTimeout); + this._pongTimeout = null; + } + }); + this._ws.ping = (() => { this.emit('log', 'ws ping received'); - this._ws.pong(); - }); + this._ws.pong(); + }); return this._openPromise = new Promise((resolve, reject) => { - this._ws.on('open', () => { - this.isOpen = true; - if (this._pingEnabled) { - this._pingHeartbeat(); - } - resolve(); - }); - this._ws.on('error', (err) => { + this._ws.onopen = (() => { + this.isOpen = true; + if (this._pingEnabled) { + this._pingHeartbeat(); + } + resolve(); + }); + this._ws.on('error', (err) => { this._handleError(err); reject(err); }); @@ -163,14 +157,20 @@ class Connection extends EventEmitter { const rid = requestId || utils.getUuid(); return this.open().then(() => new Promise((resolve, reject) => { if (op !== 'authentication') { - this._responseHandlers[rid] = { - callback: (err, result) => err ? reject(err) : resolve(result), + this._responseHandlers[rid] = { + callback: (err, result) => err ? reject(err) : resolve(result), result: null - }; - } + }; + } - const message = Buffer.from(this._header + JSON.stringify(this._getRequest(rid, op, args, processor))); - this._ws.send(message); + const message = this._header + JSON.stringify(this._getRequest(requestId, bytecode, op, args, processor)); + var buf = new ArrayBuffer(message.length); // 2 bytes for each char + var bufView = new Uint8Array(buf); + for (var i=0, strLen=message.length; i < strLen; i++) { + bufView[i] = message.charCodeAt(i); + } + this._ws.binaryType = 'arraybuffer'; + this._ws.send(bufView); })); } @@ -197,6 +197,7 @@ class Connection extends EventEmitter { args['gremlin'] = this._writer.adaptObject(args['gremlin']); } + return ({ 'requestId': { '@type': 'g:UUID', '@value': id }, 'op': op || 'bytecode', @@ -215,20 +216,20 @@ class Connection extends EventEmitter { this._pingInterval = setInterval(() => { if (this.isOpen === false) { - // in case of if not open.. - if (this._pingInterval) { - clearInterval(this._pingInterval); - this._pingInterval = null; - } + // in case of if not open.. + if (this._pingInterval) { + clearInterval(this._pingInterval); + this._pingInterval = null; } + } - this._pongTimeout = setTimeout(() => { - this._ws.terminate(); - }, this._pongTimeoutDelay); + this._pongTimeout = setTimeout(() => { + this._ws.terminate(); + }, this._pongTimeoutDelay); - this._ws.ping(); + this._ws.ping(); - }, this._pingIntervalDelay); + }, this._pingIntervalDelay); } _handleError(err) { @@ -246,8 +247,14 @@ class Connection extends EventEmitter { this.emit('close', code, message); } - _handleMessage(data) { - const response = this._reader.read(JSON.parse(data.toString())); + _handleMessage(msg) { + if(msg.data instanceof ArrayBuffer ) { + //if in browser javascript, the data are sent as Uint8 + var data = String.fromCharCode.apply(null, new Uint8Array(msg.data)); + }else{ + data = msg; + } + const response = this._reader.read(JSON.parse(data)); if (response.requestId === null || response.requestId === undefined) { // There was a serialization issue on the server that prevented the parsing of the request id // We invoke any of the pending handlers with an error @@ -278,7 +285,7 @@ class Connection extends EventEmitter { if (response.status.code === responseStatusCode.authenticationChallenge && this._authenticator) { this._authenticator.evaluateChallenge(response.result.data).then(res => { return this.submit(undefined, 'authentication', res, response.requestId); - }).catch(handler.callback); + }).catch(handler.callback); return; } @@ -351,10 +358,10 @@ class Connection extends EventEmitter { // in another map for types like EnumValue. Could be a nicer way to do this but for now it's solving the // problem with script submission of non JSON native types if (protocolLevel && key === 'bindings') - newObj[key] = this._adaptArgs(args[key], false); - else - newObj[key] = this._writer.adaptObject(args[key]); - }); + newObj[key] = this._adaptArgs(args[key], false); + else + newObj[key] = this._writer.adaptObject(args[key]); + }); return newObj; } @@ -373,8 +380,8 @@ class Connection extends EventEmitter { if (!this._closePromise) { this._closePromise = new Promise(resolve => { this._closeCallback = resolve; - this._ws.close(); - }); + this._ws.close(); + }); } return this._closePromise; } diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js index f996dba879f..a8c5d261feb 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js @@ -23,7 +23,7 @@ */ 'use strict'; -const crypto = require('crypto'); +const uuidv4 = require('uuid/v4'); exports.toLong = function toLong(value) { return new Long(value); @@ -37,22 +37,7 @@ const Long = exports.Long = function Long(value) { }; exports.getUuid = function getUuid() { - const buffer = crypto.randomBytes(16); - //clear the version - buffer[6] &= 0x0f; - //set the version 4 - buffer[6] |= 0x40; - //clear the variant - buffer[8] &= 0x3f; - //set the IETF variant - buffer[8] |= 0x80; - const hex = buffer.toString('hex'); - return ( - hex.substr(0, 8) + '-' + - hex.substr(8, 4) + '-' + - hex.substr(12, 4) + '-' + - hex.substr(16, 4) + '-' + - hex.substr(20, 12)); + return uuidv4(); }; exports.emptyArray = Object.freeze([]); diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json b/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json index ce4a26743cd..59a1f45f943 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json @@ -14,15 +14,19 @@ ], "license": "Apache-2.0", "dependencies": { - "ws": "^6.2.2" + "ws": "^6.2.2", + "util": "^0.11.1", + "events": "^3.0.0", + "uuid": "^3.3.2" }, "devDependencies": { - "chai": "~4.1.2", - "cucumber": "~4.2.1", + "cucumber": "~5.1.0", + "chai": "~4.2.0", "grunt": "~1.2.0", "grunt-cli": "~1.3.2", "grunt-jsdoc": "~2.4.1", - "mocha": "~5.2.0" + "mocha": "~5.2.0", + "uuid": "^3.3.2" }, "repository": { "type": "git",