Documentation
¶
Overview ¶
Package subscription turns a user's hosts into client-ready connection links.
Index ¶
- Constants
- func Base64(b Bundle) string
- func Clash(b Bundle) string
- func Headers(b Bundle) map[string]string
- func Links(b Bundle) []string
- func Render(b Bundle, f Format) string
- func RenderWith(b Bundle, f Format, t Templates) string
- func SingBox(b Bundle) string
- func WireGuardConf(b Bundle) string
- func XrayJSON(b Bundle) string
- type Bundle
- type Format
- type Info
- type Templates
Constants ¶
const ( PlaceholderProxies = "{{PROXIES}}" // Clash: the `proxies:` entries PlaceholderNames = "{{NAMES}}" // Clash: proxy names, quoted and comma-separated PlaceholderOutbounds = "{{OUTBOUNDS}}" // sing-box: outbound objects, JSON PlaceholderTags = "{{TAGS}}" // sing-box: outbound tags, JSON strings PlaceholderTitle = "{{TITLE}}" )
Placeholders a custom document can use. The panel supplies the parts it alone knows — the servers a subscriber is entitled to — and leaves everything else, rules, DNS, proxy groups, to the operator.
Variables ¶
This section is empty.
Functions ¶
func Base64 ¶
Base64 renders the classic base64 subscription payload understood by nearly every client.
func Clash ¶
Clash renders a Mihomo/Clash.Meta profile. It is emitted as YAML by hand because the document is small, fixed in shape, and hand-writing it avoids a YAML dependency in the panel.
func Headers ¶
Headers are the subscription-userinfo style metadata clients read to display quota and expiry without opening the panel.
func RenderWith ¶ added in v0.6.0
RenderWith is Render with operator templates applied where they exist.
A template that names no placeholder is served as written. That is a deliberate escape hatch — an operator pinning one fixed configuration is a legitimate thing to want — but it does mean the panel cannot warn that a subscriber's own servers went missing, so the UI says so.
func SingBox ¶
SingBox renders a sing-box client configuration with a selector and a urltest group over every host.
func WireGuardConf ¶ added in v0.10.0
WireGuardConf renders the subscriber's tunnel as the .conf file every WireGuard client reads — there is no URI scheme for WireGuard the way there is for VLESS, so a file is the only thing to hand over.
One file is one tunnel. When several WireGuard hosts are published the first enabled one wins rather than emitting several [Peer] blocks: two peers both claiming 0.0.0.0/0 is a configuration whose behaviour depends on the client, and a config that works differently on iOS and on Windows is worse than one that names a single server.
func XrayJSON ¶ added in v0.1.1
XrayJSON renders the "JSON subscription" that v2rayN, v2rayNG, Happ and Streisand accept: an array of complete Xray client configurations, one per host, each ready to run as-is. It is the most faithful of the formats — a vless:// link has to squeeze every stream setting through a query string, while this carries the same structure xray-core actually parses.
Every entry is self-contained on purpose. Clients present them as a server list and switch between them, so an entry that leaned on a shared block would stop working the moment the user picked a different one.
Types ¶
type Bundle ¶
type Bundle struct {
User *domain.User
Hosts []domain.Host
// Title is shown as the profile name in client apps.
Title string
SupportURL string
// UpdateInterval is how often clients should refresh, in hours.
UpdateInterval int
}
Bundle is everything a subscription response is built from.
type Format ¶
type Format string
Format is a subscription encoding a client understands.
func DetectClientFormat ¶ added in v0.1.1
DetectClientFormat reports the format a client needs when it names itself. The second return distinguishes "this client requires Clash" from "no idea what this is" — the caller has a configured default for the second case, and collapsing the two would apply that default to clients that cannot read it.
func DetectFormat ¶
DetectFormat picks an encoding from the client's User-Agent, falling back to the base64 list that every client understands.
func (Format) ContentType ¶
ContentType is what the response should be served as.
type Info ¶
type Info struct {
Username string `json:"username"`
Status string `json:"status"`
UsedBytes int64 `json:"usedTrafficBytes"`
LimitBytes int64 `json:"trafficLimitBytes"`
LifetimeBytes int64 `json:"lifetimeUsedTrafficBytes"`
ExpireAt *time.Time `json:"expireAt"`
SubscriptionURL string `json:"subscriptionUrl"`
Links []string `json:"links"`
Title string `json:"title"`
SupportURL string `json:"supportUrl,omitempty"`
DaysLeft *int `json:"daysLeft,omitempty"`
// Notices an operator has published. Empty on a deployment that has never
// used them, so the page simply renders nothing.
Announcements []domain.Announcement `json:"announcements,omitempty"`
// Page options, so the subscriber page renders what the operator chose
// without a second request.
ShowLinks bool `json:"showLinks"`
ShowFormats bool `json:"showFormats"`
}
Info is the JSON payload the subscription page renders.