mirror of
https://github.com/DullJZ/s3-balance.git
synced 2026-09-06 16:27:38 +08:00
full proxy mode
This commit is contained in:
@@ -85,6 +85,7 @@ func main() {
|
|||||||
cfg.S3API.AccessKey,
|
cfg.S3API.AccessKey,
|
||||||
cfg.S3API.SecretKey,
|
cfg.S3API.SecretKey,
|
||||||
metricsService,
|
metricsService,
|
||||||
|
cfg.S3API.ProxyMode,
|
||||||
)
|
)
|
||||||
|
|
||||||
// 设置路由
|
// 设置路由
|
||||||
|
|||||||
@@ -138,9 +138,9 @@ s3api:
|
|||||||
virtual_host: false
|
virtual_host: false
|
||||||
|
|
||||||
# 工作模式:
|
# 工作模式:
|
||||||
# false (默认):预签名重定向模式,客户端直接与后端存储交互
|
# false:预签名重定向模式,客户端直接与后端存储交互
|
||||||
# true:代理模式,数据通过S3 Balance服务器传输
|
# true (默认):代理模式,数据通过S3 Balance服务器传输
|
||||||
proxy_mode: false
|
proxy_mode: true
|
||||||
|
|
||||||
# 是否需要认证(开发环境可设为false)
|
# 是否需要认证(开发环境可设为false)
|
||||||
auth_required: false
|
auth_required: false
|
||||||
|
|||||||
@@ -82,9 +82,9 @@ func (h *S3Handler) handleGetObject(w http.ResponseWriter, r *http.Request, buck
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认使用预签名重定向模式,只有明确指定时才使用代理模式
|
// 根据配置决定使用代理模式还是重定向模式
|
||||||
if r.URL.Query().Get("proxy") == "true" {
|
if h.proxyMode {
|
||||||
// 代理模式:服务器下载内容并返回给客户端
|
// 代理模式:流式传输内容给客户端
|
||||||
resp, err := http.Get(downloadInfo.URL)
|
resp, err := http.Get(downloadInfo.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.sendS3Error(w, "InternalError", "Failed to fetch object", key)
|
h.sendS3Error(w, "InternalError", "Failed to fetch object", key)
|
||||||
@@ -92,13 +92,38 @@ func (h *S3Handler) handleGetObject(w http.ResponseWriter, r *http.Request, buck
|
|||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
// 复制响应头
|
// 检查响应状态
|
||||||
for k, v := range resp.Header {
|
if resp.StatusCode != http.StatusOK {
|
||||||
w.Header()[k] = v
|
w.WriteHeader(resp.StatusCode)
|
||||||
|
io.Copy(w, resp.Body)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 复制响应体
|
// 复制重要的响应头
|
||||||
io.Copy(w, resp.Body)
|
if contentType := resp.Header.Get("Content-Type"); contentType != "" {
|
||||||
|
w.Header().Set("Content-Type", contentType)
|
||||||
|
}
|
||||||
|
if contentLength := resp.Header.Get("Content-Length"); contentLength != "" {
|
||||||
|
w.Header().Set("Content-Length", contentLength)
|
||||||
|
}
|
||||||
|
if lastModified := resp.Header.Get("Last-Modified"); lastModified != "" {
|
||||||
|
w.Header().Set("Last-Modified", lastModified)
|
||||||
|
}
|
||||||
|
if etag := resp.Header.Get("ETag"); etag != "" {
|
||||||
|
w.Header().Set("ETag", etag)
|
||||||
|
}
|
||||||
|
if contentEncoding := resp.Header.Get("Content-Encoding"); contentEncoding != "" {
|
||||||
|
w.Header().Set("Content-Encoding", contentEncoding)
|
||||||
|
}
|
||||||
|
if cacheControl := resp.Header.Get("Cache-Control"); cacheControl != "" {
|
||||||
|
w.Header().Set("Cache-Control", cacheControl)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 流式复制响应体
|
||||||
|
_, err = io.Copy(w, resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error streaming response body for key %s: %v", key, err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 重定向模式:返回302重定向到预签名URL(默认)
|
// 重定向模式:返回302重定向到预签名URL(默认)
|
||||||
http.Redirect(w, r, downloadInfo.URL, http.StatusFound)
|
http.Redirect(w, r, downloadInfo.URL, http.StatusFound)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ type S3Handler struct {
|
|||||||
accessKey string
|
accessKey string
|
||||||
secretKey string
|
secretKey string
|
||||||
metrics *metrics.Metrics
|
metrics *metrics.Metrics
|
||||||
|
proxyMode bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewS3Handler 创建新的S3兼容API处理器
|
// NewS3Handler 创建新的S3兼容API处理器
|
||||||
@@ -29,6 +30,7 @@ func NewS3Handler(
|
|||||||
accessKey string,
|
accessKey string,
|
||||||
secretKey string,
|
secretKey string,
|
||||||
metrics *metrics.Metrics,
|
metrics *metrics.Metrics,
|
||||||
|
proxyMode bool,
|
||||||
) *S3Handler {
|
) *S3Handler {
|
||||||
return &S3Handler{
|
return &S3Handler{
|
||||||
bucketManager: bucketManager,
|
bucketManager: bucketManager,
|
||||||
@@ -38,6 +40,7 @@ func NewS3Handler(
|
|||||||
accessKey: accessKey,
|
accessKey: accessKey,
|
||||||
secretKey: secretKey,
|
secretKey: secretKey,
|
||||||
metrics: metrics,
|
metrics: metrics,
|
||||||
|
proxyMode: proxyMode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -172,8 +172,8 @@ func (c *Config) SetDefaults() {
|
|||||||
if c.S3API.SecretKey == "" {
|
if c.S3API.SecretKey == "" {
|
||||||
c.S3API.SecretKey = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
c.S3API.SecretKey = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
||||||
}
|
}
|
||||||
// 默认使用预签名模式(非代理模式)
|
// 默认使用代理模式(避免302重定向)
|
||||||
c.S3API.ProxyMode = false
|
c.S3API.ProxyMode = true
|
||||||
c.S3API.AuthRequired = false
|
c.S3API.AuthRequired = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user