116 lines
2.0 KiB
Go
116 lines
2.0 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"errors"
|
|
"gitea.loveuer.com/yizhisec/packages/handler"
|
|
"gitea.loveuer.com/yizhisec/packages/logger"
|
|
"github.com/gin-gonic/gin"
|
|
"net"
|
|
"net/http"
|
|
)
|
|
|
|
type Option func(*option)
|
|
|
|
type option struct {
|
|
name string
|
|
version string
|
|
address string
|
|
app *gin.Engine
|
|
tlsConfig *tls.Config
|
|
}
|
|
|
|
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 (
|
|
err error
|
|
fn func(context.Context) error
|
|
ln net.Listener
|
|
opt = &option{
|
|
name: "unknown",
|
|
version: "v0.0.1",
|
|
address: "127.0.0.1:9119",
|
|
tlsConfig: nil,
|
|
}
|
|
)
|
|
|
|
for _, ofn := range optFns {
|
|
ofn(opt)
|
|
}
|
|
|
|
if opt.app == nil {
|
|
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 {
|
|
ln, err = net.Listen("tcp", opt.address)
|
|
}
|
|
|
|
if err != nil {
|
|
return fn, err
|
|
}
|
|
|
|
svc := &http.Server{
|
|
Handler: opt.app,
|
|
}
|
|
|
|
go func() {
|
|
logger.InfoCtx(ctx, "[%s] api svc running at: %s", opt.name, opt.address)
|
|
if err = svc.Serve(ln); err != nil {
|
|
if !errors.Is(err, http.ErrServerClosed) {
|
|
logger.ErrorCtx(ctx, "api svc run failed, err = %s", err.Error())
|
|
}
|
|
}
|
|
}()
|
|
|
|
fn = func(timeout context.Context) error {
|
|
logger.WarnCtx(ctx, "[%s] api svc shutdown...", opt.name)
|
|
return svc.Shutdown(timeout)
|
|
}
|
|
|
|
return fn, nil
|
|
}
|