mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-25 02:09:01 +02:00
refactor: remove forward auth, move module net/http to net/gphttp
This commit is contained in:
144
internal/net/gphttp/accesslog/formatter.go
Normal file
144
internal/net/gphttp/accesslog/formatter.go
Normal file
@@ -0,0 +1,144 @@
|
||||
package accesslog
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/yusing/go-proxy/internal/logging"
|
||||
)
|
||||
|
||||
type (
|
||||
CommonFormatter struct {
|
||||
cfg *Fields
|
||||
GetTimeNow func() time.Time // for testing purposes only
|
||||
}
|
||||
CombinedFormatter struct{ CommonFormatter }
|
||||
JSONFormatter struct{ CommonFormatter }
|
||||
|
||||
JSONLogEntry struct {
|
||||
Time string `json:"time"`
|
||||
IP string `json:"ip"`
|
||||
Method string `json:"method"`
|
||||
Scheme string `json:"scheme"`
|
||||
Host string `json:"host"`
|
||||
URI string `json:"uri"`
|
||||
Protocol string `json:"protocol"`
|
||||
Status int `json:"status"`
|
||||
Error string `json:"error,omitempty"`
|
||||
ContentType string `json:"type"`
|
||||
Size int64 `json:"size"`
|
||||
Referer string `json:"referer"`
|
||||
UserAgent string `json:"useragent"`
|
||||
Query map[string][]string `json:"query,omitempty"`
|
||||
Headers map[string][]string `json:"headers,omitempty"`
|
||||
Cookies map[string]string `json:"cookies,omitempty"`
|
||||
}
|
||||
)
|
||||
|
||||
const LogTimeFormat = "02/Jan/2006:15:04:05 -0700"
|
||||
|
||||
func scheme(req *http.Request) string {
|
||||
if req.TLS != nil {
|
||||
return "https"
|
||||
}
|
||||
return "http"
|
||||
}
|
||||
|
||||
func requestURI(u *url.URL, query url.Values) string {
|
||||
uri := u.EscapedPath()
|
||||
if len(query) > 0 {
|
||||
uri += "?" + query.Encode()
|
||||
}
|
||||
return uri
|
||||
}
|
||||
|
||||
func clientIP(req *http.Request) string {
|
||||
clientIP, _, err := net.SplitHostPort(req.RemoteAddr)
|
||||
if err == nil {
|
||||
return clientIP
|
||||
}
|
||||
return req.RemoteAddr
|
||||
}
|
||||
|
||||
// debug only.
|
||||
func (f *CommonFormatter) SetGetTimeNow(getTimeNow func() time.Time) {
|
||||
f.GetTimeNow = getTimeNow
|
||||
}
|
||||
|
||||
func (f *CommonFormatter) Format(line *bytes.Buffer, req *http.Request, res *http.Response) {
|
||||
query := f.cfg.Query.ProcessQuery(req.URL.Query())
|
||||
|
||||
line.WriteString(req.Host)
|
||||
line.WriteRune(' ')
|
||||
|
||||
line.WriteString(clientIP(req))
|
||||
line.WriteString(" - - [")
|
||||
|
||||
line.WriteString(f.GetTimeNow().Format(LogTimeFormat))
|
||||
line.WriteString("] \"")
|
||||
|
||||
line.WriteString(req.Method)
|
||||
line.WriteRune(' ')
|
||||
line.WriteString(requestURI(req.URL, query))
|
||||
line.WriteRune(' ')
|
||||
line.WriteString(req.Proto)
|
||||
line.WriteString("\" ")
|
||||
|
||||
line.WriteString(strconv.Itoa(res.StatusCode))
|
||||
line.WriteRune(' ')
|
||||
line.WriteString(strconv.FormatInt(res.ContentLength, 10))
|
||||
}
|
||||
|
||||
func (f *CombinedFormatter) Format(line *bytes.Buffer, req *http.Request, res *http.Response) {
|
||||
f.CommonFormatter.Format(line, req, res)
|
||||
line.WriteString(" \"")
|
||||
line.WriteString(req.Referer())
|
||||
line.WriteString("\" \"")
|
||||
line.WriteString(req.UserAgent())
|
||||
line.WriteRune('"')
|
||||
}
|
||||
|
||||
func (f *JSONFormatter) Format(line *bytes.Buffer, req *http.Request, res *http.Response) {
|
||||
query := f.cfg.Query.ProcessQuery(req.URL.Query())
|
||||
headers := f.cfg.Headers.ProcessHeaders(req.Header)
|
||||
headers.Del("Cookie")
|
||||
cookies := f.cfg.Cookies.ProcessCookies(req.Cookies())
|
||||
|
||||
entry := JSONLogEntry{
|
||||
Time: f.GetTimeNow().Format(LogTimeFormat),
|
||||
IP: clientIP(req),
|
||||
Method: req.Method,
|
||||
Scheme: scheme(req),
|
||||
Host: req.Host,
|
||||
URI: requestURI(req.URL, query),
|
||||
Protocol: req.Proto,
|
||||
Status: res.StatusCode,
|
||||
ContentType: res.Header.Get("Content-Type"),
|
||||
Size: res.ContentLength,
|
||||
Referer: req.Referer(),
|
||||
UserAgent: req.UserAgent(),
|
||||
Query: query,
|
||||
Headers: headers,
|
||||
Cookies: cookies,
|
||||
}
|
||||
|
||||
if res.StatusCode >= 400 {
|
||||
entry.Error = res.Status
|
||||
}
|
||||
|
||||
if entry.ContentType == "" {
|
||||
// try to get content type from request
|
||||
entry.ContentType = req.Header.Get("Content-Type")
|
||||
}
|
||||
|
||||
marshaller := json.NewEncoder(line)
|
||||
err := marshaller.Encode(entry)
|
||||
if err != nil {
|
||||
logging.Err(err).Msg("failed to marshal json log")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user