# 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