MCPcopy Create free account
hub / github.com/0xUnixIO/pulse / handleSub

Method handleSub

internal/serverapi/sub.go:29–96  ·  view source on GitHub ↗
(w http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

27}
28
29func (a *subAPI) handleSub(w http.ResponseWriter, r *http.Request) {
30 if r.Method != http.MethodGet {
31 http.NotFound(w, r)
32 return
33 }
34
35 // 从路径提取 token:/sub/{token}
36 userID := strings.TrimPrefix(r.URL.Path, "/sub/")
37 userID = strings.TrimSuffix(userID, "/")
38 if userID == "" {
39 http.NotFound(w, r)
40 return
41 }
42
43 user, err := a.users.GetUserBySubToken(userID)
44 if err != nil {
45 http.NotFound(w, r)
46 return
47 }
48
49 // 异步记录订阅访问日志(无论用户状态如何,均记录)
50 go func() {
51 ip := realIP(r)
52 ua := r.Header.Get("User-Agent")
53 if err := a.users.LogSubAccess(user.ID, ip, ua); err != nil {
54 log.Printf("sub access log: %v", err)
55 }
56 }()
57
58 // 非活跃用户(disabled / expired / limited / on_hold)返回空订阅。
59 // 仍携带 Subscription-Userinfo header,让客户端能展示流量/到期信息。
60 if !user.EffectiveEnabled() {
61 w.Header().Set("Subscription-Userinfo", buildUserinfo(user))
62 w.Header().Set("Content-Type", "text/plain; charset=utf-8")
63 w.WriteHeader(http.StatusOK)
64 _, _ = w.Write([]byte(base64.StdEncoding.EncodeToString(nil)))
65 return
66 }
67
68 // 收集该用户所有节点的全部订阅链接(跳过已禁用节点)
69 accesses, err := a.users.ListActiveUserInboundsByUser(user.ID)
70 if err != nil {
71 http.Error(w, "internal error", http.StatusInternalServerError)
72 return
73 }
74
75 // 构建用户排除的 host 集合
76 excludedIDs, _ := a.users.ListHostExclusionsByUser(user.ID)
77 excluded := make(map[string]bool, len(excludedIDs))
78 for _, id := range excludedIDs {
79 excluded[id] = true
80 }
81
82 links := subscription.BuildLinks(accesses, a.inbounds, user, excluded)
83
84 // Subscription-Userinfo header(客户端如 v2rayN 用于显示流量信息)
85 w.Header().Set("Subscription-Userinfo", buildUserinfo(user))
86 w.Header().Set("Content-Type", "text/plain; charset=utf-8")

Callers

nothing calls this directly

Calls 13

BuildLinksFunction · 0.92
realIPFunction · 0.85
buildUserinfoFunction · 0.85
nextTrafficResetAtFunction · 0.85
EffectiveEnabledMethod · 0.80
WriteHeaderMethod · 0.80
WriteMethod · 0.80
GetUserBySubTokenMethod · 0.65
GetMethod · 0.65
LogSubAccessMethod · 0.65

Tested by

no test coverage detected