feat: independent limiter for user/inbound

This commit is contained in:
zakuwaki 2023-07-24 14:48:58 +08:00
parent 077b77a4a5
commit df4a879a2e
4 changed files with 53 additions and 36 deletions

View File

@ -13,10 +13,12 @@
"user-a", "user-a",
"user-b" "user-b"
], ],
"auth_user_independent": false,
"inbound": [ "inbound": [
"in-a", "in-a",
"in-b" "in-b"
] ],
"inbound_independent": false
} }
] ]
} }
@ -39,12 +41,16 @@ The tag of the limiter, used in route rule.
#### auth_user #### auth_user
Global limiter for a group of usernames, see each inbound for details. Apply limiter for a group of usernames, see each inbound for details.
#### auth_user_independent
Make each auth_user's limiter independent. If disabled, the same limiter will be shared.
#### inbound #### inbound
Global limiter for a group of inbounds. Apply limiter for a group of inbounds.
!!! info "" #### inbound_independent
All the auth_users, inbounds and route rule with limiter tag share the same limiter. To take effect independently, configure limiters seperately. Make each inbound's limiter independent. If disabled, the same limiter will be shared.

View File

@ -13,10 +13,12 @@
"user-a", "user-a",
"user-b" "user-b"
], ],
"auth_user_independent": false,
"inbound": [ "inbound": [
"in-a", "in-a",
"in-b" "in-b"
] ],
"inbound_independent": false
} }
] ]
} }
@ -39,12 +41,16 @@
#### auth_user #### auth_user
用户组全局限速,参阅入站设置。 用户组限速,参阅入站设置。
#### auth_user_independent
使每个用户有单独的限速。关闭时将共享限速。
#### inbound #### inbound
入站组全局限速。 入站组限速。
!!! info "" #### inbound_independent
所有用户、入站和有限速标签的路由规则共享同一个限速。为了独立生效,请分别配置限速器 使每个入站有单独的限速。关闭时将共享限速

View File

@ -44,13 +44,13 @@ func WithDefault(ctx context.Context, logger log.ContextLogger, options []option
func (m *defaultManager) createLimiter(ctx context.Context, option option.Limiter) (err error) { func (m *defaultManager) createLimiter(ctx context.Context, option option.Limiter) (err error) {
var download, upload uint64 var download, upload uint64
if len(option.Download) > 0 { if option.Download != "" {
download, err = humanize.ParseBytes(option.Download) download, err = humanize.ParseBytes(option.Download)
if err != nil { if err != nil {
return err return err
} }
} }
if len(option.Upload) > 0 { if option.Upload != "" {
upload, err = humanize.ParseBytes(option.Upload) upload, err = humanize.ParseBytes(option.Upload)
if err != nil { if err != nil {
return err return err
@ -59,27 +59,30 @@ func (m *defaultManager) createLimiter(ctx context.Context, option option.Limite
if download == 0 && upload == 0 { if download == 0 && upload == 0 {
return E.New("download/upload, at least one must be set") return E.New("download/upload, at least one must be set")
} }
l := newLimiter(download, upload) if option.Tag == "" && len(option.AuthUser) == 0 && len(option.Inbound) == 0 {
valid := false
if len(option.Tag) > 0 {
valid = true
m.mp[limiterKey{prefixTag, option.Tag}] = l
}
if len(option.AuthUser) > 0 {
valid = true
for _, user := range option.AuthUser {
m.mp[limiterKey{prefixUser, user}] = l
}
}
if len(option.Inbound) > 0 {
valid = true
for _, inbound := range option.Inbound {
m.mp[limiterKey{prefixInbound, inbound}] = l
}
}
if !valid {
return E.New("tag/user/inbound, at least one must be set") return E.New("tag/user/inbound, at least one must be set")
} }
var sharedLimiter *limiter
if option.Tag != "" || !option.AuthUserIndependent || !option.InboundIndependent {
sharedLimiter = newLimiter(download, upload)
}
if option.Tag != "" {
m.mp[limiterKey{prefixTag, option.Tag}] = sharedLimiter
}
for _, user := range option.AuthUser {
if option.AuthUserIndependent {
m.mp[limiterKey{prefixUser, user}] = newLimiter(download, upload)
} else {
m.mp[limiterKey{prefixUser, user}] = sharedLimiter
}
}
for _, inbound := range option.Inbound {
if option.InboundIndependent {
m.mp[limiterKey{prefixInbound, inbound}] = newLimiter(download, upload)
} else {
m.mp[limiterKey{prefixInbound, inbound}] = sharedLimiter
}
}
return return
} }

View File

@ -1,9 +1,11 @@
package option package option
type Limiter struct { type Limiter struct {
Tag string `json:"tag"` Tag string `json:"tag"`
Download string `json:"download,omitempty"` Download string `json:"download,omitempty"`
Upload string `json:"upload,omitempty"` Upload string `json:"upload,omitempty"`
AuthUser Listable[string] `json:"auth_user,omitempty"` AuthUser Listable[string] `json:"auth_user,omitempty"`
Inbound Listable[string] `json:"inbound,omitempty"` AuthUserIndependent bool `json:"auth_user_independent,omitempty"`
Inbound Listable[string] `json:"inbound,omitempty"`
InboundIndependent bool `json:"inbound_independent,omitempty"`
} }