Files
s3-balance/internal/api/utils.go
2025-10-04 15:18:45 +08:00

70 lines
1.9 KiB
Go

package api
import (
"encoding/xml"
"fmt"
"net/http"
"strconv"
"time"
"github.com/DullJZ/s3-balance/internal/storage"
)
// sendXMLResponse 发送XML响应
func (h *S3Handler) sendXMLResponse(w http.ResponseWriter, statusCode int, data interface{}) {
w.Header().Set("Content-Type", "application/xml")
w.WriteHeader(statusCode)
encoder := xml.NewEncoder(w)
encoder.Indent("", " ")
// 写入XML声明
w.Write([]byte(xml.Header))
if err := encoder.Encode(data); err != nil {
// 如果编码失败,记录错误
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
}
// sendS3Error 发送S3错误响应
func (h *S3Handler) sendS3Error(w http.ResponseWriter, code string, message string, resource string) {
errorResp := ErrorResponse{
Code: code,
Message: message,
Resource: resource,
RequestID: fmt.Sprintf("%d", time.Now().UnixNano()),
}
w.Header().Set("X-Amz-Error-Code", code)
w.Header().Set("X-Amz-Error-Message", message)
statusCode := http.StatusBadRequest
switch code {
case "NoSuchBucket", "NoSuchKey":
statusCode = http.StatusNotFound
case "BucketAlreadyExists":
statusCode = http.StatusConflict
case "InvalidAccessKeyId", "SignatureDoesNotMatch", "AccessDenied":
statusCode = http.StatusForbidden
case "InternalError":
statusCode = http.StatusInternalServerError
case "InsufficientStorage":
statusCode = http.StatusInsufficientStorage
}
h.sendXMLResponse(w, statusCode, errorResp)
}
// setObjectHeaders 设置对象响应头
func (h *S3Handler) setObjectHeaders(w http.ResponseWriter, obj *storage.Object) {
w.Header().Set("Content-Length", strconv.FormatInt(obj.Size, 10))
w.Header().Set("Last-Modified", obj.UpdatedAt.Format(http.TimeFormat))
w.Header().Set("ETag", fmt.Sprintf("\"%x\"", obj.ID))
if obj.ContentType != "" {
w.Header().Set("Content-Type", obj.ContentType)
} else {
w.Header().Set("Content-Type", "application/octet-stream")
}
}