mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-05-25 11:22:16 +00:00
Fix access log (#14475)
Fix #14121, #14478. The `AccessLog` middleware has to be after `Contexter` or `APIContexter` so that we can get `LoginUserName` if possible. And also there is a **BREAK** change that it removed internal API access log.
This commit is contained in:
parent
4c6e029506
commit
a51cc6dea4
10 changed files with 129 additions and 72 deletions
60
modules/context/access_log.go
Normal file
60
modules/context/access_log.go
Normal file
|
@ -0,0 +1,60 @@
|
|||
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package context
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
type routerLoggerOptions struct {
|
||||
req *http.Request
|
||||
Identity *string
|
||||
Start *time.Time
|
||||
ResponseWriter http.ResponseWriter
|
||||
Ctx map[string]interface{}
|
||||
}
|
||||
|
||||
// AccessLogger returns a middleware to log access logger
|
||||
func AccessLogger() func(http.Handler) http.Handler {
|
||||
logger := log.GetLogger("access")
|
||||
logTemplate, _ := template.New("log").Parse(setting.AccessLogTemplate)
|
||||
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
|
||||
}
|
||||
rw := w.(ResponseWriter)
|
||||
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
err := logTemplate.Execute(buf, routerLoggerOptions{
|
||||
req: req,
|
||||
Identity: &identity,
|
||||
Start: &start,
|
||||
ResponseWriter: rw,
|
||||
Ctx: map[string]interface{}{
|
||||
"RemoteAddr": req.RemoteAddr,
|
||||
"Req": req,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
log.Error("Could not set up chi access logger: %v", err.Error())
|
||||
}
|
||||
|
||||
err = logger.SendLog(log.INFO, "", "", 0, buf.String(), "")
|
||||
if err != nil {
|
||||
log.Error("Could not set up chi access logger: %v", err.Error())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -485,6 +485,31 @@ func GetContext(req *http.Request) *Context {
|
|||
return req.Context().Value(contextKey).(*Context)
|
||||
}
|
||||
|
||||
// SignedUserName returns signed user's name via context
|
||||
func SignedUserName(req *http.Request) string {
|
||||
if middlewares.IsInternalPath(req) {
|
||||
return ""
|
||||
}
|
||||
if middlewares.IsAPIPath(req) {
|
||||
ctx, ok := req.Context().Value(apiContextKey).(*APIContext)
|
||||
if ok {
|
||||
v := ctx.Data["SignedUserName"]
|
||||
if res, ok := v.(string); ok {
|
||||
return res
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ctx, ok := req.Context().Value(contextKey).(*Context)
|
||||
if ok {
|
||||
v := ctx.Data["SignedUserName"]
|
||||
if res, ok := v.(string); ok {
|
||||
return res
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func getCsrfOpts() CsrfOptions {
|
||||
return CsrfOptions{
|
||||
Secret: setting.SecretKey,
|
||||
|
|
|
@ -12,6 +12,7 @@ type ResponseWriter interface {
|
|||
Flush()
|
||||
Status() int
|
||||
Before(func(ResponseWriter))
|
||||
Size() int
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -21,11 +22,17 @@ var (
|
|||
// Response represents a response
|
||||
type Response struct {
|
||||
http.ResponseWriter
|
||||
written int
|
||||
status int
|
||||
befores []func(ResponseWriter)
|
||||
beforeExecuted bool
|
||||
}
|
||||
|
||||
// Size return written size
|
||||
func (r *Response) Size() int {
|
||||
return r.written
|
||||
}
|
||||
|
||||
// Write writes bytes to HTTP endpoint
|
||||
func (r *Response) Write(bs []byte) (int, error) {
|
||||
if !r.beforeExecuted {
|
||||
|
@ -35,8 +42,9 @@ func (r *Response) Write(bs []byte) (int, error) {
|
|||
r.beforeExecuted = true
|
||||
}
|
||||
size, err := r.ResponseWriter.Write(bs)
|
||||
r.written += size
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return size, err
|
||||
}
|
||||
if r.status == 0 {
|
||||
r.WriteHeader(200)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue