You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by cs...@apache.org on 2019/06/26 16:31:17 UTC

[incubator-openwhisk-client-js] branch master updated: Remove unnecessary node-proxy-agent dependency (#175)

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

csantanapr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-client-js.git


The following commit(s) were added to refs/heads/master by this push:
     new 15276c7  Remove unnecessary node-proxy-agent dependency (#175)
15276c7 is described below

commit 15276c7d9d863e0b13903d3d30e32b5ffe7ebef9
Author: James Thomas <ja...@jamesthom.as>
AuthorDate: Wed Jun 26 17:31:13 2019 +0100

    Remove unnecessary node-proxy-agent dependency (#175)
    
    Maintain proxy feature using needle's built-in proxy support.
    Added ability to set custom agent using constructor option.
    
    Fixes #158
---
 README.md                | 14 ++++++++------
 lib/client.js            | 32 ++++++++++++++++++--------------
 package.json             |  3 +--
 test/unit/client.test.js | 45 ++++++++++++++++++++++++++++++++++-----------
 4 files changed, 61 insertions(+), 33 deletions(-)

diff --git a/README.md b/README.md
index f31e6d3..73b71ca 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@
 # limitations under the License.
 #
 -->
-# OpenWhisk Client for JavaScript
+# Apache OpenWhisk Client for JavaScript
 
 [![Build Status](https://travis-ci.org/apache/incubator-openwhisk-client-js.svg?branch=master)](https://travis-ci.org/apache/incubator-openwhisk-client-js)
 [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0)
@@ -117,6 +117,8 @@ _Client constructor supports the following mandatory parameters:_
 - **apigw_space_guid**. API Gateway space identifier. This is optional when using an API gateway service, defaults to the authentication uuid.
 - **cert**. Client cert to use when connecting to the `apihost` (if `nginx_ssl_verify_client` is turned on in your apihost)
 - **key**. Client key to use when connecting to the `apihost` (if `nginx_ssl_verify_client` is turned on in your apihost)
+- **proxy.** HTTP(s) URI for proxy service to forwards requests through. Uses Needle's [built-in proxy support](https://github.com/tomas/needle#request-options).
+- **agent.** Provide custom [http.Agent](https://nodejs.org/api/http.html#http_class_http_agent) implementation.
 
 
 ### environment variables
@@ -155,13 +157,13 @@ ow.actions.invoke({ noUserAgent: true, name, params })
 
 ### Working with a Proxy
 
- If you are working behind a firewall, you could use the following environment variables to proxy your HTTP/HTTPS requests
+If you are working behind a firewall, HTTP(s) proxy details can be set by using the `proxy` option in the constructor parameters with the proxy service URI, e.g. `http://proxy-server.com:3128`. The proxy URI can also be set using the following environment parameters (to set a proxy without changing application code):
 
- - *http_proxy/HTTP_PROXY*
-- *https_proxy/HTTPS_proxy*
+ - *proxy or PROXY*
+ - *http_proxy or HTTP_PROXY*
+- *https_proxy or HTTPS_proxy*
 
- The openwhisk-client-js SDK supports the use of above mentioned proxies through third-party
- HTTP agent such as [proxy-agent](https://github.com/TooTallNate/node-proxy-agent "proxy-agent Github page")
+If you need more advanced proxy behaviour, rather than using Needle's default [built-in HTTP agent](https://github.com/tomas/needle), the `agent` constructor parameter can be used to set a custom `http.Agent` implementation, e.g [proxy-agent](https://github.com/TooTallNate/node-proxy-agent "proxy-agent Github page")
 
 ## Examples
 
diff --git a/lib/client.js b/lib/client.js
index 7e4e10d..94ab447 100644
--- a/lib/client.js
+++ b/lib/client.js
@@ -8,7 +8,7 @@ const OpenWhiskError = require('./openwhisk_error')
 const needle = require('needle')
 const url = require('url')
 const http = require('http')
-const ProxyAgent = require('proxy-agent')
+
 /**
  * This implements a request-promise-like facade over the needle
  * library. There are two gaps between needle and rp that need to be
@@ -36,18 +36,6 @@ const rp = opts => {
   // this situation than needle
   opts.json = true
 
-  // gather proxy settings if behind a firewall
-  var proxyUri = process.env.proxy ||
-      process.env.HTTP_PROXY ||
-      process.env.http_proxy ||
-      process.env.HTTPS_PROXY ||
-      process.env.https_proxy
-
-  if (proxyUri !== undefined) {
-    // set the agent with corresponding proxy
-    opts.agent = new ProxyAgent(proxyUri)
-  }
-
   return needle(opts.method.toLowerCase(), // needle takes e.g. 'put' not 'PUT'
     opts.url,
     opts.body || opts.params,
@@ -95,6 +83,14 @@ class Client {
         ? process.env['__OW_IGNORE_CERTS'].toLowerCase() === 'true'
         : false)
 
+    // gather proxy settings if behind a firewall
+    const proxy = options.proxy || process.env.PROXY || process.env.proxy ||
+      process.env.HTTP_PROXY || process.env.http_proxy ||
+      process.env.HTTPS_PROXY || process.env.https_proxy
+
+    // custom HTTP agent
+    const agent = options.agent
+
     // if apiversion is available, use it
     const apiversion = options.apiversion || 'v1'
 
@@ -117,7 +113,7 @@ class Client {
       throw new Error(`${messages.INVALID_OPTIONS_ERROR} Missing either api or apihost parameters.`)
     }
 
-    return {apiKey: apiKey, api, apiVersion: apiversion, ignoreCerts: ignoreCerts, namespace: options.namespace, apigwToken: apigwToken, apigwSpaceGuid: apigwSpaceGuid, authHandler: options.auth_handler, noUserAgent: options.noUserAgent, cert: options.cert, key: options.key}
+    return {apiKey: apiKey, api, apiVersion: apiversion, ignoreCerts: ignoreCerts, namespace: options.namespace, apigwToken: apigwToken, apigwSpaceGuid: apigwSpaceGuid, authHandler: options.auth_handler, noUserAgent: options.noUserAgent, cert: options.cert, key: options.key, proxy, agent}
   }
 
   urlFromApihost (apihost, apiversion = 'v1') {
@@ -164,6 +160,14 @@ class Client {
         parms.headers['x-namespace-id'] = this.options.namespace
       }
 
+      if (this.options.proxy) {
+        parms.proxy = this.options.proxy
+      }
+
+      if (this.options.agent) {
+        parms.agent = this.options.agent
+      }
+
       return parms
     })
   }
diff --git a/package.json b/package.json
index 297ee0f..ff5025d 100644
--- a/package.json
+++ b/package.json
@@ -54,8 +54,7 @@
     "standard": "^11.0.1"
   },
   "dependencies": {
-    "needle": "^2.1.0",
-    "proxy-agent": "^3.0.3"
+    "needle": "^2.1.0"
   },
   "babel": {
     "presets": [
diff --git a/test/unit/client.test.js b/test/unit/client.test.js
index 3684108..c0e1c4a 100644
--- a/test/unit/client.test.js
+++ b/test/unit/client.test.js
@@ -6,7 +6,6 @@
 const test = require('ava')
 const Client = require('../../lib/client')
 const http = require('http')
-const ProxyAgent = require('proxy-agent')
 
 test('should use default constructor options', t => {
   const client = new Client({api_key: 'aaa', apihost: 'my_host'})
@@ -172,20 +171,44 @@ test('should return request parameters with cert and key client options', async
   t.is(params.key, 'mykey=')
 })
 
-test('should be able to use proxy options leveraging the proxy agent.', async t => {
-  process.env['proxy'] = 'http://some_proxy'
-  const client = new Client({api_key: 'username:password', apihost: 'blah'})
+test('should be able to set proxy uri as client options.', async t => {
+  const PROXY_URL = 'http://some_proxy:5678'
   const METHOD = 'get'
   const PATH = 'some/path/to/resource'
-  const OPTIONS = {agent: new ProxyAgent(process.env['proxy'])}
+  const OPTIONS = {}
 
+  const client = new Client({api_key: 'username:password', apihost: 'blah', proxy: PROXY_URL})
   const params = await client.params(METHOD, PATH, OPTIONS)
-  t.is(params.method, METHOD)
-  t.true(params.json)
-  t.true(params.rejectUnauthorized)
-  t.true(params.headers.hasOwnProperty('Authorization'))
-  t.deepEqual(params.agent.proxyUri, 'http://some_proxy')
-  delete process.env['proxy']
+  t.is(params.proxy, PROXY_URL)
+})
+
+test('should be able to set http agent using client options.', async t => {
+  const METHOD = 'get'
+  const PATH = 'some/path/to/resource'
+  const OPTIONS = {}
+
+  const agent = new http.Agent({})
+  const client = new Client({api_key: 'username:password', apihost: 'blah', agent})
+  const params = await client.params(METHOD, PATH, OPTIONS)
+  t.is(params.agent, agent)
+})
+
+test('should be able to use env params to set proxy option.', async t => {
+  const PROXY_URL = 'https://some_proxy:1234'
+  const METHOD = 'get'
+  const PATH = 'some/path/to/resource'
+  const OPTIONS = {}
+
+  const ENV_PARAMS = ['proxy', 'PROXY', 'http_proxy', 'HTTP_PROXY',
+    'https_proxy', 'HTTPS_PROXY']
+
+  for (let envParam of ENV_PARAMS) {
+    process.env[envParam] = PROXY_URL
+    const client = new Client({api_key: 'username:password', apihost: 'blah'})
+    const params = await client.params(METHOD, PATH, OPTIONS)
+    t.is(params.proxy, PROXY_URL, `Cannot set proxy using ${envParam}`)
+    delete process.env[envParam]
+  }
 })
 
 test('should return request parameters with explicit api option', async t => {