proxy_chain_rb 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +16 -16
  3. data/README.md +14 -5
  4. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/.yarn-integrity +23 -0
  5. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/README.md +1 -1
  6. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/browser/bluebird.core.js +254 -121
  7. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/browser/bluebird.core.min.js +3 -3
  8. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/browser/bluebird.js +284 -129
  9. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/browser/bluebird.min.js +4 -4
  10. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/async.js +3 -48
  11. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/debuggability.js +145 -27
  12. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/join.js +4 -7
  13. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/map.js +10 -3
  14. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/promise.js +58 -28
  15. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/promise_array.js +1 -0
  16. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/reduce.js +16 -5
  17. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/settle.js +4 -0
  18. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/util.js +39 -7
  19. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/package.json +39 -63
  20. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/commander/CHANGELOG.md +11 -0
  21. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/commander/index.js +1 -1
  22. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/commander/package.json +20 -52
  23. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/package.json +21 -60
  24. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/ms/package.json +19 -51
  25. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/package.json +41 -66
  26. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/package.json +23 -51
  27. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/CHANGELOG.md +18 -0
  28. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/README.md +8 -0
  29. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/anonymize_proxy.js +5 -0
  30. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/handler_base.js +86 -53
  31. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/handler_forward.js +23 -5
  32. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/handler_tunnel_chain.js +3 -7
  33. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/handler_tunnel_direct.js +1 -1
  34. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/index.js +3 -5
  35. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/server.js +3 -1
  36. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/tcp_tunnel.js +245 -115
  37. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/tcp_tunnel_tools.js +138 -0
  38. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/node_modules/.bin/portastic +1 -0
  39. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/package.json +41 -68
  40. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/underscore/package.json +27 -58
  41. data/lib/proxy_chain_rb/node_js/proxy-chain-server/package.json +1 -1
  42. data/lib/proxy_chain_rb/node_js/proxy-chain-server/server.js +4 -2
  43. data/lib/proxy_chain_rb/node_js/proxy-chain-server/yarn.lock +53 -0
  44. data/lib/proxy_chain_rb/server.rb +8 -6
  45. data/lib/proxy_chain_rb/version.rb +1 -1
  46. data/proxy_chain_rb.gemspec +3 -3
  47. metadata +16 -14
  48. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/handler_tunnel_tcp_chain.js +0 -271
  49. data/lib/proxy_chain_rb/node_js/proxy-chain-server/package-lock.json +0 -63
@@ -1,39 +1,16 @@
1
1
  {
2
- "_from": "ms@2.0.0",
3
- "_id": "ms@2.0.0",
4
- "_inBundle": false,
5
- "_integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
6
- "_location": "/ms",
7
- "_phantomChildren": {},
8
- "_requested": {
9
- "type": "version",
10
- "registry": true,
11
- "raw": "ms@2.0.0",
12
- "name": "ms",
13
- "escapedName": "ms",
14
- "rawSpec": "2.0.0",
15
- "saveSpec": null,
16
- "fetchSpec": "2.0.0"
17
- },
18
- "_requiredBy": [
19
- "/debug"
20
- ],
21
- "_resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
22
- "_shasum": "5608aeadfc00be6c2901df5f9861788de0d597c8",
23
- "_spec": "ms@2.0.0",
24
- "_where": "/Users/sebastianjohnsson/Programming/Javascript/proxy-chain-server/node_modules/debug",
25
- "bugs": {
26
- "url": "https://github.com/zeit/ms/issues"
27
- },
28
- "bundleDependencies": false,
29
- "deprecated": false,
2
+ "name": "ms",
3
+ "version": "2.0.0",
30
4
  "description": "Tiny milisecond conversion utility",
31
- "devDependencies": {
32
- "eslint": "3.19.0",
33
- "expect.js": "0.3.1",
34
- "husky": "0.13.3",
35
- "lint-staged": "3.4.1",
36
- "mocha": "3.4.1"
5
+ "repository": "zeit/ms",
6
+ "main": "./index",
7
+ "files": [
8
+ "index.js"
9
+ ],
10
+ "scripts": {
11
+ "precommit": "lint-staged",
12
+ "lint": "eslint lib/* bin/*",
13
+ "test": "mocha tests.js"
37
14
  },
38
15
  "eslintConfig": {
39
16
  "extends": "eslint:recommended",
@@ -42,11 +19,6 @@
42
19
  "es6": true
43
20
  }
44
21
  },
45
- "files": [
46
- "index.js"
47
- ],
48
- "homepage": "https://github.com/zeit/ms#readme",
49
- "license": "MIT",
50
22
  "lint-staged": {
51
23
  "*.js": [
52
24
  "npm run lint",
@@ -54,16 +26,12 @@
54
26
  "git add"
55
27
  ]
56
28
  },
57
- "main": "./index",
58
- "name": "ms",
59
- "repository": {
60
- "type": "git",
61
- "url": "git+https://github.com/zeit/ms.git"
62
- },
63
- "scripts": {
64
- "lint": "eslint lib/* bin/*",
65
- "precommit": "lint-staged",
66
- "test": "mocha tests.js"
67
- },
68
- "version": "2.0.0"
29
+ "license": "MIT",
30
+ "devDependencies": {
31
+ "eslint": "3.19.0",
32
+ "expect.js": "0.3.1",
33
+ "husky": "0.13.3",
34
+ "lint-staged": "3.4.1",
35
+ "mocha": "3.4.1"
36
+ }
69
37
  }
@@ -1,39 +1,46 @@
1
1
  {
2
- "_from": "bluebird@^2.9.34",
3
- "_id": "bluebird@2.11.0",
4
- "_inBundle": false,
5
- "_integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=",
6
- "_location": "/portastic/bluebird",
7
- "_phantomChildren": {},
8
- "_requested": {
9
- "type": "range",
10
- "registry": true,
11
- "raw": "bluebird@^2.9.34",
12
- "name": "bluebird",
13
- "escapedName": "bluebird",
14
- "rawSpec": "^2.9.34",
15
- "saveSpec": null,
16
- "fetchSpec": "^2.9.34"
17
- },
18
- "_requiredBy": [
19
- "/portastic"
2
+ "name": "bluebird",
3
+ "description": "Full featured Promises/A+ implementation with exceptionally good performance",
4
+ "version": "2.11.0",
5
+ "keywords": [
6
+ "promise",
7
+ "performance",
8
+ "promises",
9
+ "promises-a",
10
+ "promises-aplus",
11
+ "async",
12
+ "await",
13
+ "deferred",
14
+ "deferreds",
15
+ "future",
16
+ "flow control",
17
+ "dsl",
18
+ "fluent interface",
19
+ "parallel",
20
+ "thread",
21
+ "concurrency"
20
22
  ],
21
- "_resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
22
- "_shasum": "534b9033c022c9579c56ba3b3e5a5caafbb650e1",
23
- "_spec": "bluebird@^2.9.34",
24
- "_where": "/Users/sebastianjohnsson/Programming/Javascript/proxy-chain-server/node_modules/portastic",
23
+ "scripts": {
24
+ "lint": "node scripts/jshint.js",
25
+ "test": "node tools/test.js",
26
+ "istanbul": "istanbul",
27
+ "prepublish": "node tools/build.js --no-debug --main --zalgo --browser --minify",
28
+ "generate-browser-core": "node tools/build.js --features=core --no-debug --main --zalgo --browser --minify && mv js/browser/bluebird.js js/browser/bluebird.core.js && mv js/browser/bluebird.min.js js/browser/bluebird.core.min.js"
29
+ },
30
+ "homepage": "https://github.com/petkaantonov/bluebird",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "git://github.com/petkaantonov/bluebird.git"
34
+ },
35
+ "bugs": {
36
+ "url": "http://github.com/petkaantonov/bluebird/issues"
37
+ },
38
+ "license": "MIT",
25
39
  "author": {
26
40
  "name": "Petka Antonov",
27
41
  "email": "petka_antonov@hotmail.com",
28
42
  "url": "http://github.com/petkaantonov/"
29
43
  },
30
- "browser": "./js/browser/bluebird.js",
31
- "bugs": {
32
- "url": "http://github.com/petkaantonov/bluebird/issues"
33
- },
34
- "bundleDependencies": false,
35
- "deprecated": false,
36
- "description": "Full featured Promises/A+ implementation with exceptionally good performance",
37
44
  "devDependencies": {
38
45
  "acorn": "~0.6.0",
39
46
  "baconjs": "^0.7.43",
@@ -49,7 +56,6 @@
49
56
  "istanbul": "^0.3.5",
50
57
  "jshint": "^2.6.0",
51
58
  "jshint-stylish": "~0.2.0",
52
- "kefir": "^2.4.1",
53
59
  "mkdirp": "~0.5.0",
54
60
  "mocha": "~2.1",
55
61
  "open": "~0.0.5",
@@ -58,46 +64,15 @@
58
64
  "rx": "^2.3.25",
59
65
  "serve-static": "^1.7.1",
60
66
  "sinon": "~1.7.3",
61
- "uglify-js": "~2.4.16"
67
+ "uglify-js": "~2.4.16",
68
+ "kefir": "^2.4.1"
62
69
  },
70
+ "main": "./js/main/bluebird.js",
71
+ "browser": "./js/browser/bluebird.js",
63
72
  "files": [
64
73
  "js/browser",
65
74
  "js/main",
66
75
  "js/zalgo",
67
76
  "zalgo.js"
68
- ],
69
- "homepage": "https://github.com/petkaantonov/bluebird",
70
- "keywords": [
71
- "promise",
72
- "performance",
73
- "promises",
74
- "promises-a",
75
- "promises-aplus",
76
- "async",
77
- "await",
78
- "deferred",
79
- "deferreds",
80
- "future",
81
- "flow control",
82
- "dsl",
83
- "fluent interface",
84
- "parallel",
85
- "thread",
86
- "concurrency"
87
- ],
88
- "license": "MIT",
89
- "main": "./js/main/bluebird.js",
90
- "name": "bluebird",
91
- "repository": {
92
- "type": "git",
93
- "url": "git://github.com/petkaantonov/bluebird.git"
94
- },
95
- "scripts": {
96
- "generate-browser-core": "node tools/build.js --features=core --no-debug --main --zalgo --browser --minify && mv js/browser/bluebird.js js/browser/bluebird.core.js && mv js/browser/bluebird.min.js js/browser/bluebird.core.min.js",
97
- "istanbul": "istanbul",
98
- "lint": "node scripts/jshint.js",
99
- "prepublish": "node tools/build.js --no-debug --main --zalgo --browser --minify",
100
- "test": "node tools/test.js"
101
- },
102
- "version": "2.11.0"
77
+ ]
103
78
  }
@@ -1,69 +1,41 @@
1
1
  {
2
- "_from": "portastic@^1.0.1",
3
- "_id": "portastic@1.0.1",
4
- "_inBundle": false,
5
- "_integrity": "sha1-HJgF1D+uj2pAzw28d5QJGi6dDSo=",
6
- "_location": "/portastic",
7
- "_phantomChildren": {},
8
- "_requested": {
9
- "type": "range",
10
- "registry": true,
11
- "raw": "portastic@^1.0.1",
12
- "name": "portastic",
13
- "escapedName": "portastic",
14
- "rawSpec": "^1.0.1",
15
- "saveSpec": null,
16
- "fetchSpec": "^1.0.1"
2
+ "name": "portastic",
3
+ "version": "1.0.1",
4
+ "description": "Pure javascript swiss knife for port management",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "mocha --tdd --bail test/**/*-test.js",
8
+ "travis": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha --report lcovonly -- -R spec test/**/*-test.js && cat ./coverage/lcov.info | ./node_modules/.bin/coveralls && rm -rf ./coverage"
17
9
  },
18
- "_requiredBy": [
19
- "/proxy-chain"
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/alanhoff/node-portastic.git"
13
+ },
14
+ "keywords": [
15
+ "port",
16
+ "management",
17
+ "open ports",
18
+ "find open",
19
+ "interface"
20
20
  ],
21
- "_resolved": "https://registry.npmjs.org/portastic/-/portastic-1.0.1.tgz",
22
- "_shasum": "1c9805d43fae8f6a40cf0dbc7794091a2e9d0d2a",
23
- "_spec": "portastic@^1.0.1",
24
- "_where": "/Users/sebastianjohnsson/Programming/Javascript/proxy-chain-server/node_modules/proxy-chain",
25
- "author": {
26
- "name": "Alan Hoffmeister",
27
- "email": "alanhoffmeister@gmail.com"
21
+ "author": "Alan Hoffmeister <alanhoffmeister@gmail.com>",
22
+ "license": "ISC",
23
+ "bugs": {
24
+ "url": "https://github.com/alanhoff/node-portastic/issues"
28
25
  },
29
26
  "bin": {
30
27
  "portastic": "./bin/portastic"
31
28
  },
32
- "bugs": {
33
- "url": "https://github.com/alanhoff/node-portastic/issues"
34
- },
35
- "bundleDependencies": false,
29
+ "homepage": "https://github.com/alanhoff/node-portastic#readme",
36
30
  "dependencies": {
37
31
  "bluebird": "^2.9.34",
38
32
  "commander": "^2.8.1",
39
33
  "debug": "^2.2.0"
40
34
  },
41
- "deprecated": false,
42
- "description": "Pure javascript swiss knife for port management",
43
35
  "devDependencies": {
44
36
  "chai": "^3.2.0",
45
37
  "coveralls": "^2.11.4",
46
38
  "istanbul": "^0.3.17",
47
39
  "mocha": "^2.2.5"
48
- },
49
- "homepage": "https://github.com/alanhoff/node-portastic#readme",
50
- "keywords": [
51
- "port",
52
- "management",
53
- "open ports",
54
- "find open",
55
- "interface"
56
- ],
57
- "license": "ISC",
58
- "main": "index.js",
59
- "name": "portastic",
60
- "repository": {
61
- "type": "git",
62
- "url": "git+https://github.com/alanhoff/node-portastic.git"
63
- },
64
- "scripts": {
65
- "test": "mocha --tdd --bail test/**/*-test.js",
66
- "travis": "istanbul cover ./node_modules/.bin/_mocha --report lcovonly -- -R spec test/**/*-test.js && cat ./coverage/lcov.info | ./node_modules/.bin/coveralls && rm -rf ./coverage"
67
- },
68
- "version": "1.0.1"
40
+ }
69
41
  }
@@ -1,3 +1,21 @@
1
+ 0.3.2 / 2019-09-17
2
+ ===================
3
+ - Bugfix: Prevent the `"TypeError: hostHeader.startsWith is not a function` error
4
+ in `HandlerForward` by not forwarding duplicate `Host` headers
5
+
6
+ 0.3.1 / 2019-09-07
7
+ ===================
8
+ - *BREAKING CHANGE*: `closeAnonymizedProxy` throws on invalid proxy URL
9
+ - Bugfix: Attempt to prevent the unhandled "write after end" error
10
+ - Bugfix: Proxy no longer attempts to forward invalid
11
+ HTTP status codes and fails with 500 Internal Server Error
12
+ - Fixed closing of sockets on Node 10+
13
+ - Fixed and improved unit tests to also work on Node 10+, update dev dependencies
14
+ - Changed HTTP 200 message from `Connection established` to `Connection Established`
15
+ to be according to standards
16
+ - Proxy source/target sockets are set to no delay (i.e. disabled Nagle's algorithm), to avoid any caching delays
17
+ - Improved logging
18
+
1
19
  0.2.7 / 2018-02-19
2
20
  ===================
3
21
  - Updated README
@@ -171,6 +171,7 @@ server.close(true, () => {
171
171
  ```
172
172
 
173
173
  The `closeConnections` parameter indicates whether pending proxy connections should be forcibly closed.
174
+ If it's `false`, the function will wait until all connections are closed, which can take a long time.
174
175
  If the `callback` parameter is omitted, the function returns a promise.
175
176
 
176
177
 
@@ -213,6 +214,9 @@ const proxyChain = require('proxy-chain');
213
214
  await page.goto('https://www.example.com');
214
215
  await page.screenshot({ path: 'example.png' });
215
216
  await browser.close();
217
+
218
+ // Clean up
219
+ await proxyChain.closeAnonymizedProxy(newProxyUrl, true);
216
220
  })();
217
221
  ```
218
222
 
@@ -223,6 +227,7 @@ If proxy was not found or was already closed, the function has no effect
223
227
  and its result is `false`. Otherwise the result is `true`.
224
228
 
225
229
  The `closeConnections` parameter indicates whether pending proxy connections are forcibly closed.
230
+ If it's `false`, the function will wait until all connections are closed, which can take a long time.
226
231
 
227
232
  The function takes an optional callback that receives the result Boolean from the function.
228
233
  If callback is not provided, the function returns a promise instead.
@@ -242,6 +247,8 @@ The `createTunnel()` function accepts an optional Node.js-style callback that re
242
247
  If no callback is supplied, the function returns a promise that resolves to a String with
243
248
  the path to the local endpoint.
244
249
 
250
+ For more information, read this [blog post](https://blog.apify.com/tunneling-arbitrary-protocols-over-http-proxy-with-static-ip-address-b3a2222191ff).
251
+
245
252
  Example:
246
253
 
247
254
  ```javascript
@@ -256,6 +263,7 @@ Closes tunnel previously started by `createTunnel()`.
256
263
  The result value is `false` if the tunnel was not found or was already closed, otherwise it is `true`.
257
264
 
258
265
  The `closeConnections` parameter indicates whether pending connections are forcibly closed.
266
+ If it's `false`, the function will wait until all connections are closed, which can take a long time.
259
267
 
260
268
  The function takes an optional callback that receives the result of the function.
261
269
  If the callback is not provided, the function returns a promise instead.
@@ -83,10 +83,15 @@ var anonymizeProxy = exports.anonymizeProxy = function anonymizeProxy(proxyUrl,
83
83
  * and its result if `false`. Otherwise the result is `true`.
84
84
  * @param anonymizedProxyUrl
85
85
  * @param closeConnections If true, pending proxy connections are forcibly closed.
86
+ * If `false`, the function will wait until all connections are closed, which can take a long time.
86
87
  * @param callback Optional callback
87
88
  * @returns Returns a promise if no callback was supplied
88
89
  */
89
90
  var closeAnonymizedProxy = exports.closeAnonymizedProxy = function closeAnonymizedProxy(anonymizedProxyUrl, closeConnections, callback) {
91
+ if (typeof anonymizedProxyUrl !== 'string') {
92
+ throw new Error('The "anonymizedProxyUrl" parameter must be a string');
93
+ }
94
+
90
95
  var server = anonymizedProxyUrlToServer[anonymizedProxyUrl];
91
96
  if (!server) {
92
97
  return _bluebird2.default.resolve(false).nodeify(callback);
@@ -24,8 +24,6 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
24
24
 
25
25
  function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
26
26
 
27
- /* globals Buffer */
28
-
29
27
  /**
30
28
  * Base class for proxy connection handlers. It emits the `destroyed` event
31
29
  * when the handler is no longer used.
@@ -49,6 +47,7 @@ var HandlerBase = function (_EventEmitter) {
49
47
  if (!server) throw new Error('The "server" option is required');
50
48
  if (!id) throw new Error('The "id" option is required');
51
49
  if (!srcRequest) throw new Error('The "srcRequest" option is required');
50
+ if (!srcRequest.socket) throw new Error('"srcRequest.socket" cannot be null');
52
51
  if (!trgParsed.hostname) throw new Error('The "trgParsed.hostname" option is required');
53
52
 
54
53
  _this.server = server;
@@ -82,7 +81,9 @@ var HandlerBase = function (_EventEmitter) {
82
81
  }
83
82
 
84
83
  // Bind all event handlers to this instance
85
- _this.bindHandlersToThis(['onSrcResponseFinish', 'onSrcSocketClose', 'onSrcSocketEnd', 'onSrcSocketError', 'onTrgSocket', 'onTrgSocketClose', 'onTrgSocketEnd', 'onTrgSocketError']);
84
+ _this.bindHandlersToThis(['onSrcResponseFinish', 'onSrcResponseError', 'onSrcSocketEnd', 'onSrcSocketFinish', 'onSrcSocketClose', 'onSrcSocketError', 'onTrgSocket', 'onTrgSocketEnd', 'onTrgSocketFinish', 'onTrgSocketClose', 'onTrgSocketError']);
85
+
86
+ _this.srcResponse.on('error', _this.onSrcResponseError);
86
87
 
87
88
  // Called for the ServerResponse's "finish" event
88
89
  // Normally, Node's "http" module has a "finish" event listener that would
@@ -91,9 +92,13 @@ var HandlerBase = function (_EventEmitter) {
91
92
  // never gets hooked up, so we must manually close the socket...
92
93
  _this.srcResponse.once('finish', _this.onSrcResponseFinish);
93
94
 
94
- _this.srcSocket.once('close', _this.onSrcSocketClose);
95
+ // Forward data directly to source client without any delay
96
+ _this.srcSocket.setNoDelay();
97
+
95
98
  _this.srcSocket.once('end', _this.onSrcSocketEnd);
96
- _this.srcSocket.once('error', _this.onSrcSocketError);
99
+ _this.srcSocket.once('close', _this.onSrcSocketClose);
100
+ _this.srcSocket.once('finish', _this.onSrcSocketFinish);
101
+ _this.srcSocket.on('error', _this.onSrcSocketError);
97
102
  return _this;
98
103
  }
99
104
 
@@ -118,6 +123,25 @@ var HandlerBase = function (_EventEmitter) {
118
123
  key: 'run',
119
124
  value: function run() {} // eslint-disable-line
120
125
 
126
+ }, {
127
+ key: 'onSrcSocketEnd',
128
+ value: function onSrcSocketEnd() {
129
+ if (this.isClosed) return;
130
+ this.log('Source socket ended');
131
+ this.close();
132
+ }
133
+
134
+ // On Node 10+, the 'close' event is called only after socket is destroyed,
135
+ // so we also need to listen for the stream 'finish' event
136
+
137
+ }, {
138
+ key: 'onSrcSocketFinish',
139
+ value: function onSrcSocketFinish() {
140
+ if (this.isClosed) return;
141
+ this.log('Source socket finished');
142
+ this.close();
143
+ }
144
+
121
145
  // If the client closes the connection prematurely,
122
146
  // then immediately destroy the upstream socket, there's nothing we can do with it
123
147
 
@@ -129,17 +153,22 @@ var HandlerBase = function (_EventEmitter) {
129
153
  this.close();
130
154
  }
131
155
  }, {
132
- key: 'onSrcSocketEnd',
133
- value: function onSrcSocketEnd() {
156
+ key: 'onSrcSocketError',
157
+ value: function onSrcSocketError(err) {
134
158
  if (this.isClosed) return;
135
- this.log('Source socket ended');
159
+ this.log('Source socket failed: ' + (err.stack || err));
136
160
  this.close();
137
161
  }
162
+
163
+ // This is to address https://github.com/apifytech/proxy-chain/issues/27
164
+ // It seems that when client closed the connection, the piped target socket
165
+ // can still pump data to it, which caused unhandled "write after end" error
166
+
138
167
  }, {
139
- key: 'onSrcSocketError',
140
- value: function onSrcSocketError(err) {
168
+ key: 'onSrcResponseError',
169
+ value: function onSrcResponseError(err) {
141
170
  if (this.isClosed) return;
142
- this.log('Source socket failed: ' + (err.stack || err));
171
+ this.log('Source response failed: ' + (err.stack || err));
143
172
  this.close();
144
173
  }
145
174
  }, {
@@ -163,19 +192,21 @@ var HandlerBase = function (_EventEmitter) {
163
192
 
164
193
  this.trgSocket = socket;
165
194
 
166
- socket.once('close', this.onTrgSocketClose);
195
+ // Forward data directly to target server without any delay
196
+ this.trgSocket.setNoDelay();
197
+
167
198
  socket.once('end', this.onTrgSocketEnd);
168
- socket.once('error', this.onTrgSocketError);
199
+ socket.once('finish', this.onTrgSocketFinish);
200
+ socket.once('close', this.onTrgSocketClose);
201
+ socket.on('error', this.onTrgSocketError);
169
202
  }
170
-
171
- // Once target socket closes, we need to give time
172
- // to source socket to receive pending data, so we only call end()
173
-
174
203
  }, {
175
- key: 'onTrgSocketClose',
176
- value: function onTrgSocketClose() {
204
+ key: 'trgSocketShutdown',
205
+ value: function trgSocketShutdown(msg) {
177
206
  if (this.isClosed) return;
178
- this.log('Target socket closed');
207
+ this.log(msg);
208
+ // Once target socket closes, we need to give time
209
+ // to source socket to receive pending data, so we only call end()
179
210
  // If socket is closed here instead of response, phantomjs does not properly parse the response as http response.
180
211
  if (this.srcResponse) {
181
212
  this.srcResponse.end();
@@ -187,15 +218,17 @@ var HandlerBase = function (_EventEmitter) {
187
218
  }, {
188
219
  key: 'onTrgSocketEnd',
189
220
  value: function onTrgSocketEnd() {
190
- if (this.isClosed) return;
191
- this.log('Target socket ended');
192
- // If socket is closed here instead of response, phantomjs does not properly parse the response as http response.
193
- if (this.srcResponse) {
194
- this.srcResponse.end();
195
- } else if (this.srcSocket) {
196
- // Handler tunnel chain does not use srcResponse, but needs to close srcSocket
197
- this.srcSocket.end();
198
- }
221
+ this.trgSocketShutdown('Target socket ended');
222
+ }
223
+ }, {
224
+ key: 'onTrgSocketFinish',
225
+ value: function onTrgSocketFinish() {
226
+ this.trgSocketShutdown('Target socket finished');
227
+ }
228
+ }, {
229
+ key: 'onTrgSocketClose',
230
+ value: function onTrgSocketClose() {
231
+ this.trgSocketShutdown('Target socket closed');
199
232
  }
200
233
  }, {
201
234
  key: 'onTrgSocketError',
@@ -274,42 +307,42 @@ var HandlerBase = function (_EventEmitter) {
274
307
  }
275
308
 
276
309
  /**
277
- * Detaches all listeners and destroys all sockets.
310
+ * Detaches all listeners, destroys all sockets and emits the 'close' event.
278
311
  */
279
312
 
280
313
  }, {
281
314
  key: 'close',
282
315
  value: function close() {
283
- if (!this.isClosed) {
284
- this.log('Closing handler');
285
-
286
- // Save stats before sockets are destroyed
287
- var stats = this.getStats();
316
+ if (this.isClosed) return;
288
317
 
289
- if (this.srcRequest) {
290
- this.srcRequest.destroy();
291
- this.srcRequest = null;
292
- }
318
+ this.log('Closing handler');
293
319
 
294
- if (this.srcSocket) {
295
- this.srcSocket.destroy();
296
- this.srcSocket = null;
297
- }
320
+ // Save stats before sockets are destroyed
321
+ var stats = this.getStats();
298
322
 
299
- if (this.trgRequest) {
300
- this.trgRequest.abort();
301
- this.trgRequest = null;
302
- }
323
+ if (this.srcRequest) {
324
+ this.srcRequest.destroy();
325
+ this.srcRequest = null;
326
+ }
303
327
 
304
- if (this.trgSocket) {
305
- this.trgSocket.destroy();
306
- this.trgSocket = null;
307
- }
328
+ if (this.srcSocket) {
329
+ this.srcSocket.destroy();
330
+ this.srcSocket = null;
331
+ }
308
332
 
309
- this.isClosed = true;
333
+ if (this.trgRequest) {
334
+ this.trgRequest.abort();
335
+ this.trgRequest = null;
336
+ }
310
337
 
311
- this.emit('close', { stats: stats });
338
+ if (this.trgSocket) {
339
+ this.trgSocket.destroy();
340
+ this.trgSocket = null;
312
341
  }
342
+
343
+ this.isClosed = true;
344
+
345
+ this.emit('close', { stats: stats });
313
346
  }
314
347
  }]);
315
348