Subscriptions Management
Relevant source files
The following files were used as context for generating this wiki page:
Subscriptions Management manages proxy node sources, handles their periodic refresh, and parses various subscription formats into a unified node inventory. It acts as the primary gateway for importing external proxy configurations into the HX-ProxyGroup control plane.
The system supports multiple source types including remote URLs, inline content, and local files. It ensures data security by encrypting source configurations at rest and provides an automated scheduling mechanism to keep node lists current.
Sources: internal/subscription/service.go:21-36, web/src/pages/subscriptions-page.tsx:112-116, internal/api/capabilities_catalog.go:121-125
System Architecture
Subscriptions Management follows a layered architecture connecting the API, application logic, and persistent storage.
The Subscription Service coordinates between the database, encryption modules, and external loaders. It relies on a Repository for persistence and a Cipher for encrypting sensitive URLs and credentials.
Sources: internal/subscription/service.go:119-142, internal/scheduler/subscriptions.go:34-40
Data Model
The system uses a strict schema to track subscription state, refresh history, and failure counts.
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier prefixed with sub-. |
name | string | Display name (1-128 characters). |
source_type | string | One of: remote, inline, file. |
source_config_encrypted | blob | AES-encrypted JSON of the source details. |
enabled | boolean | Controls whether auto-refresh is active. |
refresh_interval_seconds | integer | Frequency of updates (min 60s, default 3600s). |
refresh_cron | string | Optional UTC cron expression for scheduling. |
version | integer | Optimistic locking version for concurrent updates. |
Sources: internal/subscription/service.go:61-76, internal/store/migrations.go:31-45, internal/subscription/service.go:182-187
Source Types and Processing
The system categorizes sources based on how the data is retrieved.
- Remote: Fetches content via HTTP/HTTPS. It supports custom Headers, User-Agent, and configurable timeouts.
- Inline: Stores proxy lists directly in the database (max 4 MiB). This covers URI lists, Base64, and YAML.
- File: Reads from an absolute path on the local server.
Sources: internal/subscription/service.go:21-36, web/src/components/create-subscription-form.tsx:39-44
Recursive Provider Expansion
When parsing Clash/Mihomo YAML, the system automatically detects and expands proxy-providers. It supports recursive loading up to a depth of 3 and a maximum of 32 providers to prevent exhaustion attacks.
Refresh and Synchronization
Refreshing a subscription converts raw source content into persistent nodes.
Refresh Workflow
- Locking: A keyed locker ensures only one refresh runs per subscription ID at a time.
- Loading: The
SourceLoaderretrieves the latest content based on thesource_type. - Parsing: The
Parseridentifies the format (URI list, Clash YAML, etc.) and extracts node details. - Deduplication: Nodes are deduplicated based on a unique fingerprint.
- Persistence: New nodes are created in the
nodestable; nodes no longer present in the subscription are marked asretired.
Sources: internal/subscription/service.go:142-144, internal/subscription/parse_nodes.go:35-42, internal/store/subscriptions.go:183-195
Scheduling
The SubscriptionScheduler runs workers to process due subscriptions.
Security and Integrity
The system enforces several security constraints:
- Config Encryption: Sensitive fields like subscription URLs and credentials are encrypted using a master key (
Cipher.Seal) before being stored in SQLite. Plaintext never appears in the database or logs. - SSRF Protection: Remote fetches by default disallow private IP ranges unless
allow_privateis explicitly enabled. - Optimistic Locking: All updates and deletes require the current
version. If the version in the request does not match the database, asubscription_conflicterror is returned.
Sources: internal/subscription/service.go:315-321, internal/subscription/service.go:357-360, internal/api/subscriptions_test.go:102-105, internal/store/subscriptions.go:137-142
Summary
Subscriptions Management provides a robust pipeline for ingesting proxy nodes. By combining encrypted storage, recursive parsing of complex formats, and a distributed-style scheduler even within a single-process architecture, it maintains a reliable and fresh inventory of proxy assets for HX-ProxyGroup.