fix(port-manager, certificate-manager): Improve port binding and ACME challenge route integration in SmartProxy

This commit is contained in:
2025-05-20 15:32:19 +00:00
parent 3b1531d4a2
commit 669cc2809c
7 changed files with 746 additions and 26 deletions

View File

@ -416,6 +416,33 @@ export class SmartCertManager {
if (!this.challengeRoute) {
throw new Error('Challenge route not initialized');
}
// Get the challenge port
const challengePort = this.globalAcmeDefaults?.port || 80;
// Check if any existing routes are already using this port
const portInUseByRoutes = this.routes.some(route => {
const routePorts = Array.isArray(route.match.ports) ? route.match.ports : [route.match.ports];
return routePorts.some(p => {
// Handle both number and port range objects
if (typeof p === 'number') {
return p === challengePort;
} else if (typeof p === 'object' && 'from' in p && 'to' in p) {
// Port range case - check if challengePort is in range
return challengePort >= p.from && challengePort <= p.to;
}
return false;
});
});
if (portInUseByRoutes) {
logger.log('info', `Port ${challengePort} is already used by another route, merging ACME challenge route`, {
port: challengePort,
component: 'certificate-manager'
});
}
// Add the challenge route
const challengeRoute = this.challengeRoute;
try {
@ -430,10 +457,27 @@ export class SmartCertManager {
logger.log('info', 'ACME challenge route successfully added', { component: 'certificate-manager' });
} catch (error) {
logger.log('error', `Failed to add challenge route: ${error.message}`, { error: error.message, component: 'certificate-manager' });
// Handle specific EADDRINUSE errors differently based on whether it's an internal conflict
if ((error as any).code === 'EADDRINUSE') {
throw new Error(`Port ${this.globalAcmeDefaults?.port || 80} is already in use for ACME challenges`);
logger.log('error', `Failed to add challenge route on port ${challengePort}: ${error.message}`, {
error: error.message,
port: challengePort,
component: 'certificate-manager'
});
// Provide a more informative error message
throw new Error(
`Port ${challengePort} is already in use. ` +
`If it's in use by an external process, configure a different port in the ACME settings. ` +
`If it's in use by SmartProxy, there may be a route configuration issue.`
);
}
// Log and rethrow other errors
logger.log('error', `Failed to add challenge route: ${error.message}`, {
error: error.message,
component: 'certificate-manager'
});
throw error;
}
}