proxy_chain_rb 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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