You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by xi...@apache.org on 2022/12/07 22:18:09 UTC

[tinkerpop] branch 3.5-dev updated: Add User-Agent connection header to Javascript GLV

This is an automated email from the ASF dual-hosted git repository.

xiazcy pushed a commit to branch 3.5-dev
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/3.5-dev by this push:
     new e3a903d725 Add User-Agent connection header to Javascript GLV
     new 8ea43c1330 Merge pull request #1883 from Bit-Quill/cole/user-agent-js
e3a903d725 is described below

commit e3a903d725a4abbe2a3d2875f280d34db62e80b6
Author: Cole Greer <co...@bitquilltech.com>
AuthorDate: Tue Nov 29 17:21:45 2022 -0800

    Add User-Agent connection header to Javascript GLV
    
    User agent follows the form of [Application Name] [GLV Name].[Version] [Language Runtime Version] [OS].[Version] [CPU Architecture]
    
    New feature in the javascript driver to send a user agent header during the web socket handshake for new connections.
    This behavior is enabled by default but can be disabled with a new enableUserAgentOnConnect option.
    
    This commit also adds a configuration section to the JS reference documentation in order to be consistent with the other GLV's.
    The configuration table is populated based on the JSDoc comments from the Connection, Client, and DriverRemoteConnection constructors.
---
 CHANGELOG.asciidoc                                 |  1 +
 docs/src/reference/gremlin-variants.asciidoc       | 28 ++++++++++++++++++++++
 .../gremlin-javascript/lib/driver/client.js        |  5 ++++
 .../gremlin-javascript/lib/driver/connection.js    | 11 ++++++++-
 .../lib/driver/driver-remote-connection.js         |  4 ++++
 .../javascript/gremlin-javascript/lib/utils.js     | 24 +++++++++++++++++++
 6 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 43cce0b8e2..8d13cd11dd 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -39,6 +39,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 * Added user agent to web socket handshake in Gremlin.Net driver. Can be controlled by `EnableUserAgentOnConnect` in `ConnectionPoolSettings`. It is enabled by default.
 * Added user agent to web socket handshake in go driver. Can be controlled by a new `EnableUserAgentOnConnect` setting. It is enabled by default.
 * Added user agent to web socket handshake in python driver. Can be controlled by a new `enable_user_agent_on_connect` setting. It is enabled by default.
+* Added user agent to web socket handshake in javascript driver. Can be controlled by a new `enableUserAgentOnConnect` option. It is enabled by default.
 * Added logging in .NET.
 * Added `addDefaultXModule` to `GraphSONMapper` as a shortcut for including a version matched GraphSON extension module.
 * Modified `GraphSONRecordReader` and `GraphSONRecordWriter` to include the GraphSON extension module by default.
diff --git a/docs/src/reference/gremlin-variants.asciidoc b/docs/src/reference/gremlin-variants.asciidoc
index e445417f7d..aec7f11e88 100644
--- a/docs/src/reference/gremlin-variants.asciidoc
+++ b/docs/src/reference/gremlin-variants.asciidoc
@@ -782,6 +782,34 @@ const { order: { desc } } = gremlin.process;
 g.V().hasLabel('person').has('age',gt(30)).order().by('age',desc).toList()
 ----
 
+[[gremlin-javascript-configuration]]
+=== Configuration
+The following table describes the various configuration options for the Gremlin-Javascript Driver. They
+can be passed in the constructor of a new `Client` or `DriverRemoteConnection` :
+
+[width="100%",cols="3,3,10,^2",options="header"]
+|=========================================================
+|Key |Type |Description |Default
+|url |String |The resource uri. |None
+|options |Object |The connection options. |{}
+|options.ca |Array |Trusted certificates. |undefined
+|options.cert |String/Array/Buffer |The certificate key. |undefined
+|options.mimeType |String |The mime type to use. |'application/vnd.gremlin-v3.0+json'
+|options.pfx |String/Buffer |The private key, certificate, and CA certs. |undefined
+|options.reader |GraphSONReader/GraphBinaryReader |The reader to use. |select reader according to mimeType
+|options.writer |GraphSONWriter |The writer to use. |select writer according to mimeType
+|options.rejectUnauthorized |Boolean |Determines whether to verify or not the server certificate. |undefined
+|options.traversalSource |String |The traversal source. |'g'
+|options.authenticator |Authenticator |The authentication handler to use. |undefined
+|options.processor |String |The name of the opProcessor to use, leave it undefined or set 'session' when session mode. |undefined
+|options.session |String |The sessionId of Client in session mode. undefined means session-less Client. |undefined
+|options.enableUserAgentOnConnect |Boolean |Determines if a user agent will be sent during connection handshake. |true
+|options.headers |Object |An associative array containing the additional header key/values for the initial request. |undefined
+|options.pingEnabled |Boolean |Setup ping interval. |true
+|options.pingInterval |Number |Ping request interval in ms if ping enabled. |60000
+|options.pongTimeout |Number |Timeout of pong response in ms after sending a ping. |30000
+|=========================================================
+
 [[gremlin-javascript-transactions]]
 === Transactions
 
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js
index 811b1fe405..4f64f7e66c 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/client.js
@@ -39,8 +39,13 @@ class Client {
    * @param {String} [options.traversalSource] The traversal source. Defaults to: 'g'.
    * @param {GraphSONWriter} [options.writer] The writer to use.
    * @param {Authenticator} [options.authenticator] The authentication handler to use.
+   * @param {Object} [options.headers] An associative array containing the additional header key/values for the initial request.
+   * @param {Boolean} [options.enableUserAgentOnConnect] Determines if a user agent will be sent during connection handshake. Defaults to: true
    * @param {String} [options.processor] The name of the opProcessor to use, leave it undefined or set 'session' when session mode.
    * @param {String} [options.session] The sessionId of Client in session mode. Defaults to null means session-less Client.
+   * @param {Boolean} [options.pingEnabled] Setup ping interval. Defaults to: true.
+   * @param {Number} [options.pingInterval] Ping request interval in ms if ping enabled. Defaults to: 60000.
+   * @param {Number} [options.pongTimeout] Timeout of pong response in ms after sending a ping. Defaults to: 30000.
    * @constructor
    */
   constructor(url, options = {}) {
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 cbbfb2e368..acaeab4015 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
@@ -64,6 +64,7 @@ class Connection extends EventEmitter {
    * @param {GraphSONWriter} [options.writer] The writer to use.
    * @param {Authenticator} [options.authenticator] The authentication handler to use.
    * @param {Object} [options.headers] An associative array containing the additional header key/values for the initial request.
+   * @param {Boolean} [options.enableUserAgentOnConnect] Determines if a user agent will be sent during connection handshake. Defaults to: true
    * @param {Boolean} [options.pingEnabled] Setup ping interval. Defaults to: true.
    * @param {Number} [options.pingInterval] Ping request interval in ms if ping enabled. Defaults to: 60000.
    * @param {Number} [options.pongTimeout] Timeout of pong response in ms after sending a ping. Defaults to: 30000.
@@ -98,6 +99,7 @@ class Connection extends EventEmitter {
     this.isOpen = false;
     this.traversalSource = options.traversalSource || 'g';
     this._authenticator = options.authenticator;
+    this._enableUserAgentOnConnect = options.enableUserAgentOnConnect !== false;
 
     this._pingEnabled = this.options.pingEnabled === false ? false : true;
     this._pingIntervalDelay = this.options.pingInterval || pingIntervalDelay;
@@ -123,9 +125,16 @@ class Connection extends EventEmitter {
     }
 
     this.emit('log', 'ws open');
+    let headers = this.options.headers;
+    if (this._enableUserAgentOnConnect) {
+      if (!headers) {
+        headers = [];
+      }
+      headers[utils.getUserAgentHeader()] = utils.getUserAgent();
+    }
 
     this._ws = new WebSocket(this.url, {
-      headers: this.options.headers,
+      headers: headers,
       ca: this.options.ca,
       cert: this.options.cert,
       pfx: this.options.pfx,
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
index 05a934593a..869d621099 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
@@ -48,6 +48,10 @@ class DriverRemoteConnection extends RemoteConnection {
    * @param {GraphSONWriter} [options.writer] The writer to use.
    * @param {Authenticator} [options.authenticator] The authentication handler to use.
    * @param {Object} [options.headers] An associative array containing the additional header key/values for the initial request.
+   * @param {Boolean} [options.enableUserAgentOnConnect] Determines if a user agent will be sent during connection handshake. Defaults to: true
+   * @param {Boolean} [options.pingEnabled] Setup ping interval. Defaults to: true.
+   * @param {Number} [options.pingInterval] Ping request interval in ms if ping enabled. Defaults to: 60000.
+   * @param {Number} [options.pongTimeout] Timeout of pong response in ms after sending a ping. Defaults to: 30000.
    * @constructor
    */
   constructor(url, options = {}) {
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 6dd50ba9b0..b7581d26f1 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js
@@ -24,6 +24,8 @@
 'use strict';
 
 const crypto = require('crypto');
+const os = require('os');
+const gremlinVersion = require(__dirname + '/../package.json').version;
 
 exports.toLong = function toLong(value) {
   return new Long(value);
@@ -79,3 +81,25 @@ class ImmutableMap extends Map {
 }
 
 exports.ImmutableMap = ImmutableMap;
+
+function generateUserAgent() {
+  const applicationName = (process.env.npm_package_name || 'NotAvailable').replace('_', ' ');
+  const driverVersion = gremlinVersion.replace('_', ' ');
+  const runtimeVersion = process.version.replace(' ', '_');
+  const osName = os.platform().replace(' ', '_');
+  const osVersion = os.release().replace(' ', '_');
+  const cpuArch = process.arch.replace(' ', '_');
+  const userAgent = `${applicationName} Gremlin-Javascript.${driverVersion} ${runtimeVersion} ${osName}.${osVersion} ${cpuArch}`;
+
+  return userAgent;
+}
+
+exports.getUserAgentHeader = function getUserAgentHeader() {
+  return 'User-Agent';
+};
+
+const userAgent = generateUserAgent();
+
+exports.getUserAgent = function getUserAgent() {
+  return userAgent;
+};