feat: 004/phase 1
This commit is contained in:
@@ -5,10 +5,13 @@ import (
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/any-hub/any-hub/internal/hubmodule"
|
||||
)
|
||||
|
||||
// Load 读取并解析 TOML 配置文件,同时注入默认值与校验逻辑。
|
||||
@@ -86,6 +89,14 @@ func applyHubDefaults(h *HubConfig) {
|
||||
if h.CacheTTL.DurationValue() < 0 {
|
||||
h.CacheTTL = Duration(0)
|
||||
}
|
||||
if trimmed := strings.TrimSpace(h.Module); trimmed == "" {
|
||||
h.Module = hubmodule.DefaultModuleKey()
|
||||
} else {
|
||||
h.Module = strings.ToLower(trimmed)
|
||||
}
|
||||
if h.ValidationMode == "" {
|
||||
h.ValidationMode = string(hubmodule.ValidationModeETag)
|
||||
}
|
||||
}
|
||||
|
||||
func durationDecodeHook() mapstructure.DecodeHookFunc {
|
||||
|
||||
3
internal/config/modules.go
Normal file
3
internal/config/modules.go
Normal file
@@ -0,0 +1,3 @@
|
||||
package config
|
||||
|
||||
import _ "github.com/any-hub/any-hub/internal/hubmodule/legacy"
|
||||
25
internal/config/runtime.go
Normal file
25
internal/config/runtime.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/any-hub/any-hub/internal/hubmodule"
|
||||
)
|
||||
|
||||
// HubRuntime 将 Hub 配置与模块元数据合并,方便运行时快速取用策略。
|
||||
type HubRuntime struct {
|
||||
Config HubConfig
|
||||
Module hubmodule.ModuleMetadata
|
||||
CacheStrategy hubmodule.CacheStrategyProfile
|
||||
}
|
||||
|
||||
// BuildHubRuntime 根据 Hub 配置和模块元数据创建运行时描述。
|
||||
func BuildHubRuntime(cfg HubConfig, meta hubmodule.ModuleMetadata) HubRuntime {
|
||||
strategy := hubmodule.ResolveStrategy(meta, hubmodule.StrategyOptions{
|
||||
TTLOverride: cfg.CacheTTL.DurationValue(),
|
||||
ValidationOverride: hubmodule.ValidationMode(cfg.ValidationMode),
|
||||
})
|
||||
return HubRuntime{
|
||||
Config: cfg,
|
||||
Module: meta,
|
||||
CacheStrategy: strategy,
|
||||
}
|
||||
}
|
||||
@@ -67,9 +67,11 @@ type HubConfig struct {
|
||||
Upstream string `mapstructure:"Upstream"`
|
||||
Proxy string `mapstructure:"Proxy"`
|
||||
Type string `mapstructure:"Type"`
|
||||
Module string `mapstructure:"Module"`
|
||||
Username string `mapstructure:"Username"`
|
||||
Password string `mapstructure:"Password"`
|
||||
CacheTTL Duration `mapstructure:"CacheTTL"`
|
||||
ValidationMode string `mapstructure:"ValidationMode"`
|
||||
EnableHeadCheck bool `mapstructure:"EnableHeadCheck"`
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/any-hub/any-hub/internal/hubmodule"
|
||||
)
|
||||
|
||||
var supportedHubTypes = map[string]struct{}{
|
||||
@@ -74,6 +76,24 @@ func (c *Config) Validate() error {
|
||||
}
|
||||
hub.Type = normalizedType
|
||||
|
||||
moduleKey := strings.ToLower(strings.TrimSpace(hub.Module))
|
||||
if moduleKey == "" {
|
||||
moduleKey = hubmodule.DefaultModuleKey()
|
||||
}
|
||||
if _, ok := hubmodule.Resolve(moduleKey); !ok {
|
||||
return newFieldError(hubField(hub.Name, "Module"), fmt.Sprintf("未注册模块: %s", moduleKey))
|
||||
}
|
||||
hub.Module = moduleKey
|
||||
if hub.ValidationMode != "" {
|
||||
mode := strings.ToLower(strings.TrimSpace(hub.ValidationMode))
|
||||
switch mode {
|
||||
case string(hubmodule.ValidationModeETag), string(hubmodule.ValidationModeLastModified), string(hubmodule.ValidationModeNever):
|
||||
hub.ValidationMode = mode
|
||||
default:
|
||||
return newFieldError(hubField(hub.Name, "ValidationMode"), "仅支持 etag/last-modified/never")
|
||||
}
|
||||
}
|
||||
|
||||
if (hub.Username == "") != (hub.Password == "") {
|
||||
return newFieldError(hubField(hub.Name, "Username/Password"), "必须同时提供或同时留空")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user