update structure
This commit is contained in:
156
ts/forwarding/factory/forwarding-factory.ts
Normal file
156
ts/forwarding/factory/forwarding-factory.ts
Normal file
@ -0,0 +1,156 @@
|
||||
import type { ForwardConfig } from '../config/forwarding-types.js';
|
||||
import type { ForwardingHandler } from '../handlers/base-handler.js';
|
||||
import { HttpForwardingHandler } from '../handlers/http-handler.js';
|
||||
import { HttpsPassthroughHandler } from '../handlers/https-passthrough-handler.js';
|
||||
import { HttpsTerminateToHttpHandler } from '../handlers/https-terminate-to-http-handler.js';
|
||||
import { HttpsTerminateToHttpsHandler } from '../handlers/https-terminate-to-https-handler.js';
|
||||
|
||||
/**
|
||||
* Factory for creating forwarding handlers based on the configuration type
|
||||
*/
|
||||
export class ForwardingHandlerFactory {
|
||||
/**
|
||||
* Create a forwarding handler based on the configuration
|
||||
* @param config The forwarding configuration
|
||||
* @returns The appropriate forwarding handler
|
||||
*/
|
||||
public static createHandler(config: ForwardConfig): ForwardingHandler {
|
||||
// Create the appropriate handler based on the forwarding type
|
||||
switch (config.type) {
|
||||
case 'http-only':
|
||||
return new HttpForwardingHandler(config);
|
||||
|
||||
case 'https-passthrough':
|
||||
return new HttpsPassthroughHandler(config);
|
||||
|
||||
case 'https-terminate-to-http':
|
||||
return new HttpsTerminateToHttpHandler(config);
|
||||
|
||||
case 'https-terminate-to-https':
|
||||
return new HttpsTerminateToHttpsHandler(config);
|
||||
|
||||
default:
|
||||
// Type system should prevent this, but just in case:
|
||||
throw new Error(`Unknown forwarding type: ${(config as any).type}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply default values to a forwarding configuration based on its type
|
||||
* @param config The original forwarding configuration
|
||||
* @returns A configuration with defaults applied
|
||||
*/
|
||||
public static applyDefaults(config: ForwardConfig): ForwardConfig {
|
||||
// Create a deep copy of the configuration
|
||||
const result: ForwardConfig = JSON.parse(JSON.stringify(config));
|
||||
|
||||
// Apply defaults based on forwarding type
|
||||
switch (config.type) {
|
||||
case 'http-only':
|
||||
// Set defaults for HTTP-only mode
|
||||
result.http = {
|
||||
enabled: true,
|
||||
...config.http
|
||||
};
|
||||
break;
|
||||
|
||||
case 'https-passthrough':
|
||||
// Set defaults for HTTPS passthrough
|
||||
result.https = {
|
||||
forwardSni: true,
|
||||
...config.https
|
||||
};
|
||||
// SNI forwarding doesn't do HTTP
|
||||
result.http = {
|
||||
enabled: false,
|
||||
...config.http
|
||||
};
|
||||
break;
|
||||
|
||||
case 'https-terminate-to-http':
|
||||
// Set defaults for HTTPS termination to HTTP
|
||||
result.https = {
|
||||
...config.https
|
||||
};
|
||||
// Support HTTP access by default in this mode
|
||||
result.http = {
|
||||
enabled: true,
|
||||
redirectToHttps: true,
|
||||
...config.http
|
||||
};
|
||||
// Enable ACME by default
|
||||
result.acme = {
|
||||
enabled: true,
|
||||
maintenance: true,
|
||||
...config.acme
|
||||
};
|
||||
break;
|
||||
|
||||
case 'https-terminate-to-https':
|
||||
// Similar to terminate-to-http but with different target handling
|
||||
result.https = {
|
||||
...config.https
|
||||
};
|
||||
result.http = {
|
||||
enabled: true,
|
||||
redirectToHttps: true,
|
||||
...config.http
|
||||
};
|
||||
result.acme = {
|
||||
enabled: true,
|
||||
maintenance: true,
|
||||
...config.acme
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a forwarding configuration
|
||||
* @param config The configuration to validate
|
||||
* @throws Error if the configuration is invalid
|
||||
*/
|
||||
public static validateConfig(config: ForwardConfig): void {
|
||||
// Validate common properties
|
||||
if (!config.target) {
|
||||
throw new Error('Forwarding configuration must include a target');
|
||||
}
|
||||
|
||||
if (!config.target.host || (Array.isArray(config.target.host) && config.target.host.length === 0)) {
|
||||
throw new Error('Target must include a host or array of hosts');
|
||||
}
|
||||
|
||||
if (!config.target.port || config.target.port <= 0 || config.target.port > 65535) {
|
||||
throw new Error('Target must include a valid port (1-65535)');
|
||||
}
|
||||
|
||||
// Type-specific validation
|
||||
switch (config.type) {
|
||||
case 'http-only':
|
||||
// HTTP-only needs http.enabled to be true
|
||||
if (config.http?.enabled === false) {
|
||||
throw new Error('HTTP-only forwarding must have HTTP enabled');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'https-passthrough':
|
||||
// HTTPS passthrough doesn't support HTTP
|
||||
if (config.http?.enabled === true) {
|
||||
throw new Error('HTTPS passthrough does not support HTTP');
|
||||
}
|
||||
|
||||
// HTTPS passthrough doesn't work with ACME
|
||||
if (config.acme?.enabled === true) {
|
||||
throw new Error('HTTPS passthrough does not support ACME');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'https-terminate-to-http':
|
||||
case 'https-terminate-to-https':
|
||||
// These modes support all options, nothing specific to validate
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
5
ts/forwarding/factory/index.ts
Normal file
5
ts/forwarding/factory/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Forwarding factory implementations
|
||||
*/
|
||||
|
||||
export { ForwardingHandlerFactory } from './forwarding-factory.js';
|
Reference in New Issue
Block a user