This commit is contained in:
fancl 2023-07-07 09:53:37 +08:00
parent a995627a52
commit 4114e5fcb0
7 changed files with 112 additions and 52 deletions

View File

@ -14,6 +14,15 @@ var (
defaultBinder = &DefaultBinder{} defaultBinder = &DefaultBinder{}
) )
var (
realIPHeaders = []string{
"Cf-Connecting-Ip",
"True-Client-IP",
"X-Forwarded-For",
"X-Real-Ip",
}
)
type Context struct { type Context struct {
ctx context.Context ctx context.Context
req *http.Request req *http.Request
@ -28,18 +37,21 @@ func (ctx *Context) reset(req *http.Request, res http.ResponseWriter, ps map[str
} }
func (ctx *Context) RealIp() string { func (ctx *Context) RealIp() string {
if ip := ctx.Request().Header.Get("X-Forwarded-For"); ip != "" { var (
i := strings.IndexAny(ip, ",") pos int
if i > 0 { ipaddr string
return strings.TrimSpace(ip[:i]) )
for _, h := range realIPHeaders {
if ipaddr = ctx.Request().Header.Get(h); ipaddr != "" {
goto __end
} }
return ip
} }
if ip := ctx.Request().Header.Get("X-Real-IP"); ip != "" { ipaddr, _, _ = net.SplitHostPort(ctx.Request().RemoteAddr)
return ip __end:
if pos = strings.LastIndexByte(ipaddr, ','); pos > -1 {
ipaddr = ipaddr[:pos]
} }
ra, _, _ := net.SplitHostPort(ctx.Request().RemoteAddr) return ipaddr
return ra
} }
func (ctx *Context) Request() *http.Request { func (ctx *Context) Request() *http.Request {
@ -76,7 +88,7 @@ func (ctx *Context) Param(k string) string {
return ctx.Request().FormValue(k) return ctx.Request().FormValue(k)
} }
func (ctx *Context) send(res responsePayload) (err error) { func (ctx *Context) json(res responsePayload) (err error) {
ctx.Response().Header().Set("Content-Type", "application/json") ctx.Response().Header().Set("Content-Type", "application/json")
encoder := json.NewEncoder(ctx.Response()) encoder := json.NewEncoder(ctx.Response())
if strings.HasPrefix(ctx.Request().Header.Get("User-Agent"), "curl") { if strings.HasPrefix(ctx.Request().Header.Get("User-Agent"), "curl") {
@ -86,7 +98,7 @@ func (ctx *Context) send(res responsePayload) (err error) {
} }
func (ctx *Context) Success(v any) (err error) { func (ctx *Context) Success(v any) (err error) {
return ctx.send(responsePayload{Data: v}) return ctx.json(responsePayload{Data: v})
} }
func (ctx *Context) Status(code int) { func (ctx *Context) Status(code int) {
@ -94,7 +106,7 @@ func (ctx *Context) Status(code int) {
} }
func (ctx *Context) Error(code int, reason string) (err error) { func (ctx *Context) Error(code int, reason string) (err error) {
return ctx.send(responsePayload{Code: code, Reason: reason}) return ctx.json(responsePayload{Code: code, Reason: reason})
} }
func (ctx *Context) Redirect(url string, code int) { func (ctx *Context) Redirect(url string, code int) {

View File

@ -3,6 +3,8 @@ package kos
import ( import (
"git.nspix.com/golang/kos/entry/cli" "git.nspix.com/golang/kos/entry/cli"
"git.nspix.com/golang/kos/entry/http" "git.nspix.com/golang/kos/entry/http"
_ "git.nspix.com/golang/kos/pkg/request"
_ "git.nspix.com/golang/kos/util/bs"
_ "git.nspix.com/golang/kos/util/fetch" _ "git.nspix.com/golang/kos/util/fetch"
_ "git.nspix.com/golang/kos/util/random" _ "git.nspix.com/golang/kos/util/random"
_ "git.nspix.com/golang/kos/util/reflection" _ "git.nspix.com/golang/kos/util/reflection"

View File

@ -92,6 +92,6 @@ func NewOptions() *Options {
Signals: []os.Signal{syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL}, Signals: []os.Signal{syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL},
} }
opts.Port = int(env.Integer(18080, EnvAppPort, "HTTP_PORT", "KOS_PORT")) opts.Port = int(env.Integer(18080, EnvAppPort, "HTTP_PORT", "KOS_PORT"))
opts.Address = env.Get(EnvAppAddress, ip.Internal()) opts.Address = env.Getter(ip.Internal(), EnvAppAddress, "KOS_ADDRESS")
return opts return opts
} }

View File

@ -2,6 +2,8 @@ package log
import ( import (
"fmt" "fmt"
"git.nspix.com/golang/kos/util/env"
"strconv"
"time" "time"
) )
@ -16,9 +18,22 @@ const (
FG_GREY = 37 FG_GREY = 37
) )
var (
levelColor = map[int]int{
TraceLevel: FG_GREY,
DebugLevel: FG_BLUE,
InfoLevel: FG_GREEN,
WarnLevel: FG_PURPLE,
ErrorLevel: FG_RED,
FatalLevel: FG_RED,
PanicLevel: FG_RED,
}
)
type Console struct { type Console struct {
Level int Level int
EnableColor int DisableColor bool
DisableTime bool
prefix string prefix string
} }
@ -87,32 +102,29 @@ func (log *Console) Panicf(format string, args ...interface{}) {
} }
func (log *Console) write(level int, s string) { func (log *Console) write(level int, s string) {
var ls string
if log.Level > level { if log.Level > level {
return return
} }
lvColor := map[int]int{ if log.DisableColor {
TraceLevel: FG_GREY,
DebugLevel: FG_BLUE,
InfoLevel: FG_GREEN,
WarnLevel: FG_PURPLE,
ErrorLevel: FG_RED,
FatalLevel: FG_RED,
PanicLevel: FG_RED,
}
var ls string
if log.EnableColor > 0 {
ls = fmt.Sprintf("\033[0m\033[%dm[%s]\033[0m", lvColor[level], getLevelText(level))
} else {
ls = getLevelText(level) ls = getLevelText(level)
} else {
ls = fmt.Sprintf("\033[0m\033[%dm[%s]\033[0m", levelColor[level], getLevelText(level))
} }
if log.prefix != "" { if log.prefix != "" {
ls += " [" + log.prefix + "]" ls += " [" + log.prefix + "]"
} }
if log.DisableTime {
fmt.Println(ls + " " + s)
} else {
fmt.Println(time.Now().Format("2006-01-02 15:04:05") + " " + ls + " " + s) fmt.Println(time.Now().Format("2006-01-02 15:04:05") + " " + ls + " " + s)
}
} }
func NewConsoleLogger() *Console { func NewConsoleLogger() *Console {
return &Console{ lg := &Console{}
EnableColor: 1, lg.DisableColor, _ = strconv.ParseBool(env.Get("VOX_DISABLE_LOG_COLOR", "false"))
} lg.DisableTime, _ = strconv.ParseBool(env.Get("VOX_DISABLE_LOG_DATETIME", "false"))
return lg
} }

12
util/bs/safe.go 100644
View File

@ -0,0 +1,12 @@
//go:build appengine
// +build appengine
package bs
func BytesToString(b []byte) string {
return string(b)
}
func StringToBytes(s string) []byte {
return []byte(s)
}

23
util/bs/unsafe.go 100644
View File

@ -0,0 +1,23 @@
//go:build !appengine
// +build !appengine
package bs
import (
"unsafe"
)
// BytesToString converts byte slice to string.
func BytesToString(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
// StringToBytes converts string to byte slice.
func StringToBytes(s string) []byte {
return *(*[]byte)(unsafe.Pointer(
&struct {
string
Cap int
}{s, len(s)},
))
}

View File

@ -7,17 +7,17 @@ import (
"strings" "strings"
) )
var (
allowTags = []string{"json", "yaml", "xml", "name"}
)
func findField(v reflect.Value, field string) reflect.Value { func findField(v reflect.Value, field string) reflect.Value {
var ( var (
pos int pos int
tagValue string tagValue string
refValue reflect.Value
refType reflect.Type refType reflect.Type
fieldType reflect.StructField fieldType reflect.StructField
allowTags = []string{"json", "yaml", "xml"}
) )
refValue = v.FieldByName(field)
if !refValue.IsValid() {
refType = v.Type() refType = v.Type()
for i := 0; i < refType.NumField(); i++ { for i := 0; i < refType.NumField(); i++ {
fieldType = refType.Field(i) fieldType = refType.Field(i)
@ -26,7 +26,7 @@ func findField(v reflect.Value, field string) reflect.Value {
if tagValue == "" { if tagValue == "" {
continue continue
} }
if pos = strings.Index(tagValue, ","); pos != -1 { if pos = strings.IndexByte(tagValue, ','); pos != -1 {
tagValue = tagValue[:pos] tagValue = tagValue[:pos]
} }
if tagValue == field { if tagValue == field {
@ -34,8 +34,7 @@ func findField(v reflect.Value, field string) reflect.Value {
} }
} }
} }
} return v.FieldByName(field)
return refValue
} }
func safeAssignment(variable reflect.Value, value interface{}) (err error) { func safeAssignment(variable reflect.Value, value interface{}) (err error) {