mirror of
https://github.com/DullJZ/s3-balance.git
synced 2026-09-08 17:36:39 +08:00
Fix the deleted key issue
This commit is contained in:
@@ -388,7 +388,7 @@ func (h *S3Handler) handleCreateBucket(w http.ResponseWriter, r *http.Request, b
|
||||
|
||||
// 在负载均衡场景下,不真正创建bucket,只返回成功
|
||||
// 实际的bucket应该在配置中预先定义
|
||||
w.Header().Set("Location", "/" + bucketName)
|
||||
w.Header().Set("Location", "/"+bucketName)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
@@ -551,7 +551,7 @@ func (h *S3Handler) setObjectHeaders(w http.ResponseWriter, obj *storage.Object)
|
||||
}
|
||||
}
|
||||
|
||||
// handlePutObject 上传对象(默认使用预签名URL重定向)
|
||||
// handlePutObject 上传对象
|
||||
func (h *S3Handler) handlePutObject(w http.ResponseWriter, r *http.Request, bucketName string, key string) {
|
||||
// 检查请求的存储桶是否为虚拟存储桶
|
||||
requestedBucket, ok := h.bucketManager.GetBucket(bucketName)
|
||||
@@ -614,9 +614,7 @@ func (h *S3Handler) handlePutObject(w http.ResponseWriter, r *http.Request, buck
|
||||
return
|
||||
}
|
||||
|
||||
// 默认使用预签名重定向模式,只有明确指定时才使用代理模式
|
||||
if r.URL.Query().Get("proxy") == "true" {
|
||||
// 代理模式:读取请求体并上传到预签名URL
|
||||
// 只使用反向代理上传到真实预签名URL,不再返回307重定向
|
||||
// 创建新的请求
|
||||
req, err := http.NewRequest(uploadInfo.Method, uploadInfo.URL, r.Body)
|
||||
if err != nil {
|
||||
@@ -655,11 +653,6 @@ func (h *S3Handler) handlePutObject(w http.ResponseWriter, r *http.Request, buck
|
||||
} else {
|
||||
h.sendS3Error(w, "InternalError", "Upload failed", key)
|
||||
}
|
||||
} else {
|
||||
// 重定向模式:返回307临时重定向让客户端直接上传(默认)
|
||||
w.Header().Set("Location", uploadInfo.URL)
|
||||
w.WriteHeader(http.StatusTemporaryRedirect)
|
||||
}
|
||||
}
|
||||
|
||||
// handleDeleteObject 删除对象
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
// Object 对象信息模型
|
||||
type Object struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Key string `gorm:"uniqueIndex;size:512;not null" json:"key"`
|
||||
Key string `gorm:"size:512;not null" json:"key"`
|
||||
BucketName string `gorm:"index;size:255;not null" json:"bucket_name"`
|
||||
Size int64 `gorm:"not null;default:0" json:"size"`
|
||||
Metadata JSON `gorm:"type:json" json:"metadata,omitempty"`
|
||||
|
||||
@@ -21,6 +21,15 @@ func NewService(db *gorm.DB) *Service {
|
||||
|
||||
// RecordObject 记录对象信息
|
||||
func (s *Service) RecordObject(key, bucketName string, size int64, metadata map[string]string) error {
|
||||
// 首先检查是否存在已删除的同名对象
|
||||
var deletedObj Object
|
||||
if err := s.db.Unscoped().Where("`key` = ?", key).Where("`deleted_at` IS NOT NULL").First(&deletedObj).Error; err == nil {
|
||||
// 存在已删除的同名对象,永久删除它
|
||||
if err := s.db.Unscoped().Delete(&deletedObj).Error; err != nil {
|
||||
return fmt.Errorf("failed to permanently delete soft-deleted object: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
obj := &Object{
|
||||
Key: key,
|
||||
BucketName: bucketName,
|
||||
@@ -37,7 +46,7 @@ func (s *Service) RecordObject(key, bucketName string, size int64, metadata map[
|
||||
}
|
||||
|
||||
// 使用 Upsert(更新或插入)
|
||||
result := s.db.Where("`key` = ?", key).FirstOrCreate(&obj)
|
||||
result := s.db.Where("`key` = ?", key).Where("`deleted_at` IS NULL").FirstOrCreate(&obj)
|
||||
if result.Error != nil {
|
||||
return fmt.Errorf("failed to record object: %w", result.Error)
|
||||
}
|
||||
@@ -198,6 +207,9 @@ func (s *Service) updateBucketStats(bucketName string) error {
|
||||
// 获取或创建统计记录
|
||||
result := s.db.Where("bucket_name = ?", bucketName).FirstOrCreate(&stats, BucketStats{
|
||||
BucketName: bucketName,
|
||||
LastCheckedAt: time.Now(),
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
})
|
||||
if result.Error != nil {
|
||||
return fmt.Errorf("failed to get bucket stats: %w", result.Error)
|
||||
|
||||
Reference in New Issue
Block a user