mirror of
https://github.com/DullJZ/s3-balance.git
synced 2026-09-06 00:06:38 +08:00
Support setting host & recording error req
This commit is contained in:
@@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"errors"
|
||||
"log"
|
||||
"net"
|
||||
@@ -12,6 +13,12 @@ import (
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
type accessLogContextKey string
|
||||
|
||||
const (
|
||||
errorCodeKey accessLogContextKey = "errorCode"
|
||||
)
|
||||
|
||||
func (h *S3Handler) accessLogMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if h.storage == nil {
|
||||
@@ -34,7 +41,10 @@ func (h *S3Handler) accessLogMiddleware(next http.Handler) http.Handler {
|
||||
success := lrw.statusCode < 400
|
||||
errMsg := ""
|
||||
if !success {
|
||||
if code := lrw.Header().Get("X-Amz-Error-Code"); code != "" {
|
||||
// 优先使用context中的错误码(auth错误设置的)
|
||||
if code, ok := r.Context().Value(errorCodeKey).(string); ok && code != "" {
|
||||
errMsg = code
|
||||
} else if code := lrw.Header().Get("X-Amz-Error-Code"); code != "" {
|
||||
errMsg = code
|
||||
} else {
|
||||
errMsg = http.StatusText(lrw.statusCode)
|
||||
@@ -50,14 +60,23 @@ func (h *S3Handler) accessLogMiddleware(next http.Handler) http.Handler {
|
||||
func (h *S3Handler) recordAccessLog(r *http.Request, action, bucket, key string, size int64, success bool, errMsg string, duration time.Duration) {
|
||||
clientIP := extractClientIP(r)
|
||||
userAgent := r.UserAgent()
|
||||
host := r.Host
|
||||
// 异步记录日志,避免阻塞请求响应
|
||||
go func() {
|
||||
if err := h.storage.RecordAccessLog(action, key, bucket, clientIP, userAgent, size, success, errMsg, duration.Milliseconds()); err != nil {
|
||||
if err := h.storage.RecordAccessLog(action, key, bucket, clientIP, userAgent, host, size, success, errMsg, duration.Milliseconds()); err != nil {
|
||||
log.Printf("failed to record access log: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (h *S3Handler) handleAuthError(w http.ResponseWriter, r *http.Request, code, message, resource string) {
|
||||
// 将错误码存入context,供accessLogMiddleware使用
|
||||
ctx := context.WithValue(r.Context(), errorCodeKey, code)
|
||||
*r = *r.WithContext(ctx)
|
||||
|
||||
h.sendS3Error(w, code, message, resource)
|
||||
}
|
||||
|
||||
type loggingResponseWriter struct {
|
||||
http.ResponseWriter
|
||||
statusCode int
|
||||
|
||||
@@ -24,11 +24,11 @@ type S3Handler struct {
|
||||
}
|
||||
|
||||
type handlerSettings struct {
|
||||
accessKey string
|
||||
secretKey string
|
||||
proxyMode bool
|
||||
authRequired bool
|
||||
virtualHost bool
|
||||
accessKey string
|
||||
secretKey string
|
||||
proxyMode bool
|
||||
authRequired bool
|
||||
virtualHost bool
|
||||
signatureHost string
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ func (h *S3Handler) RegisterS3Routes(router *mux.Router) {
|
||||
protected.HandleFunc("/{key:.*}", h.handleObjectOperations).Methods("GET", "HEAD", "PUT", "DELETE")
|
||||
|
||||
// 添加中间件
|
||||
protected.Use(h.accessLogMiddleware)
|
||||
protected.Use(middleware.VirtualHost(middleware.VirtualHostConfig{
|
||||
Enabled: h.virtualHostEnabled,
|
||||
BucketExists: func(name string) bool {
|
||||
@@ -104,10 +105,9 @@ func (h *S3Handler) RegisterS3Routes(router *mux.Router) {
|
||||
protected.Use(middleware.S3Signature(middleware.S3SignatureConfig{
|
||||
Required: h.authRequired,
|
||||
Credentials: h.credentials,
|
||||
OnError: h.sendS3Error,
|
||||
OnError: h.handleAuthError,
|
||||
SignatureHost: h.signatureHost,
|
||||
}))
|
||||
protected.Use(h.accessLogMiddleware)
|
||||
}
|
||||
|
||||
func (h *S3Handler) loadSettings() handlerSettings {
|
||||
|
||||
Reference in New Issue
Block a user