dynamic-self-register-proxy 1.0.5 → 1.0.7

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 (2) hide show
  1. package/package.json +1 -1
  2. package/proxy.js +46 -47
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dynamic-self-register-proxy",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "Dynamic reverse proxy with self-registration API - applications can register themselves and receive an automatically assigned port",
5
5
  "main": "proxy-client.js",
6
6
  "bin": {
package/proxy.js CHANGED
@@ -818,22 +818,51 @@ function escapeHtml(text) {
818
818
  }
819
819
 
820
820
  // ============================================
821
- // PROXY MIDDLEWARE
821
+ // PROXY MIDDLEWARE (PERSISTENT)
822
822
  // ============================================
823
823
 
824
824
  /**
825
- * Router dynamique - détermine la cible en fonction de la requête
825
+ * Middleware de proxy persistant pour éviter les fuites de mémoire (EventEmitter MaxListenersExceededWarning)
826
+ * Créé une seule fois et réutilisé pour toutes les requêtes.
826
827
  */
827
- const dynamicRouter = (req) => {
828
- const route = findRouteForPath(req.path);
829
- if (route) {
830
- return `http://localhost:${route.port}`;
828
+ const persistentProxyMiddleware = createProxyMiddleware({
829
+ target: 'http://localhost', // Cible par défaut (sera surchargée par router)
830
+ router: (req) => req.proxyTarget,
831
+ changeOrigin: true,
832
+ pathRewrite: (path, req) => {
833
+ const routePath = req.proxyRoutePath;
834
+ if (routePath && path.startsWith(routePath)) {
835
+ return path.slice(routePath.length) || '/';
836
+ }
837
+ return path;
838
+ },
839
+ on: {
840
+ proxyReq: (proxyReq, req) => {
841
+ // Ré-écriture du body si présent (nécessaire car express.json() a consommé le stream)
842
+ if (req.body && typeof req.body === 'object' && Object.keys(req.body).length > 0) {
843
+ const bodyData = JSON.stringify(req.body);
844
+ proxyReq.setHeader('Content-Type', 'application/json');
845
+ proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
846
+ proxyReq.write(bodyData);
847
+ }
848
+ console.log(`[PROXY] ${req.method} ${req.path} -> ${req.proxyTarget}`);
849
+ },
850
+ error: (err, req, res) => {
851
+ // Si la réponse a déjà été envoyée, on ne fait rien
852
+ if (res.headersSent) return;
853
+
854
+ console.error(`[PROXY ERROR] ${req.path}:`, err.message);
855
+ res.status(502).json({
856
+ error: 'Proxy error',
857
+ message: err.message,
858
+ target: req.proxyTarget
859
+ });
860
+ }
831
861
  }
832
- return null;
833
- };
862
+ });
834
863
 
835
864
  /**
836
- * Middleware de proxy pour toutes les autres requêtes
865
+ * Middleware principal qui gère le routage vers le proxy
837
866
  */
838
867
  app.use((req, res, next) => {
839
868
  // Ignore les routes de l'API proxy
@@ -841,9 +870,9 @@ app.use((req, res, next) => {
841
870
  return next();
842
871
  }
843
872
 
844
- const target = dynamicRouter(req);
873
+ const route = findRouteForPath(req.path);
845
874
 
846
- if (!target) {
875
+ if (!route) {
847
876
  return res.status(404).json({
848
877
  error: 'No route registered for this path',
849
878
  path: req.path,
@@ -851,45 +880,15 @@ app.use((req, res, next) => {
851
880
  });
852
881
  }
853
882
 
883
+ // Stocke les informations de la route dans l'objet req pour le middleware persistant
884
+ req.proxyTarget = `http://localhost:${route.port}`;
885
+
854
886
  // Trouve le path de la route pour le pathRewrite
855
- const route = findRouteForPath(req.path);
856
- const routePath = [...registry.routes.entries()]
887
+ req.proxyRoutePath = [...registry.routes.entries()]
857
888
  .find(([, v]) => v === route)?.[0];
858
889
 
859
- const proxyMiddleware = createProxyMiddleware({
860
- target,
861
- changeOrigin: true,
862
- pathRewrite: (path) => {
863
- // Retire le préfixe de la route du path
864
- if (routePath && path.startsWith(routePath)) {
865
- const newPath = path.slice(routePath.length) || '/';
866
- return newPath;
867
- }
868
- return path;
869
- },
870
- on: {
871
- proxyReq: (proxyReq, req) => {
872
- // Ré-écriture du body si présent (nécessaire car express.json() a consommé le stream)
873
- if (req.body && Object.keys(req.body).length > 0) {
874
- const bodyData = JSON.stringify(req.body);
875
- proxyReq.setHeader('Content-Type', 'application/json');
876
- proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
877
- proxyReq.write(bodyData);
878
- }
879
- console.log(`[PROXY] ${req.method} ${req.path} -> ${target}`);
880
- },
881
- error: (err, req, res) => {
882
- console.error(`[PROXY ERROR] ${req.path}:`, err.message);
883
- res.status(502).json({
884
- error: 'Proxy error',
885
- message: err.message,
886
- target
887
- });
888
- }
889
- }
890
- });
891
-
892
- proxyMiddleware(req, res, next);
890
+ // Délègue au middleware de proxy persistant
891
+ persistentProxyMiddleware(req, res, next);
893
892
  });
894
893
 
895
894
  // ============================================