Files
GoProxy/CLAUDE.md
isboyjc f03c3300b4 feat: implement custom proxy subscription management and enhance configuration
- Added support for importing Clash/V2ray subscriptions, including automatic format detection and integration with sing-box for protocol conversion.
- Introduced five proxy usage modes in the configuration, allowing flexible selection between mixed, custom-only, and free-only modes.
- Enhanced `.env.example` and `docker-compose.yml` to include new environment variables for custom proxy settings.
- Updated `CHANGELOG.md` to document new features and improvements related to subscription management.
- Improved WebUI for managing subscriptions and displaying proxy statistics.
- Implemented a background process for refreshing subscriptions and probing disabled proxies for reactivation.
2026-04-04 22:25:54 +08:00

122 lines
6.9 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
GoProxy is an intelligent proxy pool system written in Go. It automatically fetches HTTP/SOCKS5 proxies from public sources, validates them (exit IP + geolocation + latency), and serves them via 4 proxy ports (HTTP random/stable, SOCKS5 random/stable) plus a WebUI dashboard.
## Build & Run
```bash
# Run directly (requires Go 1.25, CGO enabled for sqlite3)
go run .
# Build and run
go build -o proxygo .
./proxygo
# Docker
docker compose up -d
```
CGO is required (`CGO_ENABLED=1`) because of the `github.com/mattn/go-sqlite3` dependency.
## Testing
There are no Go unit tests (`go test ./...`). Testing is done via shell scripts against a running instance:
```bash
# HTTP proxy test (continuous, Ctrl+C to stop)
./test/test_proxy.sh # port 7777 (random)
./test/test_proxy.sh 7776 # port 7776 (stable)
# HTTP proxy HTTPS access test (random visits to Google/OpenAI/GitHub etc.)
./test/test_http_https.sh # port 7777, continuous
./test/test_http_https.sh 7776 20 # port 7776, 20 iterations
# SOCKS5 proxy test
./test/test_socks5.sh localhost 7779 # random
./test/test_socks5.sh localhost 7780 50 # stable, 50 iterations
# Go/Python test scripts
go run test/test_proxy.go 7777
python test/test_proxy.py 7776
```
## Architecture
The system is a single binary with several cooperating goroutines. Module `go.mod` name is `goproxy`.
### Module Dependency Flow
```
main.go (orchestrator)
├── config/ — Global config (env vars + config.json), thread-safe singleton
├── storage/ — SQLite persistence layer (proxies + source_status tables)
├── fetcher/ — Multi-source proxy fetcher with circuit breaker (SourceManager)
├── validator/ — Concurrent proxy validation (connectivity + exit IP + geo + latency)
├── pool/ — Pool manager (admission control, slot allocation, replacement logic)
├── checker/ — Background health checker (batch-based, skips S-grade when healthy)
├── optimizer/ — Background quality optimizer (replaces slow proxies with faster ones)
├── custom/ — Custom proxy subscription manager (fetch, parse, validate, periodic refresh)
│ ├── parser.go — Clash YAML / plain / base64 subscription parser
│ ├── singbox.go — sing-box process manager (config generation, start/stop/reload)
│ └── manager.go — Subscription refresh loop + probe-wake loop for disabled proxies
├── proxy/ — Outward-facing proxy servers
│ ├── server.go — HTTP proxy (implements http.Handler)
│ └── socks5_server.go — SOCKS5 proxy (raw TCP, manual protocol implementation)
├── webui/ — Dashboard server (embedded HTML in html.go, API in dashboard.go)
└── logger/ — In-memory log collector for WebUI display
```
### Key Design Patterns
- **Pool state machine**: healthy → warning → critical → emergency. State determines fetch mode (optimize/refill/emergency) and latency thresholds.
- **Slot-based capacity**: Pool has fixed size split between HTTP/SOCKS5 by configurable ratio (default 3:7). Each protocol has guaranteed minimum slots.
- **Smart admission**: New proxies enter if slots available, or replace worst existing proxy if significantly faster (30%+ by default via `ReplaceThreshold`). HTTP proxies must also pass an HTTPS CONNECT tunnel test (random real HTTPS site visit with retry) before admission. Geo-filter (whitelist/blacklist) is applied during validation before admission.
- **Geo-filter**: Whitelist (`AllowedCountries`) takes priority — if non-empty, only those countries pass. Otherwise blacklist (`BlockedCountries`) rejects listed countries. Configurable via env vars, `config.json`, or WebUI at runtime. On startup, existing proxies violating the filter are cleaned from the database.
- **Protocol-parallel validation**: `smartFetchAndFill` splits candidates by protocol and validates SOCKS5/HTTP concurrently. SOCKS5 fills faster (no HTTPS check overhead); HTTP validation runs in parallel without blocking SOCKS5 admission.
- **Circuit breaker on sources**: `SourceManager` tracks consecutive failures per source URL. 3 fails → degraded, 5 → disabled for 30min.
- **Auto-retry on proxy failure**: Both HTTP and SOCKS5 servers retry with different upstream proxies on failure (up to `MaxRetry` times), deleting failed proxies immediately.
- **SOCKS5 service only uses SOCKS5 upstreams** (many free HTTP proxies don't support CONNECT). HTTP service can use either protocol upstream.
### Background Goroutines (started in main.go)
1. **Status monitor** — every 30s, checks pool state and triggers `smartFetchAndFill` if needed
2. **Health checker** — every `HealthCheckInterval` min, validates a batch of proxies
3. **Optimizer** — every `OptimizeInterval` min, fetches from slow sources and replaces B/C grade proxies
4. **Config watcher** — listens for WebUI config changes and adjusts pool slots
### Ports
| Port | Service |
|------|---------|
| 7776 | HTTP proxy (lowest-latency mode) |
| 7777 | HTTP proxy (random rotation mode) |
| 7778 | WebUI dashboard |
| 7779 | SOCKS5 proxy (random rotation mode) |
| 7780 | SOCKS5 proxy (lowest-latency mode) |
### Configuration
- Environment variables: `WEBUI_PASSWORD`, `PROXY_AUTH_ENABLED`, `PROXY_AUTH_USERNAME`, `PROXY_AUTH_PASSWORD`, `BLOCKED_COUNTRIES`, `ALLOWED_COUNTRIES`, `DATA_DIR`
- Persistent config: `config.json` (or `$DATA_DIR/config.json`) — pool capacity, latency thresholds, intervals, geo-filter (blocked/allowed countries). Editable via WebUI.
- Config is loaded once at startup via `config.Load()`, updated in-memory via `config.Save()`. Thread-safe via `sync.RWMutex`.
- Geo-filter: `ALLOWED_COUNTRIES` (whitelist) takes priority over `BLOCKED_COUNTRIES` (blacklist). When whitelist is non-empty, only listed countries are admitted; blacklist is ignored. Both are comma-separated country codes (e.g. `US,JP,KR`). Configurable at runtime via WebUI; `config.json` values override env vars after first save.
### Storage
SQLite with `MaxOpenConns(1)` (single-writer). Two tables: `proxies` (with quality grades S/A/B/C based on latency) and `source_status` (circuit breaker state). Schema auto-migrates on startup.
### WebUI
The entire frontend is embedded as Go string literals in `webui/html.go`. The server (`webui/server.go`) serves HTML and API endpoints. `webui/dashboard.go` contains API handlers. Dual-role auth: guest (read-only) and admin (full control via password).
## Code Conventions
- All log messages use `[module]` prefix: `[pool]`, `[fetch]`, `[health]`, `[optimize]`, `[monitor]`, `[socks5]`, `[proxy]`, `[tunnel]`, `[storage]`, `[source]`
- Comments and log messages are in Chinese
- Quality grades: S (≤500ms), A (501-1000ms), B (1001-2000ms), C (>2000ms)
- `storage.Proxy` is the shared data type across all modules