proxy_chain_rb 0.1.0

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 (169) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +7 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +6 -0
  7. data/Gemfile.lock +41 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +43 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +15 -0
  12. data/bin/setup +8 -0
  13. data/lib/proxy_chain_rb.rb +7 -0
  14. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/.bin/portastic +1 -0
  15. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/LICENSE +21 -0
  16. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/README.md +57 -0
  17. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/changelog.md +1 -0
  18. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/browser/bluebird.core.js +3824 -0
  19. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/browser/bluebird.core.min.js +31 -0
  20. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/browser/bluebird.js +5666 -0
  21. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/browser/bluebird.min.js +31 -0
  22. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/any.js +21 -0
  23. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/assert.js +55 -0
  24. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/async.js +165 -0
  25. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/bind.js +67 -0
  26. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/bluebird.js +11 -0
  27. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/call_get.js +123 -0
  28. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/cancel.js +129 -0
  29. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/catch_filter.js +42 -0
  30. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/context.js +69 -0
  31. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/debuggability.js +934 -0
  32. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/direct_resolve.js +46 -0
  33. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/each.js +30 -0
  34. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/errors.js +116 -0
  35. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/es5.js +80 -0
  36. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/filter.js +12 -0
  37. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/finally.js +146 -0
  38. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/generators.js +223 -0
  39. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/join.js +168 -0
  40. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/map.js +168 -0
  41. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/method.js +55 -0
  42. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/nodeback.js +51 -0
  43. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/nodeify.js +58 -0
  44. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/promise.js +789 -0
  45. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/promise_array.js +185 -0
  46. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/promisify.js +314 -0
  47. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/props.js +118 -0
  48. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/queue.js +73 -0
  49. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/race.js +49 -0
  50. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/reduce.js +172 -0
  51. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/schedule.js +62 -0
  52. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/settle.js +43 -0
  53. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/some.js +148 -0
  54. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/synchronous_inspection.js +103 -0
  55. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/thenables.js +86 -0
  56. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/timers.js +93 -0
  57. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/using.js +226 -0
  58. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/js/release/util.js +389 -0
  59. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/bluebird/package.json +102 -0
  60. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/commander/CHANGELOG.md +408 -0
  61. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/commander/LICENSE +22 -0
  62. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/commander/Readme.md +428 -0
  63. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/commander/index.js +1224 -0
  64. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/commander/package.json +70 -0
  65. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/commander/typings/index.d.ts +310 -0
  66. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/.coveralls.yml +1 -0
  67. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/.eslintrc +11 -0
  68. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/.npmignore +9 -0
  69. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/.travis.yml +14 -0
  70. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/CHANGELOG.md +362 -0
  71. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/LICENSE +19 -0
  72. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/Makefile +50 -0
  73. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/README.md +312 -0
  74. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/component.json +19 -0
  75. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/karma.conf.js +70 -0
  76. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/node.js +1 -0
  77. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/package.json +88 -0
  78. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/src/browser.js +185 -0
  79. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/src/debug.js +202 -0
  80. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/src/index.js +10 -0
  81. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/src/inspector-log.js +15 -0
  82. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/debug/src/node.js +248 -0
  83. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/ms/index.js +152 -0
  84. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/ms/license.md +21 -0
  85. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/ms/package.json +69 -0
  86. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/ms/readme.md +51 -0
  87. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/LICENSE +13 -0
  88. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/README.md +148 -0
  89. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/bin/portastic +65 -0
  90. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/history.md +7 -0
  91. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/index.js +4 -0
  92. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/lib/monitor.js +59 -0
  93. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/lib/portastic.js +167 -0
  94. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/LICENSE +21 -0
  95. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/README.md +677 -0
  96. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/changelog.md +1730 -0
  97. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/browser/bluebird.js +4892 -0
  98. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/browser/bluebird.min.js +31 -0
  99. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/any.js +21 -0
  100. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/assert.js +55 -0
  101. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/async.js +150 -0
  102. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/bind.js +72 -0
  103. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/bluebird.js +11 -0
  104. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/call_get.js +123 -0
  105. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/cancel.js +48 -0
  106. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/captured_trace.js +493 -0
  107. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/catch_filter.js +66 -0
  108. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/context.js +38 -0
  109. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/debuggability.js +162 -0
  110. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/direct_resolve.js +63 -0
  111. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/each.js +12 -0
  112. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/errors.js +111 -0
  113. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/es5.js +80 -0
  114. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/filter.js +12 -0
  115. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/finally.js +98 -0
  116. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/generators.js +136 -0
  117. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/join.js +107 -0
  118. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/map.js +133 -0
  119. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/method.js +44 -0
  120. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/nodeify.js +59 -0
  121. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/progress.js +76 -0
  122. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/promise.js +759 -0
  123. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/promise_array.js +142 -0
  124. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/promise_resolver.js +123 -0
  125. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/promisify.js +307 -0
  126. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/props.js +79 -0
  127. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/queue.js +90 -0
  128. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/race.js +47 -0
  129. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/reduce.js +148 -0
  130. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/schedule.js +35 -0
  131. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/settle.js +40 -0
  132. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/some.js +125 -0
  133. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/synchronous_inspection.js +94 -0
  134. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/thenables.js +84 -0
  135. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/timers.js +64 -0
  136. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/using.js +213 -0
  137. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/js/main/util.js +321 -0
  138. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/node_modules/bluebird/package.json +103 -0
  139. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/portastic/package.json +69 -0
  140. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/CHANGELOG.md +109 -0
  141. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/LICENSE +201 -0
  142. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/README.md +278 -0
  143. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/anonymize_proxy.js +100 -0
  144. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/handler_base.js +319 -0
  145. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/handler_custom_response.js +96 -0
  146. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/handler_forward.js +173 -0
  147. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/handler_tunnel_chain.js +132 -0
  148. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/handler_tunnel_direct.js +89 -0
  149. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/handler_tunnel_tcp_chain.js +271 -0
  150. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/index.js +26 -0
  151. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/run_locally.js +66 -0
  152. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/server.js +595 -0
  153. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/tcp_tunnel.js +138 -0
  154. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/testing_tcp_service.js +37 -0
  155. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/build/tools.js +220 -0
  156. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/proxy-chain/package.json +104 -0
  157. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/underscore/LICENSE +23 -0
  158. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/underscore/README.md +28 -0
  159. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/underscore/package.json +81 -0
  160. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/underscore/underscore-min.js +5 -0
  161. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/underscore/underscore-min.js.map +1 -0
  162. data/lib/proxy_chain_rb/node_js/proxy-chain-server/node_modules/underscore/underscore.js +1692 -0
  163. data/lib/proxy_chain_rb/node_js/proxy-chain-server/package-lock.json +63 -0
  164. data/lib/proxy_chain_rb/node_js/proxy-chain-server/package.json +15 -0
  165. data/lib/proxy_chain_rb/node_js/proxy-chain-server/server.js +25 -0
  166. data/lib/proxy_chain_rb/server.rb +49 -0
  167. data/lib/proxy_chain_rb/version.rb +3 -0
  168. data/proxy_chain_rb.gemspec +31 -0
  169. metadata +266 -0
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ var _server = require('./server');
4
+
5
+ var _tools = require('./tools');
6
+
7
+ var _anonymize_proxy = require('./anonymize_proxy');
8
+
9
+ var _tcp_tunnel = require('./tcp_tunnel');
10
+
11
+ /* globals module */
12
+
13
+ // Publicly exported functions and classes
14
+ var ProxyChain = {
15
+ Server: _server.Server,
16
+ RequestError: _server.RequestError,
17
+ parseUrl: _tools.parseUrl,
18
+ redactUrl: _tools.redactUrl,
19
+ redactParsedUrl: _tools.redactParsedUrl,
20
+ anonymizeProxy: _anonymize_proxy.anonymizeProxy,
21
+ closeAnonymizedProxy: _anonymize_proxy.closeAnonymizedProxy,
22
+ createTunnel: _tcp_tunnel.createTunnel,
23
+ closeTunnel: _tcp_tunnel.closeTunnel
24
+ };
25
+
26
+ module.exports = ProxyChain;
@@ -0,0 +1,66 @@
1
+ 'use strict';
2
+
3
+ var _http = require('http');
4
+
5
+ var _http2 = _interopRequireDefault(_http);
6
+
7
+ var _proxy = require('proxy');
8
+
9
+ var _proxy2 = _interopRequireDefault(_proxy);
10
+
11
+ var _server = require('./server');
12
+
13
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
+
15
+ // Set up upstream proxy with no auth
16
+ var upstreamProxyHttpServer = _http2.default.createServer(); // eslint-disable-line import/no-extraneous-dependencies
17
+ /*!
18
+ * This script runs the proxy with a second upstream proxy locally on port specified by PORT environment variable
19
+ * or 8080 if not provided. This is used to manually test the proxy on normal browsing.
20
+ *
21
+ * node ./build/run_locally.js
22
+ *
23
+ * Author: Jan Curn (jan@apify.com)
24
+ * Copyright(c) 2017 Apify Technologies. All rights reserved.
25
+ *
26
+ */
27
+
28
+ upstreamProxyHttpServer.on('error', function (err) {
29
+ console.error(err.stack || err);
30
+ });
31
+
32
+ var upstreamProxyServer = (0, _proxy2.default)(upstreamProxyHttpServer);
33
+ var upstreamProxyPort = process.env.UPSTREAM_PROXY_PORT || 8081;
34
+ upstreamProxyServer.listen(process.env.UPSTREAM_PROXY_PORT || 8081, function (err) {
35
+ if (err) {
36
+ console.error(err.stack || err);
37
+ process.exit(1);
38
+ }
39
+ });
40
+
41
+ // Setup proxy to forward to upstream
42
+ var server = new _server.Server({
43
+ port: process.env.PORT || 8080,
44
+ // verbose: true,
45
+ prepareRequestFunction: function prepareRequestFunction() {
46
+ return { requestAuthentication: false, upstreamProxyUrl: 'http://127.0.0.1:' + upstreamProxyPort };
47
+ }
48
+ });
49
+
50
+ server.on('requestFailed', function (_ref) {
51
+ var error = _ref.error,
52
+ request = _ref.request;
53
+
54
+ console.error('Request failed (' + (request ? request.url : 'N/A') + '): ' + (error.stack || error));
55
+ });
56
+
57
+ server.listen().then(function () {
58
+ console.log('Proxy server is running at http://127.0.0.1:' + server.port);
59
+
60
+ setInterval(function () {
61
+ console.log('Stats: ' + JSON.stringify(server.stats));
62
+ }, 30000);
63
+ }).catch(function (err) {
64
+ console.error(err.stack || err);
65
+ process.exit(1);
66
+ });
@@ -0,0 +1,595 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Server = exports.RequestError = undefined;
7
+
8
+ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
9
+
10
+ var _http = require('http');
11
+
12
+ var _http2 = _interopRequireDefault(_http);
13
+
14
+ var _events = require('events');
15
+
16
+ var _events2 = _interopRequireDefault(_events);
17
+
18
+ var _underscore = require('underscore');
19
+
20
+ var _underscore2 = _interopRequireDefault(_underscore);
21
+
22
+ var _bluebird = require('bluebird');
23
+
24
+ var _bluebird2 = _interopRequireDefault(_bluebird);
25
+
26
+ var _tools = require('./tools');
27
+
28
+ var _handler_forward = require('./handler_forward');
29
+
30
+ var _handler_forward2 = _interopRequireDefault(_handler_forward);
31
+
32
+ var _handler_tunnel_direct = require('./handler_tunnel_direct');
33
+
34
+ var _handler_tunnel_direct2 = _interopRequireDefault(_handler_tunnel_direct);
35
+
36
+ var _handler_tunnel_chain = require('./handler_tunnel_chain');
37
+
38
+ var _handler_tunnel_chain2 = _interopRequireDefault(_handler_tunnel_chain);
39
+
40
+ var _handler_custom_response = require('./handler_custom_response');
41
+
42
+ var _handler_custom_response2 = _interopRequireDefault(_handler_custom_response);
43
+
44
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
45
+
46
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
47
+
48
+ function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
49
+
50
+ 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; }
51
+
52
+ // TODO:
53
+ // - Fail gracefully if target proxy fails (invalid credentials or non-existent)
54
+ // - Implement this requirement from rfc7230
55
+ // "A proxy MUST forward unrecognized header fields unless the field-name
56
+ // is listed in the Connection header field (Section 6.1) or the proxy
57
+ // is specifically configured to block, or otherwise transform, such
58
+ // fields. Other recipients SHOULD ignore unrecognized header fields.
59
+ // These requirements allow HTTP's functionality to be enhanced without
60
+ // requiring prior update of deployed intermediaries."
61
+ // - Add param to prepareRequestFunction() that would allow the caller to kill a connection
62
+
63
+ // TODO:
64
+ // - Use connection pooling and maybe other stuff from:
65
+ // https://github.com/request/tunnel-agent/blob/master/index.js
66
+ // https://github.com/request/request/blob/master/lib/tunnel.js
67
+
68
+ var DEFAULT_AUTH_REALM = 'ProxyChain';
69
+ var DEFAULT_PROXY_SERVER_PORT = 8000;
70
+ var DEFAULT_TARGET_PORT = 80;
71
+
72
+ var REQUEST_ERROR_NAME = 'RequestError';
73
+
74
+ /**
75
+ * Represents custom request error. The message is emitted as HTTP response
76
+ * with a specific HTTP code and headers.
77
+ * If this error is thrown from the `prepareRequestFunction` function,
78
+ * the message and status code is sent to client.
79
+ * By default, the response will have Content-Type: text/plain
80
+ * and for the 407 status the Proxy-Authenticate header will be added.
81
+ */
82
+
83
+ var RequestError = exports.RequestError = function (_Error) {
84
+ _inherits(RequestError, _Error);
85
+
86
+ function RequestError(message, statusCode, headers) {
87
+ _classCallCheck(this, RequestError);
88
+
89
+ var _this = _possibleConstructorReturn(this, (RequestError.__proto__ || Object.getPrototypeOf(RequestError)).call(this, message));
90
+
91
+ _this.name = REQUEST_ERROR_NAME;
92
+ _this.statusCode = statusCode;
93
+ _this.headers = headers;
94
+
95
+ Error.captureStackTrace(_this, RequestError);
96
+ return _this;
97
+ }
98
+
99
+ return RequestError;
100
+ }(Error);
101
+
102
+ /**
103
+ * Represents the proxy server.
104
+ * It emits the 'requestFailed' event on unexpected request errors, with the following parameter `{ error, request }`.
105
+ * It emits the 'connectionClosed' event when connection to proxy server is closed, with parameter `{ connectionId, stats }`.
106
+ */
107
+
108
+
109
+ var Server = exports.Server = function (_EventEmitter) {
110
+ _inherits(Server, _EventEmitter);
111
+
112
+ /**
113
+ * Initializes a new instance of Server class.
114
+ * @param options
115
+ * @param [options.port] Port where the server will listen. By default 8000.
116
+ * @param [options.prepareRequestFunction] Custom function to authenticate proxy requests,
117
+ * provide URL to chained upstream proxy or potentially provide function that generates a custom response to HTTP requests.
118
+ * It accepts a single parameter which is an object:
119
+ * ```{
120
+ * connectionId: Number,
121
+ * request: Object,
122
+ * username: String,
123
+ * password: String,
124
+ * hostname: String,
125
+ * port: Number,
126
+ * isHttp: Boolean
127
+ * }```
128
+ * and returns an object (or promise resolving to the object) with following form:
129
+ * ```{
130
+ * requestAuthentication: Boolean,
131
+ * upstreamProxyUrl: String,
132
+ * customResponseFunction: Function
133
+ * }```
134
+ * If `upstreamProxyUrl` is false-ish value, no upstream proxy is used.
135
+ * If `prepareRequestFunction` is not set, the proxy server will not require any authentication
136
+ * and will not use any upstream proxy.
137
+ * If `customResponseFunction` is set, it will be called to generate a custom response to the HTTP request.
138
+ * It should not be used together with `upstreamProxyUrl`.
139
+ * @param [options.authRealm] Realm used in the Proxy-Authenticate header and also in the 'Server' HTTP header. By default it's `ProxyChain`.
140
+ * @param [options.verbose] If true, the server logs
141
+ */
142
+ function Server(options) {
143
+ _classCallCheck(this, Server);
144
+
145
+ var _this2 = _possibleConstructorReturn(this, (Server.__proto__ || Object.getPrototypeOf(Server)).call(this));
146
+
147
+ options = options || {};
148
+
149
+ _this2.port = options.port || DEFAULT_PROXY_SERVER_PORT;
150
+ _this2.prepareRequestFunction = options.prepareRequestFunction;
151
+ _this2.authRealm = options.authRealm || DEFAULT_AUTH_REALM;
152
+ _this2.verbose = !!options.verbose;
153
+
154
+ // Key is handler ID, value is HandlerXxx instance
155
+ _this2.handlers = {};
156
+ _this2.lastHandlerId = 0;
157
+
158
+ _this2.server = _http2.default.createServer();
159
+ _this2.server.on('clientError', _this2.onClientError.bind(_this2));
160
+ _this2.server.on('request', _this2.onRequest.bind(_this2));
161
+ _this2.server.on('connect', _this2.onConnect.bind(_this2));
162
+
163
+ _this2.stats = {
164
+ httpRequestCount: 0,
165
+ connectRequestCount: 0
166
+ };
167
+ return _this2;
168
+ }
169
+
170
+ _createClass(Server, [{
171
+ key: 'log',
172
+ value: function log(handlerId, str) {
173
+ if (this.verbose) {
174
+ var logPrefix = handlerId ? handlerId + ' | ' : '';
175
+ console.log('Server[' + this.port + ']: ' + logPrefix + str);
176
+ }
177
+ }
178
+ }, {
179
+ key: 'onClientError',
180
+ value: function onClientError(err, socket) {
181
+ this.log(null, 'onClientError: ' + err);
182
+ this.sendResponse(socket, 400, null, 'Invalid request');
183
+ }
184
+
185
+ /**
186
+ * Handles normal HTTP request by forwarding it to target host or the upstream proxy.
187
+ */
188
+
189
+ }, {
190
+ key: 'onRequest',
191
+ value: function onRequest(request, response) {
192
+ var _this3 = this;
193
+
194
+ var handlerOpts = void 0;
195
+ this.prepareRequestHandling(request).then(function (result) {
196
+ handlerOpts = result;
197
+ handlerOpts.srcResponse = response;
198
+
199
+ var handler = void 0;
200
+ if (handlerOpts.customResponseFunction) {
201
+ _this3.log(handlerOpts.id, 'Using HandlerCustomResponse');
202
+ handler = new _handler_custom_response2.default(handlerOpts);
203
+ } else {
204
+ _this3.log(handlerOpts.id, 'Using HandlerForward');
205
+ handler = new _handler_forward2.default(handlerOpts);
206
+ }
207
+
208
+ _this3.handlerRun(handler);
209
+ }).catch(function (err) {
210
+ _this3.failRequest(request, err, handlerOpts);
211
+ });
212
+ }
213
+
214
+ /**
215
+ * Handles HTTP CONNECT request by setting up a tunnel either to target host or to the upstream proxy.
216
+ * @param request
217
+ * @param socket
218
+ * @param head The first packet of the tunneling stream (may be empty)
219
+ */
220
+
221
+ }, {
222
+ key: 'onConnect',
223
+ value: function onConnect(request, socket, head) {
224
+ var _this4 = this;
225
+
226
+ var handlerOpts = void 0;
227
+ this.prepareRequestHandling(request).then(function (result) {
228
+ handlerOpts = result;
229
+ handlerOpts.srcHead = head;
230
+
231
+ var handler = void 0;
232
+ if (handlerOpts.upstreamProxyUrlParsed) {
233
+ _this4.log(handlerOpts.id, 'Using HandlerTunnelChain');
234
+ handler = new _handler_tunnel_chain2.default(handlerOpts);
235
+ } else {
236
+ _this4.log(handlerOpts.id, 'Using HandlerTunnelDirect');
237
+ handler = new _handler_tunnel_direct2.default(handlerOpts);
238
+ }
239
+
240
+ _this4.handlerRun(handler);
241
+ }).catch(function (err) {
242
+ _this4.failRequest(request, err, handlerOpts);
243
+ });
244
+ }
245
+
246
+ /**
247
+ * Authenticates a new request and determines upstream proxy URL using the user function.
248
+ * Returns a promise resolving to an object that can be passed to construcot of one of the HandlerXxx classes.
249
+ * @param request
250
+ */
251
+
252
+ }, {
253
+ key: 'prepareRequestHandling',
254
+ value: function prepareRequestHandling(request) {
255
+ var _this5 = this;
256
+
257
+ // console.log('XXX prepareRequestHandling');
258
+ // console.dir(_.pick(request, 'url', 'method'));
259
+ // console.dir(url.parse(request.url));
260
+
261
+ var handlerOpts = {
262
+ server: this,
263
+ id: ++this.lastHandlerId,
264
+ srcRequest: request,
265
+ srcHead: null,
266
+ trgParsed: null,
267
+ upstreamProxyUrlParsed: null
268
+ };
269
+
270
+ this.log(handlerOpts.id, '!!! Handling ' + request.method + ' ' + request.url + ' HTTP/' + request.httpVersion);
271
+
272
+ var socket = request.socket;
273
+ var isHttp = false;
274
+
275
+ return _bluebird2.default.resolve().then(function () {
276
+ // console.dir(_.pick(request, 'url', 'headers', 'method'));
277
+ // Determine target hostname and port
278
+ if (request.method === 'CONNECT') {
279
+ // The request should look like:
280
+ // CONNECT server.example.com:80 HTTP/1.1
281
+ // Note that request.url contains the "server.example.com:80" part
282
+ handlerOpts.trgParsed = (0, _tools.parseHostHeader)(request.url);
283
+
284
+ // If srcRequest.url does not match the regexp tools.HOST_HEADER_REGEX
285
+ // or the url is too long it will not be parsed so we throw error here.
286
+ if (!handlerOpts.trgParsed) {
287
+ throw new RequestError('Target "' + request.url + '" could not be parsed', 400);
288
+ }
289
+
290
+ _this5.stats.connectRequestCount++;
291
+ } else {
292
+ // The request should look like:
293
+ // GET http://server.example.com:80/some-path HTTP/1.1
294
+ // Note that RFC 7230 says:
295
+ // "When making a request to a proxy, other than a CONNECT or server-wide
296
+ // OPTIONS request (as detailed below), a client MUST send the target
297
+ // URI in absolute-form as the request-target"
298
+ var parsed = (0, _tools.parseUrl)(request.url);
299
+
300
+ // If srcRequest.url does not match the regexp tools.HOST_HEADER_REGEX
301
+ // or the url is too long it will not be parsed so we throw error here.
302
+ if (!parsed) {
303
+ throw new RequestError('Target "' + request.url + '" could not be parsed', 400);
304
+ }
305
+
306
+ // If srcRequest.url is something like '/some-path', this is most likely a normal HTTP request
307
+ if (!parsed.protocol) {
308
+ throw new RequestError('Hey, good try, but I\'m a HTTP proxy, not your ordinary web server :)', 400);
309
+ }
310
+ // Only HTTP is supported, other protocols such as HTTP or FTP must use the CONNECT method
311
+ if (parsed.protocol !== 'http:') {
312
+ throw new RequestError('Only HTTP protocol is supported (was ' + parsed.protocol + ')', 400);
313
+ }
314
+
315
+ handlerOpts.trgParsed = parsed;
316
+ isHttp = true;
317
+
318
+ _this5.stats.httpRequestCount++;
319
+ }
320
+
321
+ handlerOpts.trgParsed.port = handlerOpts.trgParsed.port || DEFAULT_TARGET_PORT;
322
+
323
+ // Authenticate the request using a user function (if provided)
324
+ if (!_this5.prepareRequestFunction) return { requestAuthentication: false, upstreamProxyUrlParsed: null };
325
+
326
+ // Pause the socket so that no data is lost
327
+ socket.pause();
328
+
329
+ var funcOpts = {
330
+ connectionId: handlerOpts.id,
331
+ request: request,
332
+ username: null,
333
+ password: null,
334
+ hostname: handlerOpts.trgParsed.hostname,
335
+ port: handlerOpts.trgParsed.port,
336
+ isHttp: isHttp
337
+ };
338
+
339
+ var proxyAuth = request.headers['proxy-authorization'];
340
+ if (proxyAuth) {
341
+ var auth = (0, _tools.parseProxyAuthorizationHeader)(proxyAuth);
342
+ if (!auth) {
343
+ throw new RequestError('Invalid "Proxy-Authorization" header', 400);
344
+ }
345
+ if (auth.type !== 'Basic') {
346
+ throw new RequestError('The "Proxy-Authorization" header must have the "Basic" type.', 400);
347
+ }
348
+ funcOpts.username = auth.username;
349
+ funcOpts.password = auth.password;
350
+ }
351
+
352
+ // User function returns a result directly or a promise
353
+ return _this5.prepareRequestFunction(funcOpts);
354
+ }).then(function (funcResult) {
355
+ // If not authenticated, request client to authenticate
356
+ if (funcResult && funcResult.requestAuthentication) {
357
+ throw new RequestError(funcResult.failMsg || 'Proxy credentials required.', 407);
358
+ }
359
+
360
+ if (funcResult && funcResult.upstreamProxyUrl) {
361
+ handlerOpts.upstreamProxyUrlParsed = (0, _tools.parseUrl)(funcResult.upstreamProxyUrl);
362
+
363
+ if (handlerOpts.upstreamProxyUrlParsed) {
364
+ if (!handlerOpts.upstreamProxyUrlParsed.hostname || !handlerOpts.upstreamProxyUrlParsed.port) {
365
+ throw new Error('Invalid "upstreamProxyUrl" provided: URL must have hostname and port');
366
+ }
367
+ if (handlerOpts.upstreamProxyUrlParsed.scheme !== 'http') {
368
+ throw new Error('Invalid "upstreamProxyUrl" provided: URL must have the "http" scheme');
369
+ }
370
+ }
371
+ }
372
+
373
+ if (funcResult && funcResult.customResponseFunction) {
374
+ _this5.log(handlerOpts.id, 'Using custom response function');
375
+ handlerOpts.customResponseFunction = funcResult.customResponseFunction;
376
+ if (!isHttp) {
377
+ throw new Error('The "customResponseFunction" option can only be used for HTTP requests.');
378
+ }
379
+ if (typeof handlerOpts.customResponseFunction !== 'function') {
380
+ throw new Error('The "customResponseFunction" option must be a function.');
381
+ }
382
+ }
383
+
384
+ if (handlerOpts.upstreamProxyUrlParsed) {
385
+ _this5.log(handlerOpts.id, 'Using upstream proxy ' + (0, _tools.redactParsedUrl)(handlerOpts.upstreamProxyUrlParsed));
386
+ }
387
+
388
+ return handlerOpts;
389
+ }).finally(function () {
390
+ if (_this5.prepareRequestFunction) socket.resume();
391
+ });
392
+ }
393
+ }, {
394
+ key: 'handlerRun',
395
+ value: function handlerRun(handler) {
396
+ var _this6 = this;
397
+
398
+ this.handlers[handler.id] = handler;
399
+
400
+ handler.once('close', function (_ref) {
401
+ var stats = _ref.stats;
402
+
403
+ _this6.emit('connectionClosed', {
404
+ connectionId: handler.id,
405
+ stats: stats
406
+ });
407
+ delete _this6.handlers[handler.id];
408
+ _this6.log(handler.id, '!!! Closed and removed from server');
409
+ });
410
+
411
+ handler.run();
412
+ }
413
+
414
+ /**
415
+ * Sends a HTTP error response to the client.
416
+ * @param request
417
+ * @param err
418
+ */
419
+
420
+ }, {
421
+ key: 'failRequest',
422
+ value: function failRequest(request, err, handlerOpts) {
423
+ var handlerId = handlerOpts ? handlerOpts.id : null;
424
+
425
+ if (err.name === REQUEST_ERROR_NAME) {
426
+ this.log(handlerId, 'Request failed (status ' + err.statusCode + '): ' + err.message);
427
+ this.sendResponse(request.socket, err.statusCode, err.headers, err.message);
428
+ } else {
429
+ this.log(handlerId, 'Request failed with unknown error: ' + (err.stack || err));
430
+ this.sendResponse(request.socket, 500, null, 'Internal error in proxy server');
431
+ this.emit('requestFailed', { error: err, request: request });
432
+ }
433
+
434
+ // emit connection closed if request fails and connection was already reported
435
+ if (handlerOpts) {
436
+ this.log(handlerId, 'Closed because request failed with error');
437
+ this.emit('connectionClosed', {
438
+ connectionId: handlerOpts.id,
439
+ stats: { srcTxBytes: 0, srcRxBytes: 0 }
440
+ });
441
+ }
442
+ }
443
+
444
+ /**
445
+ * Sends a simple HTTP response to the client and forcibly closes the connection.
446
+ * @param socket
447
+ * @param statusCode
448
+ * @param headers
449
+ * @param message
450
+ */
451
+
452
+ }, {
453
+ key: 'sendResponse',
454
+ value: function sendResponse(socket, statusCode, headers, message) {
455
+ try {
456
+ headers = headers || {};
457
+
458
+ if (!headers['Content-Type']) {
459
+ headers['Content-Type'] = 'text/html; charset=utf-8';
460
+ }
461
+ if (statusCode === 407 && !headers['Proxy-Authenticate']) {
462
+ headers['Proxy-Authenticate'] = 'Basic realm="' + this.authRealm + '"';
463
+ }
464
+ if (!headers.Server) {
465
+ headers.Server = this.authRealm;
466
+ }
467
+ // These headers are required by PhantomJS, otherwise the connection would timeout!
468
+ if (!headers.Connection) {
469
+ headers.Connection = 'close';
470
+ }
471
+ if (!headers['Content-Length']) {
472
+ headers['Content-Length'] = Buffer.byteLength(message);
473
+ }
474
+
475
+ var msg = 'HTTP/1.1 ' + statusCode + ' ' + _http2.default.STATUS_CODES[statusCode] + '\r\n';
476
+ _underscore2.default.each(headers, function (value, key) {
477
+ msg += key + ': ' + value + '\r\n';
478
+ });
479
+ msg += '\r\n' + message;
480
+
481
+ // console.log("RESPONSE:\n" + msg);
482
+
483
+ socket.write(msg, function () {
484
+ socket.end();
485
+
486
+ // Unfortunately calling end() will not close the socket
487
+ // if client refuses to close it. Hence calling destroy after a short while.
488
+ setTimeout(function () {
489
+ socket.destroy();
490
+ }, 100);
491
+ });
492
+ } catch (err) {
493
+ this.log(null, 'Unhandled error in sendResponse(), will be ignored: ' + (err.stack || err));
494
+ }
495
+ }
496
+
497
+ /**
498
+ * Starts listening at a port specified in the constructor.
499
+ * @param callback Optional callback
500
+ * @return {*}
501
+ */
502
+
503
+ }, {
504
+ key: 'listen',
505
+ value: function listen(callback) {
506
+ var _this7 = this;
507
+
508
+ return new _bluebird2.default(function (resolve, reject) {
509
+ // Unfortunately server.listen() is not a normal function that fails on error,
510
+ // so we need this trickery
511
+ var onError = function onError(err) {
512
+ _this7.log(null, 'Listen failed: ' + err);
513
+ removeListeners();
514
+ reject(err);
515
+ };
516
+ var onListening = function onListening() {
517
+ _this7.log(null, 'Listening...');
518
+ removeListeners();
519
+ resolve();
520
+ };
521
+ var removeListeners = function removeListeners() {
522
+ _this7.server.removeListener('error', onError);
523
+ _this7.server.removeListener('listening', onListening);
524
+ };
525
+
526
+ _this7.server.on('error', onError);
527
+ _this7.server.on('listening', onListening);
528
+ _this7.server.listen(_this7.port);
529
+ }).nodeify(callback);
530
+ }
531
+
532
+ /**
533
+ * Gets array of IDs of all active connections.
534
+ * @returns {*}
535
+ */
536
+
537
+ }, {
538
+ key: 'getConnectionIds',
539
+ value: function getConnectionIds() {
540
+ return _underscore2.default.keys(this.handlers);
541
+ }
542
+
543
+ /**
544
+ * Gets data transfer statistics of a specific proxy connection.
545
+ * @param {Number} connectionId ID of the connection handler.
546
+ * It is passed to `prepareRequestFunction` function.
547
+ * @return {Object} An object with statistics { srcTxBytes, srcRxBytes, trgTxBytes, trgRxBytes },
548
+ * or null if connection does not exist or has been closed.
549
+ */
550
+
551
+ }, {
552
+ key: 'getConnectionStats',
553
+ value: function getConnectionStats(connectionId) {
554
+ var handler = this.handlers && this.handlers[connectionId];
555
+ if (!handler) return undefined;
556
+
557
+ return handler.getStats();
558
+ }
559
+
560
+ /**
561
+ * Closes the proxy server.
562
+ * @param [closeConnections] If true, then all the pending connections from clients
563
+ * to targets and upstream proxies will be forcibly aborted.
564
+ * @param callback
565
+ */
566
+
567
+ }, {
568
+ key: 'close',
569
+ value: function close(closeConnections, callback) {
570
+ if (typeof closeConnections === 'function') {
571
+ callback = closeConnections;
572
+ closeConnections = false;
573
+ }
574
+
575
+ if (closeConnections) {
576
+ this.log(null, 'Closing pending handlers');
577
+ var count = 0;
578
+ _underscore2.default.each(this.handlers, function (handler) {
579
+ count++;
580
+ handler.close();
581
+ });
582
+ this.log(null, 'Destroyed ' + count + ' pending handlers');
583
+ }
584
+
585
+ // TODO: keep track of all handlers and close them if closeConnections=true
586
+ if (this.server) {
587
+ var server = this.server;
588
+ this.server = null;
589
+ return _bluebird2.default.promisify(server.close).bind(server)().nodeify(callback);
590
+ }
591
+ }
592
+ }]);
593
+
594
+ return Server;
595
+ }(_events2.default);