com.jimuwd.xian.registry-proxy 1.0.110 → 1.0.112

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.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { Server as HttpServer } from 'node:http';
3
3
  import { Server as HttpsServer } from 'node:https';
4
- export declare function startProxyServer(proxyConfigPath?: string, localYarnConfigPath?: string, globalYarnConfigPath?: string, port?: number): Promise<HttpServer | HttpsServer>;
4
+ export declare function startProxyServer(proxyConfigPath?: string, localYarnConfigPath?: string, globalYarnConfigPath?: string, port?: number): Promise<{
5
+ serverIpv6: HttpServer | HttpsServer;
6
+ serverIpv4: HttpServer | HttpsServer;
7
+ }>;
package/dist/index.js CHANGED
@@ -299,6 +299,7 @@ function getDownstreamClientIp(req) {
299
299
  // 直接连接时,取 socket.remoteAddress
300
300
  return req.socket.remoteAddress;
301
301
  }
302
+ // 同时启动ipv6,ipv4监听,比如当客户端访问http://localhost:port时,无论客户端DNS解析到IPV4-127.0.0.1还是IPV6-::1地址,咱server都能轻松应对!
302
303
  export async function startProxyServer(proxyConfigPath, localYarnConfigPath, globalYarnConfigPath, port = 0) {
303
304
  const proxyInfo = await loadProxyInfo(proxyConfigPath, localYarnConfigPath, globalYarnConfigPath);
304
305
  const registryInfos = proxyInfo.registries;
@@ -306,6 +307,7 @@ export async function startProxyServer(proxyConfigPath, localYarnConfigPath, glo
306
307
  logger.info('Active registries:', registryInfos.map(r => r.normalizedRegistryUrl));
307
308
  logger.info('Proxy base path:', basePathPrefixedWithSlash);
308
309
  logger.info('HTTPS:', !!proxyInfo.https);
310
+ // the real port server is listening on if configured port is empty or 0
309
311
  let proxyPort;
310
312
  const requestHandler = async (reqFromDownstreamClient, resToDownstreamClient) => {
311
313
  const downstreamUserAgent = reqFromDownstreamClient.headers["user-agent"]; // "curl/x.x.x"
@@ -358,7 +360,9 @@ export async function startProxyServer(proxyConfigPath, localYarnConfigPath, glo
358
360
  resToDownstreamClient.writeHead(404).end('All upstream registries failed');
359
361
  }
360
362
  };
361
- let server;
363
+ // 同时启动ipv6,ipv4监听,比如当客户端访问http://localhost:port时,无论客户端DNS解析到IPV4-127.0.0.1还是IPV6-::1地址,咱server都能轻松应对!
364
+ let serverIpv6;
365
+ let serverIpv4;
362
366
  if (proxyInfo.https) {
363
367
  const { key, cert } = proxyInfo.https;
364
368
  const keyPath = resolvePath(key);
@@ -375,40 +379,57 @@ export async function startProxyServer(proxyConfigPath, localYarnConfigPath, glo
375
379
  key: readFileSync(keyPath),
376
380
  cert: readFileSync(certPath),
377
381
  };
378
- server = createHttpsServer(httpsOptions, requestHandler);
382
+ serverIpv6 = createHttpsServer(httpsOptions, requestHandler);
383
+ serverIpv4 = createHttpsServer(httpsOptions, requestHandler);
379
384
  logger.info("Proxy server's maxSockets is", https.globalAgent.maxSockets);
380
385
  }
381
386
  else {
382
- server = createServer(requestHandler);
387
+ serverIpv6 = createServer(requestHandler);
388
+ serverIpv4 = createServer(requestHandler);
383
389
  logger.info("Proxy server's maxSockets is", http.globalAgent.maxSockets);
384
390
  }
385
- logger.info(`Proxy server's initial maxConnections is ${server.maxConnections}, adjusting to 10000`);
386
- server.maxConnections = 10000;
387
- logger.info(`Proxy server's initial timeout is ${server.timeout}, adjusting to 60000ms`);
388
- server.timeout = 60000;
391
+ // server参数暂时写死
392
+ const serverMaxConnections = 10000;
393
+ const serverTimeoutMs = 60000;
394
+ logger.info(`Proxy server's initial maxConnections is ${serverIpv4.maxConnections}, adjusting to ${serverMaxConnections}`);
395
+ serverIpv6.maxConnections = serverMaxConnections;
396
+ serverIpv4.maxConnections = serverMaxConnections;
397
+ logger.info(`Proxy server's initial timeout is ${serverIpv4.timeout}, adjusting to ${serverTimeoutMs}ms`);
398
+ serverIpv6.timeout = serverTimeoutMs;
399
+ serverIpv4.timeout = serverTimeoutMs;
389
400
  const promisedServer = new Promise((resolve, reject) => {
390
- server.on('error', (err) => {
401
+ const errHandler = (err) => {
391
402
  if (err.code === 'EADDRINUSE') {
392
- logger.error(`Port ${port} is in use, please specify a different port or free it.`);
403
+ logger.error(`Port ${port} is in use, please specify a different port or free it.`, err);
393
404
  process.exit(1);
394
405
  }
395
406
  logger.error('Server error:', err);
396
407
  reject(err);
397
- });
398
- server.on('connection', (socket) => {
408
+ };
409
+ const connectionHandler = (socket) => {
399
410
  logger.info("Server on connection");
400
411
  socket.setTimeout(60000);
401
412
  socket.setKeepAlive(true, 30000);
402
- });
403
- // ipv4和ipv6双栈支持
404
- server.listen(port, '::', () => {
405
- const address = server.address();
406
- proxyPort = address.port;
413
+ };
414
+ // 嵌套的回调函数,在ipv6监听器启动之后会被回调调用
415
+ const nestedListener = () => {
407
416
  const portFile = join(process.env.PROJECT_ROOT || process.cwd(), '.registry-proxy-port');
408
- writeFile(portFile, proxyPort.toString()).catch(e => logger.error('Failed to write port file:', e));
409
- logger.info(`Proxy server running on ${proxyInfo.https ? 'https' : 'http'}://127.0.0.1:${proxyPort}${basePathPrefixedWithSlash === '/' ? '' : basePathPrefixedWithSlash}`);
410
- resolve(server);
411
- });
417
+ writeFile(portFile, proxyPort.toString()).catch(e => logger.error(`Failed to write port file: ${portFile}`, e));
418
+ logger.info(`Proxy server running on ${proxyInfo.https ? 'https' : 'http'}://localhost:${proxyPort}${basePathPrefixedWithSlash === '/' ? '' : basePathPrefixedWithSlash}`);
419
+ resolve({ serverIpv6, serverIpv4, });
420
+ };
421
+ const listenerCallback = () => {
422
+ const address = serverIpv6.address();
423
+ proxyPort = address.port;
424
+ // 前面已经监听了ipv6端口,追加监听Ipv4同端口号
425
+ serverIpv4.listen(proxyPort, '0.0.0.0', nestedListener);
426
+ };
427
+ serverIpv6.on('error', errHandler);
428
+ serverIpv4.on('error', errHandler);
429
+ serverIpv6.on('connection', connectionHandler);
430
+ serverIpv4.on('connection', connectionHandler);
431
+ // 为了代理服务器的健壮性,先启动ipv6监听,然后再在其回调函数中启动ipv4监听
432
+ serverIpv6.listen(port, '::', listenerCallback);
412
433
  });
413
434
  return promisedServer;
414
435
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.jimuwd.xian.registry-proxy",
3
- "version": "1.0.110",
3
+ "version": "1.0.112",
4
4
  "description": "A lightweight npm registry proxy with fallback support",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",