mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-05-31 05:56:21 +00:00
Authentication records the identity with r.WithContext, which returns a request copy. Handlers that log their own audit entry (PUT, DELETE, tagging) see it, but GET/HEAD object and IAM operations rely on track()'s fallback entry, which is built from the original request the auth copy never reached - so requester came out empty. Install a mutable identity holder on the request before authentication and have SetIdentityNameInContext record into it. The holder is shared by pointer across every request copy, so the fallback entry recovers the authenticated requester. The per-request context value still takes precedence, so nothing changes for handlers that see the auth copy.
63 lines
2.4 KiB
Go
63 lines
2.4 KiB
Go
package s3api
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/util/version"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/s3api/s3_constants"
|
|
"github.com/seaweedfs/seaweedfs/weed/s3api/s3err"
|
|
stats_collect "github.com/seaweedfs/seaweedfs/weed/stats"
|
|
)
|
|
|
|
func track(f http.HandlerFunc, action string) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
inFlightGauge := stats_collect.S3InFlightRequestsGauge.WithLabelValues(action)
|
|
inFlightGauge.Inc()
|
|
defer inFlightGauge.Dec()
|
|
|
|
bucket, _ := s3_constants.GetBucketAndObject(r)
|
|
w.Header().Set("Server", "SeaweedFS "+version.VERSION)
|
|
recorder := stats_collect.NewStatusResponseWriter(w)
|
|
// Attach an audit-tracking flag to the request so handlers that call
|
|
// PostLog directly mark it; we emit a fallback entry afterward for
|
|
// handlers (e.g. successful GET/HEAD object) that don't.
|
|
r = s3err.EnsureAuditTracking(r)
|
|
// Attach a mutable identity holder before authentication so the fallback
|
|
// entry can report the requester even though auth records it on a
|
|
// request copy this middleware never sees.
|
|
r = s3_constants.EnsureIdentityHolder(r)
|
|
start := time.Now()
|
|
f(recorder, r)
|
|
if recorder.Status == http.StatusForbidden {
|
|
bucket = ""
|
|
}
|
|
stats_collect.S3RequestHistogram.WithLabelValues(action, bucket).Observe(time.Since(start).Seconds())
|
|
stats_collect.S3RequestCounter.WithLabelValues(action, strconv.Itoa(recorder.Status), bucket).Inc()
|
|
stats_collect.RecordBucketActiveTime(bucket)
|
|
if !s3err.AuditAlreadyLogged(r) {
|
|
s3err.PostLog(r, recorder.Status, s3err.ErrNone)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TimeToFirstByte(action string, start time.Time, r *http.Request) {
|
|
bucket, _ := s3_constants.GetBucketAndObject(r)
|
|
stats_collect.S3TimeToFirstByteHistogram.WithLabelValues(action, bucket).Observe(float64(time.Since(start).Milliseconds()))
|
|
stats_collect.RecordBucketActiveTime(bucket)
|
|
}
|
|
|
|
func BucketTrafficReceived(bytesReceived int64, r *http.Request) {
|
|
bucket, _ := s3_constants.GetBucketAndObject(r)
|
|
stats_collect.RecordBucketActiveTime(bucket)
|
|
stats_collect.S3BucketTrafficReceivedBytesCounter.WithLabelValues(bucket).Add(float64(bytesReceived))
|
|
}
|
|
|
|
func BucketTrafficSent(bytesTransferred int64, r *http.Request) {
|
|
bucket, _ := s3_constants.GetBucketAndObject(r)
|
|
stats_collect.RecordBucketActiveTime(bucket)
|
|
stats_collect.S3BucketTrafficSentBytesCounter.WithLabelValues(bucket).Add(float64(bytesTransferred))
|
|
}
|