init
This commit is contained in:
105
internal/config/types.go
Normal file
105
internal/config/types.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Duration 提供更灵活的反序列化能力,同时兼容纯秒整数与 Go Duration 字符串。
|
||||
type Duration time.Duration
|
||||
|
||||
// UnmarshalText 使 Viper 可以识别诸如 "30s"、"5m" 或纯数字秒值等配置写法。
|
||||
func (d *Duration) UnmarshalText(text []byte) error {
|
||||
raw := strings.TrimSpace(string(text))
|
||||
if raw == "" {
|
||||
*d = Duration(0)
|
||||
return nil
|
||||
}
|
||||
|
||||
if seconds, err := time.ParseDuration(raw); err == nil {
|
||||
*d = Duration(seconds)
|
||||
return nil
|
||||
}
|
||||
|
||||
if intVal, err := parseInt(raw); err == nil {
|
||||
*d = Duration(time.Duration(intVal) * time.Second)
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("invalid duration value: %s", raw)
|
||||
}
|
||||
|
||||
// DurationValue 返回真实的 time.Duration,便于调用方计算。
|
||||
func (d Duration) DurationValue() time.Duration {
|
||||
return time.Duration(d)
|
||||
}
|
||||
|
||||
// parseInt 支持十进制或 0x 前缀的十六进制字符串解析。
|
||||
func parseInt(value string) (int64, error) {
|
||||
if strings.HasPrefix(value, "0x") || strings.HasPrefix(value, "0X") {
|
||||
return strconv.ParseInt(value, 0, 64)
|
||||
}
|
||||
return strconv.ParseInt(value, 10, 64)
|
||||
}
|
||||
|
||||
// GlobalConfig 描述全局运行时行为,所有 Hub 共享同一份参数。
|
||||
type GlobalConfig struct {
|
||||
ListenPort int `mapstructure:"ListenPort"`
|
||||
LogLevel string `mapstructure:"LogLevel"`
|
||||
LogFilePath string `mapstructure:"LogFilePath"`
|
||||
LogMaxSize int `mapstructure:"LogMaxSize"`
|
||||
LogMaxBackups int `mapstructure:"LogMaxBackups"`
|
||||
LogCompress bool `mapstructure:"LogCompress"`
|
||||
StoragePath string `mapstructure:"StoragePath"`
|
||||
CacheTTL Duration `mapstructure:"CacheTTL"`
|
||||
MaxMemoryCache int64 `mapstructure:"MaxMemoryCacheSize"`
|
||||
MaxRetries int `mapstructure:"MaxRetries"`
|
||||
InitialBackoff Duration `mapstructure:"InitialBackoff"`
|
||||
UpstreamTimeout Duration `mapstructure:"UpstreamTimeout"`
|
||||
}
|
||||
|
||||
// HubConfig 决定单个代理实例如何与下游/上游交互。
|
||||
type HubConfig struct {
|
||||
Name string `mapstructure:"Name"`
|
||||
Domain string `mapstructure:"Domain"`
|
||||
Upstream string `mapstructure:"Upstream"`
|
||||
Proxy string `mapstructure:"Proxy"`
|
||||
Type string `mapstructure:"Type"`
|
||||
Username string `mapstructure:"Username"`
|
||||
Password string `mapstructure:"Password"`
|
||||
CacheTTL Duration `mapstructure:"CacheTTL"`
|
||||
EnableHeadCheck bool `mapstructure:"EnableHeadCheck"`
|
||||
}
|
||||
|
||||
// Config 是 TOML 文件映射的整体结构。
|
||||
type Config struct {
|
||||
Global GlobalConfig `mapstructure:",squash"`
|
||||
Hubs []HubConfig `mapstructure:"Hub"`
|
||||
}
|
||||
|
||||
// HasCredentials 表示当前 Hub 是否配置了完整的上游凭证。
|
||||
func (h HubConfig) HasCredentials() bool {
|
||||
return h.Username != "" && h.Password != ""
|
||||
}
|
||||
|
||||
// AuthMode 输出 `credentialed` 或 `anonymous`,供日志字段使用。
|
||||
func (h HubConfig) AuthMode() string {
|
||||
if h.HasCredentials() {
|
||||
return "credentialed"
|
||||
}
|
||||
return "anonymous"
|
||||
}
|
||||
|
||||
// CredentialModes 返回所有 Hub 的鉴权模式摘要,例如 secure:credentialed。
|
||||
func CredentialModes(hubs []HubConfig) []string {
|
||||
if len(hubs) == 0 {
|
||||
return nil
|
||||
}
|
||||
result := make([]string, len(hubs))
|
||||
for i, hub := range hubs {
|
||||
result[i] = fmt.Sprintf("%s:%s", hub.Name, hub.AuthMode())
|
||||
}
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user