Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
23d7841ccf | |||
247490c35d | |||
fad0b852cb |
83
api/api.go
83
api/api.go
@ -4,34 +4,89 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
|
"gitea.loveuer.com/yizhisec/packages/handler"
|
||||||
"gitea.loveuer.com/yizhisec/packages/logger"
|
"gitea.loveuer.com/yizhisec/packages/logger"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Api struct {
|
type Option func(*option)
|
||||||
Address string
|
|
||||||
Name string
|
type option struct {
|
||||||
App *gin.Engine
|
name string
|
||||||
TlsConfig *tls.Config
|
version string
|
||||||
|
address string
|
||||||
|
app *gin.Engine
|
||||||
|
tlsConfig *tls.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(ctx context.Context, api *Api) (func(context.Context) error, error) {
|
func WithName(name string) Option {
|
||||||
|
return func(o *option) {
|
||||||
|
if name == "" {
|
||||||
|
o.name = name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithVersion(version string) Option {
|
||||||
|
return func(o *option) {
|
||||||
|
if version == "" {
|
||||||
|
o.version = version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithAddress(address string) Option {
|
||||||
|
return func(o *option) {
|
||||||
|
if address == "" {
|
||||||
|
o.address = address
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithApp(app *gin.Engine) Option {
|
||||||
|
return func(o *option) {
|
||||||
|
if app != nil {
|
||||||
|
o.app = app
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithTLSConfig(tlsConfig *tls.Config) Option {
|
||||||
|
return func(o *option) {
|
||||||
|
if tlsConfig != nil {
|
||||||
|
o.tlsConfig = tlsConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(ctx context.Context, optFns ...Option) (func(context.Context) error, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
fn func(context.Context) error
|
fn func(context.Context) error
|
||||||
ln net.Listener
|
ln net.Listener
|
||||||
|
opt = &option{
|
||||||
|
name: "unknown",
|
||||||
|
version: "v0.0.1",
|
||||||
|
address: "127.0.0.1:9119",
|
||||||
|
tlsConfig: nil,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
if api == nil {
|
for _, ofn := range optFns {
|
||||||
return fn, errors.New("api is nil")
|
ofn(opt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if api.TlsConfig != nil {
|
if opt.app == nil {
|
||||||
ln, err = tls.Listen("tcp", api.Address, api.TlsConfig)
|
opt.app = gin.Default()
|
||||||
|
opt.app.GET("/healthz", handler.Healthz(opt.name, opt.version))
|
||||||
|
}
|
||||||
|
|
||||||
|
if opt.tlsConfig != nil {
|
||||||
|
ln, err = tls.Listen("tcp", opt.address, opt.tlsConfig)
|
||||||
} else {
|
} else {
|
||||||
ln, err = net.Listen("tcp", api.Address)
|
ln, err = net.Listen("tcp", opt.address)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -39,11 +94,11 @@ func New(ctx context.Context, api *Api) (func(context.Context) error, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
svc := &http.Server{
|
svc := &http.Server{
|
||||||
Handler: api.App,
|
Handler: opt.app,
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
logger.InfoCtx(ctx, "[%s] api svc running at: %s", api.Name, api.Address)
|
logger.InfoCtx(ctx, "[%s] api svc running at: %s", opt.name, opt.address)
|
||||||
if err = svc.Serve(ln); err != nil {
|
if err = svc.Serve(ln); err != nil {
|
||||||
if !errors.Is(err, http.ErrServerClosed) {
|
if !errors.Is(err, http.ErrServerClosed) {
|
||||||
logger.ErrorCtx(ctx, "api svc run failed, err = %s", err.Error())
|
logger.ErrorCtx(ctx, "api svc run failed, err = %s", err.Error())
|
||||||
@ -52,7 +107,7 @@ func New(ctx context.Context, api *Api) (func(context.Context) error, error) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
fn = func(timeout context.Context) error {
|
fn = func(timeout context.Context) error {
|
||||||
logger.WarnCtx(ctx, "[%s] api svc shutdown...", api.Name)
|
logger.WarnCtx(ctx, "[%s] api svc shutdown...", opt.name)
|
||||||
return svc.Shutdown(timeout)
|
return svc.Shutdown(timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
handler/healthz.go
Normal file
19
handler/healthz.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gitea.loveuer.com/yizhisec/packages/resp"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Healthz(name, version string) gin.HandlerFunc {
|
||||||
|
start := time.Now()
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
resp.R200(c, gin.H{
|
||||||
|
"name": name,
|
||||||
|
"version": version,
|
||||||
|
"start_at": start,
|
||||||
|
"uptime": time.Since(start).String(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ const (
|
|||||||
Msg400 = "参数错误"
|
Msg400 = "参数错误"
|
||||||
Msg401 = "该账号登录已失效, 请重新登录"
|
Msg401 = "该账号登录已失效, 请重新登录"
|
||||||
Msg401NoMulti = "用户已在其他地方登录"
|
Msg401NoMulti = "用户已在其他地方登录"
|
||||||
|
Msg401Inactive = "当前用户尚未生效, 请稍后再试"
|
||||||
Msg403 = "权限不足"
|
Msg403 = "权限不足"
|
||||||
Msg404 = "资源不存在"
|
Msg404 = "资源不存在"
|
||||||
Msg500 = "服务器开小差了"
|
Msg500 = "服务器开小差了"
|
||||||
|
44
resp/resp.go
44
resp/resp.go
@ -43,22 +43,44 @@ func RE(c *gin.Context, err error) {
|
|||||||
|
|
||||||
func _r(c *gin.Context, r *res, args ...any) {
|
func _r(c *gin.Context, r *res, args ...any) {
|
||||||
length := len(args)
|
length := len(args)
|
||||||
switch length {
|
|
||||||
case 0:
|
if length == 0 {
|
||||||
break
|
goto END
|
||||||
case 1:
|
|
||||||
if msg, ok := args[0].(string); ok {
|
|
||||||
r.Msg = msg
|
|
||||||
}
|
}
|
||||||
case 2:
|
|
||||||
r.Data = args[1]
|
if length >= 4 {
|
||||||
case 3:
|
goto H4
|
||||||
r.Err = args[2]
|
}
|
||||||
case 4:
|
|
||||||
|
if length >= 3 {
|
||||||
|
goto H3
|
||||||
|
}
|
||||||
|
|
||||||
|
if length >= 2 {
|
||||||
|
goto H2
|
||||||
|
}
|
||||||
|
if length >= 1 {
|
||||||
|
goto H1
|
||||||
|
}
|
||||||
|
|
||||||
|
H4:
|
||||||
if code, err := cast.ToIntE(args[3]); err == nil {
|
if code, err := cast.ToIntE(args[3]); err == nil {
|
||||||
r.Code = code
|
r.Code = code
|
||||||
}
|
}
|
||||||
|
H3:
|
||||||
|
if es, ok := args[2].(error); ok {
|
||||||
|
r.Err = es.Error()
|
||||||
|
} else {
|
||||||
|
r.Err = args[2]
|
||||||
}
|
}
|
||||||
|
H2:
|
||||||
|
r.Data = args[1]
|
||||||
|
H1:
|
||||||
|
if msg, ok := args[0].(string); ok {
|
||||||
|
r.Msg = msg
|
||||||
|
}
|
||||||
|
|
||||||
|
END:
|
||||||
|
|
||||||
if r.Msg == "" {
|
if r.Msg == "" {
|
||||||
r.Msg = Msg(r.Status)
|
r.Msg = Msg(r.Status)
|
||||||
|
9
resp/resp_test.go
Normal file
9
resp/resp_test.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package resp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestResp(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user