* Pass down SignedUserName down to AccessLogger context Unfortunately when the AccessLogger was moved back before the contexters the SignedUserName reporting was lost. This is due to Request.WithContext leading to a shallow copy of the Request and the modules/context/Context being within that request. This PR adds a new context variable of a string pointer which is set and handled in the contexters. Fix #16600 Signed-off-by: Andrew Thornton <art27@cantab.net> * handle nil ptr issue Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>tags/v1.16.0-rc1
@@ -6,6 +6,7 @@ package context | |||
import ( | |||
"bytes" | |||
"context" | |||
"html/template" | |||
"net/http" | |||
"time" | |||
@@ -22,6 +23,8 @@ type routerLoggerOptions struct { | |||
Ctx map[string]interface{} | |||
} | |||
var signedUserNameStringPointerKey interface{} = "signedUserNameStringPointerKey" | |||
// AccessLogger returns a middleware to log access logger | |||
func AccessLogger() func(http.Handler) http.Handler { | |||
logger := log.GetLogger("access") | |||
@@ -29,11 +32,10 @@ func AccessLogger() func(http.Handler) http.Handler { | |||
return func(next http.Handler) http.Handler { | |||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { | |||
start := time.Now() | |||
next.ServeHTTP(w, req) | |||
identity := "-" | |||
if val := SignedUserName(req); val != "" { | |||
identity = val | |||
} | |||
r := req.WithContext(context.WithValue(req.Context(), signedUserNameStringPointerKey, &identity)) | |||
next.ServeHTTP(w, r) | |||
rw := w.(ResponseWriter) | |||
buf := bytes.NewBuffer([]byte{}) |
@@ -275,6 +275,17 @@ func APIContexter() func(http.Handler) http.Handler { | |||
ctx.Data["CsrfToken"] = html.EscapeString(ctx.csrf.GetToken()) | |||
next.ServeHTTP(ctx.Resp, ctx.Req) | |||
// Handle adding signedUserName to the context for the AccessLogger | |||
usernameInterface := ctx.Data["SignedUserName"] | |||
identityPtrInterface := ctx.Req.Context().Value(signedUserNameStringPointerKey) | |||
if usernameInterface != nil && identityPtrInterface != nil { | |||
username := usernameInterface.(string) | |||
identityPtr := identityPtrInterface.(*string) | |||
if identityPtr != nil && username != "" { | |||
*identityPtr = username | |||
} | |||
} | |||
}) | |||
} | |||
} |
@@ -770,6 +770,17 @@ func Contexter() func(next http.Handler) http.Handler { | |||
} | |||
next.ServeHTTP(ctx.Resp, ctx.Req) | |||
// Handle adding signedUserName to the context for the AccessLogger | |||
usernameInterface := ctx.Data["SignedUserName"] | |||
identityPtrInterface := ctx.Req.Context().Value(signedUserNameStringPointerKey) | |||
if usernameInterface != nil && identityPtrInterface != nil { | |||
username := usernameInterface.(string) | |||
identityPtr := identityPtrInterface.(*string) | |||
if identityPtr != nil && username != "" { | |||
*identityPtr = username | |||
} | |||
} | |||
}) | |||
} | |||
} |