Skip to content

Commit af5842e

Browse files
authored
Merge pull request #720 from aoberoi/proxy-testing
Disables automatic proxy detection
2 parents c640509 + 2ef09df commit af5842e

File tree

4 files changed

+77
-3
lines changed

4 files changed

+77
-3
lines changed

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"lint": "tslint --project .",
3636
"test": "npm run build && npm run test:spec && npm run test:integration",
3737
"test:spec": "nyc mocha --opts src/mocha.opts src/*.spec.js src/**/*.spec.js",
38-
"test:integration": "mocha --opts test/mocha.opts test/typescript/test.ts",
38+
"test:integration": "mocha --opts test/mocha.opts test/typescript/test.ts test/proxy/test.js",
3939
"coverage": "codecov",
4040
"build": "npm run build:clean && tsc",
4141
"build:clean": "shx rm -rf ./dist ./coverage ./.nyc_output",
@@ -72,13 +72,16 @@
7272
"busboy": "^0.2.14",
7373
"chai": "^4.1.2",
7474
"codecov": "^3.0.0",
75+
"http-shutdown": "^1.2.0",
76+
"https-proxy-agent": "^2.2.1",
7577
"husky": "^0.14.3",
7678
"jsdoc-to-markdown": "^4.0.1",
7779
"lint-staged": "^6.1.0",
7880
"mocha": "^5.0.0",
7981
"nock": "^9.1.6",
8082
"nyc": "^13.3.0",
8183
"p-is-promise": "^1.1.0",
84+
"proxy": "^0.2.4",
8285
"shx": "^0.2.2",
8386
"sinon": "^4.2.2",
8487
"source-map-support": "^0.5.3",

src/WebClient.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ export class WebClient extends EventEmitter {
177177
transformRequest: [this.serializeApiCallOptions.bind(this)],
178178
validateStatus: () => true, // all HTTP status codes should result in a resolved promise (as opposed to only 2xx)
179179
maxRedirects: 0,
180+
// disabling axios' automatic proxy support:
181+
// axios would read from envvars to configure a proxy automatically, but it doesn't support TLS destinations.
182+
// for compatibility with https://api.slack.com, and for a larger set of possible proxies (SOCKS or other
183+
// protocols), users of this package should use the `agent` option to configure a proxy.
184+
proxy: false,
180185
});
181186
// serializeApiCallOptions will always determine the appropriate content-type
182187
delete this.axios.defaults.headers.post['Content-Type'];
@@ -709,7 +714,7 @@ export class WebClient extends EventEmitter {
709714

710715
return response;
711716
} catch (error) {
712-
this.logger.debug('http request failed');
717+
this.logger.debug('http request failed', error.message);
713718
if (error.request) {
714719
throw requestErrorWithOriginal(error);
715720
}

test/proxy/test.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
require('mocha');
2+
const { createServer } = require('http');
3+
const shutdown = require('http-shutdown');
4+
const setup = require('proxy');
5+
const HttpsProxyAgent = require('https-proxy-agent');
6+
const { assert } = require('chai');
7+
const sinon = require('sinon');
8+
const { WebClient, retryPolicies } = require('../../dist');
9+
10+
const proxyPort = 31280;
11+
12+
describe('with a proxy server listening', function () {
13+
beforeEach(function (done) {
14+
this.proxyUrl = `http://localhost:${proxyPort}`;
15+
this.server = shutdown(setup(createServer()));
16+
this.server.listen(proxyPort, done);
17+
});
18+
19+
it('should connect to a host through the proxy when a proxy agent is configured', function () {
20+
const agent = new HttpsProxyAgent(this.proxyUrl);
21+
const client = new WebClient(undefined, { agent, retryConfig: retryPolicies.rapidRetryPolicy });
22+
23+
// Hooking into authenticate just to observe when an inbound request is seen at the proxy
24+
const spy = sinon.spy();
25+
this.server.authenticate = (req, fn) => {
26+
spy();
27+
fn(null, true);
28+
};
29+
30+
return client.apiCall('method')
31+
.catch(() => {
32+
assert(spy.called);
33+
});
34+
});
35+
36+
it('should NOT connect to a proxy when an environment variable is used', function () {
37+
// manipulate the environment
38+
process.env.http_proxy = this.proxyUrl;
39+
after(function () {
40+
delete process.env.http_proxy;
41+
});
42+
43+
// NOTE: we are intentionally using a non-TLS URL here to make this test effective. otherwise we'd still see the
44+
// effect that the proxy was not called, and that would be a false positive.
45+
const client = new WebClient(undefined, {
46+
slackApiUrl: 'http://example.com/',
47+
retryConfig: retryPolicies.rapidRetryPolicy
48+
});
49+
50+
// Hooking into authenticate just to observe when an inbound request is seen at the proxy
51+
const spy = sinon.spy();
52+
this.server.authenticate = (req, fn) => {
53+
spy();
54+
fn(null, true);
55+
};
56+
57+
return client.apiCall('method')
58+
.catch(() => {
59+
assert(spy.notCalled);
60+
});
61+
});
62+
63+
afterEach(function (done) {
64+
this.server.shutdown(done);
65+
});
66+
});

test/typescript/test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import 'mocha';
2-
import { check, checkDirectory } from 'typings-tester';
2+
import { check } from 'typings-tester';
33

44
describe('typescript typings tests', () => {
55
it('should allow WebClient to work without a token', () => {

0 commit comments

Comments
 (0)