feat(proxy): Start implementing PROXY protocol support and WrappedSocket class for enhanced client IP handling
This commit is contained in:
341
readme.routing.md
Normal file
341
readme.routing.md
Normal file
@ -0,0 +1,341 @@
|
||||
# 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.
|
Reference in New Issue
Block a user