Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

createGlobalProxyAgent.js.flow 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. // @flow
  2. import http from 'http';
  3. import https from 'https';
  4. import {
  5. boolean as parseBoolean,
  6. } from 'boolean';
  7. import semver from 'semver';
  8. import Logger from '../Logger';
  9. import {
  10. HttpProxyAgent,
  11. HttpsProxyAgent,
  12. } from '../classes';
  13. import {
  14. UnexpectedStateError,
  15. } from '../errors';
  16. import {
  17. bindHttpMethod,
  18. isUrlMatchingNoProxy,
  19. parseProxyUrl,
  20. } from '../utilities';
  21. import type {
  22. ProxyAgentConfigurationInputType,
  23. ProxyAgentConfigurationType,
  24. } from '../types';
  25. import createProxyController from './createProxyController';
  26. const httpGet = http.get;
  27. const httpRequest = http.request;
  28. const httpsGet = https.get;
  29. const httpsRequest = https.request;
  30. const log = Logger.child({
  31. namespace: 'createGlobalProxyAgent',
  32. });
  33. const defaultConfigurationInput = {
  34. environmentVariableNamespace: undefined,
  35. forceGlobalAgent: undefined,
  36. socketConnectionTimeout: 60000,
  37. };
  38. const omitUndefined = (subject) => {
  39. const keys = Object.keys(subject);
  40. const result = {};
  41. for (const key of keys) {
  42. const value = subject[key];
  43. if (value !== undefined) {
  44. result[key] = value;
  45. }
  46. }
  47. return result;
  48. };
  49. const createConfiguration = (configurationInput: ProxyAgentConfigurationInputType): ProxyAgentConfigurationType => {
  50. // eslint-disable-next-line no-process-env
  51. const environment = process.env;
  52. const defaultConfiguration = {
  53. environmentVariableNamespace: typeof environment.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE === 'string' ? environment.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE : 'GLOBAL_AGENT_',
  54. forceGlobalAgent: typeof environment.GLOBAL_AGENT_FORCE_GLOBAL_AGENT === 'string' ? parseBoolean(environment.GLOBAL_AGENT_FORCE_GLOBAL_AGENT) : true,
  55. socketConnectionTimeout: typeof environment.GLOBAL_AGENT_SOCKET_CONNECTION_TIMEOUT === 'string' ? Number.parseInt(environment.GLOBAL_AGENT_SOCKET_CONNECTION_TIMEOUT, 10) : defaultConfigurationInput.socketConnectionTimeout,
  56. };
  57. // $FlowFixMe
  58. return {
  59. ...defaultConfiguration,
  60. ...omitUndefined(configurationInput),
  61. };
  62. };
  63. export default (configurationInput: ProxyAgentConfigurationInputType = defaultConfigurationInput) => {
  64. const configuration = createConfiguration(configurationInput);
  65. const proxyController = createProxyController();
  66. // eslint-disable-next-line no-process-env
  67. proxyController.HTTP_PROXY = process.env[configuration.environmentVariableNamespace + 'HTTP_PROXY'] || null;
  68. // eslint-disable-next-line no-process-env
  69. proxyController.HTTPS_PROXY = process.env[configuration.environmentVariableNamespace + 'HTTPS_PROXY'] || null;
  70. // eslint-disable-next-line no-process-env
  71. proxyController.NO_PROXY = process.env[configuration.environmentVariableNamespace + 'NO_PROXY'] || null;
  72. log.info({
  73. configuration,
  74. state: proxyController,
  75. }, 'global agent has been initialized');
  76. const mustUrlUseProxy = (getProxy) => {
  77. return (url) => {
  78. if (!getProxy()) {
  79. return false;
  80. }
  81. if (!proxyController.NO_PROXY) {
  82. return true;
  83. }
  84. return !isUrlMatchingNoProxy(url, proxyController.NO_PROXY);
  85. };
  86. };
  87. const getUrlProxy = (getProxy) => {
  88. return () => {
  89. const proxy = getProxy();
  90. if (!proxy) {
  91. throw new UnexpectedStateError('HTTP(S) proxy must be configured.');
  92. }
  93. return parseProxyUrl(proxy);
  94. };
  95. };
  96. const getHttpProxy = () => {
  97. return proxyController.HTTP_PROXY;
  98. };
  99. const BoundHttpProxyAgent = class extends HttpProxyAgent {
  100. constructor () {
  101. super(
  102. () => {
  103. return getHttpProxy();
  104. },
  105. mustUrlUseProxy(getHttpProxy),
  106. getUrlProxy(getHttpProxy),
  107. http.globalAgent,
  108. configuration.socketConnectionTimeout,
  109. );
  110. }
  111. };
  112. const httpAgent = new BoundHttpProxyAgent();
  113. const getHttpsProxy = () => {
  114. return proxyController.HTTPS_PROXY || proxyController.HTTP_PROXY;
  115. };
  116. const BoundHttpsProxyAgent = class extends HttpsProxyAgent {
  117. constructor () {
  118. super(
  119. () => {
  120. return getHttpsProxy();
  121. },
  122. mustUrlUseProxy(getHttpsProxy),
  123. getUrlProxy(getHttpsProxy),
  124. https.globalAgent,
  125. configuration.socketConnectionTimeout,
  126. );
  127. }
  128. };
  129. const httpsAgent = new BoundHttpsProxyAgent();
  130. // Overriding globalAgent was added in v11.7.
  131. // @see https://nodejs.org/uk/blog/release/v11.7.0/
  132. if (semver.gte(process.version, 'v11.7.0')) {
  133. // @see https://github.com/facebook/flow/issues/7670
  134. // $FlowFixMe
  135. http.globalAgent = httpAgent;
  136. // $FlowFixMe
  137. https.globalAgent = httpsAgent;
  138. }
  139. // The reason this logic is used in addition to overriding http(s).globalAgent
  140. // is because there is no guarantee that we set http(s).globalAgent variable
  141. // before an instance of http(s).Agent has been already constructed by someone,
  142. // e.g. Stripe SDK creates instances of http(s).Agent at the top-level.
  143. // @see https://github.com/gajus/global-agent/pull/13
  144. //
  145. // We still want to override http(s).globalAgent when possible to enable logic
  146. // in `bindHttpMethod`.
  147. if (semver.gte(process.version, 'v10.0.0')) {
  148. // $FlowFixMe
  149. http.get = bindHttpMethod(httpGet, httpAgent, configuration.forceGlobalAgent);
  150. // $FlowFixMe
  151. http.request = bindHttpMethod(httpRequest, httpAgent, configuration.forceGlobalAgent);
  152. // $FlowFixMe
  153. https.get = bindHttpMethod(httpsGet, httpsAgent, configuration.forceGlobalAgent);
  154. // $FlowFixMe
  155. https.request = bindHttpMethod(httpsRequest, httpsAgent, configuration.forceGlobalAgent);
  156. } else {
  157. log.warn('attempt to initialize global-agent in unsupported Node.js version was ignored');
  158. }
  159. return proxyController;
  160. };