mirror of
https://github.com/DullJZ/s3-balance.git
synced 2026-09-07 00:46:38 +08:00
Support custom host
This commit is contained in:
@@ -92,6 +92,7 @@ func main() {
|
|||||||
cfg.S3API.ProxyMode,
|
cfg.S3API.ProxyMode,
|
||||||
cfg.S3API.AuthRequired,
|
cfg.S3API.AuthRequired,
|
||||||
cfg.S3API.VirtualHost,
|
cfg.S3API.VirtualHost,
|
||||||
|
cfg.S3API.Host,
|
||||||
)
|
)
|
||||||
|
|
||||||
// 注册配置热更新回调
|
// 注册配置热更新回调
|
||||||
|
|||||||
@@ -138,3 +138,9 @@ s3api:
|
|||||||
|
|
||||||
# 是否需要认证(开启后使用 Basic Auth,凭据来自 access_key/secret_key)
|
# 是否需要认证(开启后使用 Basic Auth,凭据来自 access_key/secret_key)
|
||||||
auth_required: true
|
auth_required: true
|
||||||
|
|
||||||
|
# 用于签名验证的Host(可选)
|
||||||
|
# 当服务前有 nginx 等反向代理时,可以设置此项为客户端实际访问的域名
|
||||||
|
# 留空则使用请求中的 Host 头
|
||||||
|
# 示例: "s3.example.com" 或 "s3.example.com:8080"
|
||||||
|
host: ""
|
||||||
|
|||||||
@@ -56,4 +56,5 @@ s3api:
|
|||||||
secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
||||||
virtual_host: false
|
virtual_host: false
|
||||||
proxy_mode: true
|
proxy_mode: true
|
||||||
auth_required: true
|
auth_required: true
|
||||||
|
host: ""
|
||||||
+25
-15
@@ -29,6 +29,7 @@ type handlerSettings struct {
|
|||||||
proxyMode bool
|
proxyMode bool
|
||||||
authRequired bool
|
authRequired bool
|
||||||
virtualHost bool
|
virtualHost bool
|
||||||
|
signatureHost string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewS3Handler 创建新的S3兼容API处理器
|
// NewS3Handler 创建新的S3兼容API处理器
|
||||||
@@ -43,6 +44,7 @@ func NewS3Handler(
|
|||||||
proxyMode bool,
|
proxyMode bool,
|
||||||
authRequired bool,
|
authRequired bool,
|
||||||
virtualHost bool,
|
virtualHost bool,
|
||||||
|
signatureHost string,
|
||||||
|
|
||||||
) *S3Handler {
|
) *S3Handler {
|
||||||
handler := &S3Handler{
|
handler := &S3Handler{
|
||||||
@@ -52,17 +54,18 @@ func NewS3Handler(
|
|||||||
storage: storage,
|
storage: storage,
|
||||||
metrics: metrics,
|
metrics: metrics,
|
||||||
}
|
}
|
||||||
handler.initSettings(accessKey, secretKey, proxyMode, authRequired, virtualHost)
|
handler.initSettings(accessKey, secretKey, proxyMode, authRequired, virtualHost, signatureHost)
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *S3Handler) initSettings(accessKey, secretKey string, proxyMode, authRequired, virtualHost bool) {
|
func (h *S3Handler) initSettings(accessKey, secretKey string, proxyMode, authRequired, virtualHost bool, signatureHost string) {
|
||||||
h.settings.Store(handlerSettings{
|
h.settings.Store(handlerSettings{
|
||||||
accessKey: accessKey,
|
accessKey: accessKey,
|
||||||
secretKey: secretKey,
|
secretKey: secretKey,
|
||||||
proxyMode: proxyMode,
|
proxyMode: proxyMode,
|
||||||
authRequired: authRequired,
|
authRequired: authRequired,
|
||||||
virtualHost: virtualHost,
|
virtualHost: virtualHost,
|
||||||
|
signatureHost: signatureHost,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,10 +102,12 @@ func (h *S3Handler) RegisterS3Routes(router *mux.Router) {
|
|||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
protected.Use(middleware.S3Signature(middleware.S3SignatureConfig{
|
protected.Use(middleware.S3Signature(middleware.S3SignatureConfig{
|
||||||
Required: h.authRequired,
|
Required: h.authRequired,
|
||||||
Credentials: h.credentials,
|
Credentials: h.credentials,
|
||||||
OnError: h.sendS3Error,
|
OnError: h.sendS3Error,
|
||||||
|
SignatureHost: h.signatureHost,
|
||||||
}))
|
}))
|
||||||
|
protected.Use(h.accessLogMiddleware)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *S3Handler) loadSettings() handlerSettings {
|
func (h *S3Handler) loadSettings() handlerSettings {
|
||||||
@@ -129,15 +134,20 @@ func (h *S3Handler) proxyModeEnabled() bool {
|
|||||||
return h.loadSettings().proxyMode
|
return h.loadSettings().proxyMode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *S3Handler) signatureHost() string {
|
||||||
|
return h.loadSettings().signatureHost
|
||||||
|
}
|
||||||
|
|
||||||
func (h *S3Handler) UpdateS3APIConfig(cfg *config.S3APIConfig) {
|
func (h *S3Handler) UpdateS3APIConfig(cfg *config.S3APIConfig) {
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
h.settings.Store(handlerSettings{
|
h.settings.Store(handlerSettings{
|
||||||
accessKey: cfg.AccessKey,
|
accessKey: cfg.AccessKey,
|
||||||
secretKey: cfg.SecretKey,
|
secretKey: cfg.SecretKey,
|
||||||
proxyMode: cfg.ProxyMode,
|
proxyMode: cfg.ProxyMode,
|
||||||
authRequired: cfg.AuthRequired,
|
authRequired: cfg.AuthRequired,
|
||||||
virtualHost: cfg.VirtualHost,
|
virtualHost: cfg.VirtualHost,
|
||||||
|
signatureHost: cfg.Host,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ type S3APIConfig struct {
|
|||||||
VirtualHost bool `yaml:"virtual_host"` // 是否使用虚拟主机模式
|
VirtualHost bool `yaml:"virtual_host"` // 是否使用虚拟主机模式
|
||||||
ProxyMode bool `yaml:"proxy_mode"` // 是否使用代理模式(而非重定向)
|
ProxyMode bool `yaml:"proxy_mode"` // 是否使用代理模式(而非重定向)
|
||||||
AuthRequired bool `yaml:"auth_required"` // 是否需要认证
|
AuthRequired bool `yaml:"auth_required"` // 是否需要认证
|
||||||
|
Host string `yaml:"host"` // 用于签名验证的Host(为空则使用请求的Host)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DatabaseConfig 数据库配置
|
// DatabaseConfig 数据库配置
|
||||||
|
|||||||
@@ -10,9 +10,10 @@ import (
|
|||||||
|
|
||||||
// S3SignatureConfig controls S3 signature validation.
|
// S3SignatureConfig controls S3 signature validation.
|
||||||
type S3SignatureConfig struct {
|
type S3SignatureConfig struct {
|
||||||
Required func() bool
|
Required func() bool
|
||||||
Credentials func() (string, string)
|
Credentials func() (string, string)
|
||||||
OnError func(http.ResponseWriter, string, string, string)
|
OnError func(http.ResponseWriter, string, string, string)
|
||||||
|
SignatureHost func() string // 用于签名验证的Host(为空则使用请求的Host)
|
||||||
}
|
}
|
||||||
|
|
||||||
// credentialsProvider implements s3validate.CredentialsProvider interface.
|
// credentialsProvider implements s3validate.CredentialsProvider interface.
|
||||||
@@ -47,6 +48,13 @@ func S3Signature(cfg S3SignatureConfig) func(http.Handler) http.Handler {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果配置了签名验证的Host,覆盖请求的Host
|
||||||
|
if cfg.SignatureHost != nil {
|
||||||
|
if signatureHost := cfg.SignatureHost(); signatureHost != "" {
|
||||||
|
r.Host = signatureHost
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
result, err := verifier.Verify(r.Context(), r)
|
result, err := verifier.Verify(r.Context(), r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
invokeOnError(w, cfg, "SignatureDoesNotMatch", err.Error())
|
invokeOnError(w, cfg, "SignatureDoesNotMatch", err.Error())
|
||||||
|
|||||||
Reference in New Issue
Block a user