341 lines
10 KiB
Markdown
341 lines
10 KiB
Markdown
# SmartProxy Routing Architecture Unification Plan
|
|
|
|
## Overview
|
|
This document analyzes the current state of routing in SmartProxy, identifies redundancies and inconsistencies, and proposes a unified architecture.
|
|
|
|
## Current State Analysis
|
|
|
|
### 1. Multiple Route Manager Implementations
|
|
|
|
#### 1.1 Core SharedRouteManager (`ts/core/utils/route-manager.ts`)
|
|
- **Purpose**: Designed as a shared component for SmartProxy and NetworkProxy
|
|
- **Features**:
|
|
- Port mapping and expansion (e.g., `[80, 443]` → individual routes)
|
|
- Comprehensive route matching (domain, path, IP, headers, TLS)
|
|
- Route validation and conflict detection
|
|
- Event emitter for route changes
|
|
- Detailed logging support
|
|
- **Status**: Well-designed but underutilized
|
|
|
|
#### 1.2 SmartProxy RouteManager (`ts/proxies/smart-proxy/route-manager.ts`)
|
|
- **Purpose**: SmartProxy-specific route management
|
|
- **Issues**:
|
|
- 95% duplicate code from SharedRouteManager
|
|
- Only difference is using `ISmartProxyOptions` instead of generic interface
|
|
- Contains deprecated security methods
|
|
- Unnecessary code duplication
|
|
- **Status**: Should be removed in favor of SharedRouteManager
|
|
|
|
#### 1.3 HttpProxy Route Management (`ts/proxies/http-proxy/`)
|
|
- **Purpose**: HTTP-specific routing
|
|
- **Implementation**: Minimal, inline route matching
|
|
- **Status**: Could benefit from SharedRouteManager
|
|
|
|
### 2. Multiple Router Implementations
|
|
|
|
#### 2.1 ProxyRouter (`ts/routing/router/proxy-router.ts`)
|
|
- **Purpose**: Legacy compatibility with `IReverseProxyConfig`
|
|
- **Features**: Domain-based routing with path patterns
|
|
- **Used by**: HttpProxy for backward compatibility
|
|
|
|
#### 2.2 RouteRouter (`ts/routing/router/route-router.ts`)
|
|
- **Purpose**: Modern routing with `IRouteConfig`
|
|
- **Features**: Nearly identical to ProxyRouter
|
|
- **Issues**: Code duplication with ProxyRouter
|
|
|
|
### 3. Scattered Route Utilities
|
|
|
|
#### 3.1 Core route-utils (`ts/core/utils/route-utils.ts`)
|
|
- **Purpose**: Shared matching functions
|
|
- **Features**: Domain, path, IP, CIDR matching
|
|
- **Status**: Well-implemented, should be the single source
|
|
|
|
#### 3.2 SmartProxy route-utils (`ts/proxies/smart-proxy/utils/route-utils.ts`)
|
|
- **Purpose**: Route configuration utilities
|
|
- **Features**: Different scope - config merging, not pattern matching
|
|
- **Status**: Keep separate as it serves different purpose
|
|
|
|
### 4. Other Route-Related Files
|
|
- `route-patterns.ts`: Constants for route patterns
|
|
- `route-validators.ts`: Route configuration validation
|
|
- `route-helpers.ts`: Additional utilities
|
|
- `route-connection-handler.ts`: Connection routing logic
|
|
|
|
## Problems Identified
|
|
|
|
### 1. Code Duplication
|
|
- **SharedRouteManager vs SmartProxy RouteManager**: ~1000 lines of duplicate code
|
|
- **ProxyRouter vs RouteRouter**: ~500 lines of duplicate code
|
|
- **Matching logic**: Implemented in 4+ different places
|
|
|
|
### 2. Inconsistent Implementations
|
|
```typescript
|
|
// Example: Domain matching appears in multiple places
|
|
// 1. In route-utils.ts
|
|
export function matchDomain(pattern: string, hostname: string): boolean
|
|
|
|
// 2. In SmartProxy RouteManager
|
|
private matchDomain(domain: string, hostname: string): boolean
|
|
|
|
// 3. In ProxyRouter
|
|
private matchesHostname(configName: string, hostname: string): boolean
|
|
|
|
// 4. In RouteRouter
|
|
private matchDomain(pattern: string, hostname: string): boolean
|
|
```
|
|
|
|
### 3. Unclear Separation of Concerns
|
|
- Route Managers handle both storage AND matching
|
|
- Routers also handle storage AND matching
|
|
- No clear boundaries between layers
|
|
|
|
### 4. Maintenance Burden
|
|
- Bug fixes need to be applied in multiple places
|
|
- New features must be implemented multiple times
|
|
- Testing effort multiplied
|
|
|
|
## Proposed Unified Architecture
|
|
|
|
### Layer 1: Core Routing Components
|
|
```
|
|
ts/core/routing/
|
|
├── types.ts # All route-related types
|
|
├── utils.ts # All matching logic (consolidated)
|
|
├── route-store.ts # Route storage and indexing
|
|
└── route-matcher.ts # Route matching engine
|
|
```
|
|
|
|
### Layer 2: Route Management
|
|
```
|
|
ts/core/routing/
|
|
└── route-manager.ts # Single RouteManager for all proxies
|
|
- Uses RouteStore for storage
|
|
- Uses RouteMatcher for matching
|
|
- Provides high-level API
|
|
```
|
|
|
|
### Layer 3: HTTP Routing
|
|
```
|
|
ts/routing/
|
|
└── http-router.ts # Single HTTP router implementation
|
|
- Uses RouteManager for route lookup
|
|
- Handles HTTP-specific concerns
|
|
- Legacy adapter built-in
|
|
```
|
|
|
|
### Layer 4: Proxy Integration
|
|
```
|
|
ts/proxies/
|
|
├── smart-proxy/
|
|
│ └── (uses core RouteManager directly)
|
|
├── http-proxy/
|
|
│ └── (uses core RouteManager + HttpRouter)
|
|
└── network-proxy/
|
|
└── (uses core RouteManager directly)
|
|
```
|
|
|
|
## Implementation Plan
|
|
|
|
### Phase 1: Consolidate Matching Logic (Week 1)
|
|
1. **Audit all matching implementations**
|
|
- Document differences in behavior
|
|
- Identify the most comprehensive implementation
|
|
- Create test suite covering all edge cases
|
|
|
|
2. **Create unified matching module**
|
|
```typescript
|
|
// ts/core/routing/matchers.ts
|
|
export class DomainMatcher {
|
|
static match(pattern: string, hostname: string): boolean
|
|
}
|
|
|
|
export class PathMatcher {
|
|
static match(pattern: string, path: string): MatchResult
|
|
}
|
|
|
|
export class IpMatcher {
|
|
static match(pattern: string, ip: string): boolean
|
|
static matchCidr(cidr: string, ip: string): boolean
|
|
}
|
|
```
|
|
|
|
3. **Update all components to use unified matchers**
|
|
- Replace local implementations
|
|
- Ensure backward compatibility
|
|
- Run comprehensive tests
|
|
|
|
### Phase 2: Unify Route Managers (Week 2)
|
|
1. **Enhance SharedRouteManager**
|
|
- Add any missing features from SmartProxy RouteManager
|
|
- Make it truly generic (no proxy-specific dependencies)
|
|
- Add adapter pattern for different options types
|
|
|
|
2. **Migrate SmartProxy to use SharedRouteManager**
|
|
```typescript
|
|
// Before
|
|
this.routeManager = new RouteManager(this.settings);
|
|
|
|
// After
|
|
this.routeManager = new SharedRouteManager({
|
|
logger: this.settings.logger,
|
|
enableDetailedLogging: this.settings.enableDetailedLogging
|
|
});
|
|
```
|
|
|
|
3. **Remove duplicate RouteManager**
|
|
- Delete `ts/proxies/smart-proxy/route-manager.ts`
|
|
- Update all imports
|
|
- Verify all tests pass
|
|
|
|
### Phase 3: Consolidate Routers (Week 3)
|
|
1. **Create unified HttpRouter**
|
|
```typescript
|
|
export class HttpRouter {
|
|
constructor(private routeManager: SharedRouteManager) {}
|
|
|
|
// Modern interface
|
|
route(req: IncomingMessage): RouteResult
|
|
|
|
// Legacy adapter
|
|
routeLegacy(config: IReverseProxyConfig): RouteResult
|
|
}
|
|
```
|
|
|
|
2. **Migrate HttpProxy**
|
|
- Replace both ProxyRouter and RouteRouter
|
|
- Use single HttpRouter with appropriate adapter
|
|
- Maintain backward compatibility
|
|
|
|
3. **Clean up legacy code**
|
|
- Mark old interfaces as deprecated
|
|
- Add migration guides
|
|
- Plan removal in next major version
|
|
|
|
### Phase 4: Architecture Cleanup (Week 4)
|
|
1. **Reorganize file structure**
|
|
```
|
|
ts/core/
|
|
├── routing/
|
|
│ ├── index.ts
|
|
│ ├── types.ts
|
|
│ ├── matchers/
|
|
│ │ ├── domain.ts
|
|
│ │ ├── path.ts
|
|
│ │ ├── ip.ts
|
|
│ │ └── index.ts
|
|
│ ├── route-store.ts
|
|
│ ├── route-matcher.ts
|
|
│ └── route-manager.ts
|
|
└── utils/
|
|
└── (remove route-specific utils)
|
|
```
|
|
|
|
2. **Update documentation**
|
|
- Architecture diagrams
|
|
- Migration guides
|
|
- API documentation
|
|
|
|
3. **Performance optimization**
|
|
- Add caching where beneficial
|
|
- Optimize hot paths
|
|
- Benchmark before/after
|
|
|
|
## Migration Strategy
|
|
|
|
### For SmartProxy RouteManager Users
|
|
```typescript
|
|
// Old way
|
|
import { RouteManager } from './route-manager.js';
|
|
const manager = new RouteManager(options);
|
|
|
|
// New way
|
|
import { SharedRouteManager as RouteManager } from '../core/utils/route-manager.js';
|
|
const manager = new RouteManager({
|
|
logger: options.logger,
|
|
enableDetailedLogging: options.enableDetailedLogging
|
|
});
|
|
```
|
|
|
|
### For Router Users
|
|
```typescript
|
|
// Old way
|
|
const proxyRouter = new ProxyRouter();
|
|
const routeRouter = new RouteRouter();
|
|
|
|
// New way
|
|
const router = new HttpRouter(routeManager);
|
|
// Automatically handles both modern and legacy configs
|
|
```
|
|
|
|
## Success Metrics
|
|
|
|
1. **Code Reduction**
|
|
- Target: Remove ~1,500 lines of duplicate code
|
|
- Measure: Lines of code before/after
|
|
|
|
2. **Performance**
|
|
- Target: No regression in routing performance
|
|
- Measure: Benchmark route matching operations
|
|
|
|
3. **Maintainability**
|
|
- Target: Single implementation for each concept
|
|
- Measure: Time to implement new features
|
|
|
|
4. **Test Coverage**
|
|
- Target: 100% coverage of routing logic
|
|
- Measure: Coverage reports
|
|
|
|
## Risks and Mitigations
|
|
|
|
### Risk 1: Breaking Changes
|
|
- **Mitigation**: Extensive adapter patterns and backward compatibility layers
|
|
- **Testing**: Run all existing tests plus new integration tests
|
|
|
|
### Risk 2: Performance Regression
|
|
- **Mitigation**: Benchmark critical paths before changes
|
|
- **Testing**: Load testing with production-like scenarios
|
|
|
|
### Risk 3: Hidden Dependencies
|
|
- **Mitigation**: Careful code analysis and dependency mapping
|
|
- **Testing**: Integration tests across all proxy types
|
|
|
|
## Long-term Vision
|
|
|
|
### Future Enhancements
|
|
1. **Route Caching**: LRU cache for frequently accessed routes
|
|
2. **Route Indexing**: Trie-based indexing for faster domain matching
|
|
3. **Route Priorities**: Explicit priority system instead of specificity
|
|
4. **Dynamic Routes**: Support for runtime route modifications
|
|
5. **Route Templates**: Reusable route configurations
|
|
|
|
### API Evolution
|
|
```typescript
|
|
// Future unified routing API
|
|
const routingEngine = new RoutingEngine({
|
|
stores: [fileStore, dbStore, dynamicStore],
|
|
matchers: [domainMatcher, pathMatcher, customMatcher],
|
|
cache: new LRUCache({ max: 1000 }),
|
|
indexes: {
|
|
domain: new TrieIndex(),
|
|
path: new RadixTree()
|
|
}
|
|
});
|
|
|
|
// Simple, powerful API
|
|
const route = await routingEngine.findRoute({
|
|
domain: 'example.com',
|
|
path: '/api/v1/users',
|
|
ip: '192.168.1.1',
|
|
headers: { 'x-custom': 'value' }
|
|
});
|
|
```
|
|
|
|
## Conclusion
|
|
|
|
The current routing architecture has significant duplication and inconsistencies. By following this unification plan, we can:
|
|
1. Reduce code by ~30%
|
|
2. Improve maintainability
|
|
3. Ensure consistent behavior
|
|
4. Enable future enhancements
|
|
|
|
The phased approach minimizes risk while delivering incremental value. Each phase is independently valuable and can be deployed separately. |