master
parent
b731d13a88
commit
25c38491fe
20 changed files with 448 additions and 95 deletions
@ -0,0 +1,78 @@ |
|||||||
|
package main |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"fmt" |
||||||
|
"github.com/gorilla/mux" |
||||||
|
"log" |
||||||
|
"net/http" |
||||||
|
) |
||||||
|
|
||||||
|
type FilterFunc func(http.Handler) http.Handler |
||||||
|
|
||||||
|
func FilterChain(filters ...FilterFunc) FilterFunc { |
||||||
|
return func(next http.Handler) http.Handler { |
||||||
|
for i := len(filters) - 1; i >= 0; i-- { |
||||||
|
next = filters[i](next) |
||||||
|
} |
||||||
|
return next |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
type Context struct { |
||||||
|
context.Context |
||||||
|
req *http.Request |
||||||
|
res http.ResponseWriter |
||||||
|
} |
||||||
|
|
||||||
|
func (c *Context) String(code int, str string) error { |
||||||
|
c.res.WriteHeader(code) |
||||||
|
_, err := c.res.Write([]byte(str)) |
||||||
|
return err |
||||||
|
} |
||||||
|
|
||||||
|
func (c *Context) Result(code int, str string) error { |
||||||
|
c.res.WriteHeader(code) |
||||||
|
_, err := c.res.Write([]byte(str)) |
||||||
|
return err |
||||||
|
} |
||||||
|
|
||||||
|
type HandleFunc func(Context) error |
||||||
|
|
||||||
|
func IndexPage(ctx Context) error { |
||||||
|
//return errors.New("xxx")
|
||||||
|
return ctx.String(200, "hello index") |
||||||
|
} |
||||||
|
func Logger() HandleFunc { |
||||||
|
return func(c Context) error { |
||||||
|
return nil |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func main() { |
||||||
|
app := mux.NewRouter() |
||||||
|
next := http.Handler(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { |
||||||
|
ctx := Context{ |
||||||
|
res: res, |
||||||
|
req: req, |
||||||
|
} |
||||||
|
h := Logger() |
||||||
|
h(ctx) |
||||||
|
if err := IndexPage(ctx); err != nil { |
||||||
|
ctx.Result(500, "err:"+err.Error()) |
||||||
|
} |
||||||
|
})) |
||||||
|
next = FilterChain(func(handler http.Handler) http.Handler { |
||||||
|
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { |
||||||
|
fmt.Println("start") |
||||||
|
handler.ServeHTTP(writer, request) |
||||||
|
fmt.Println("end") |
||||||
|
}) |
||||||
|
})(next) |
||||||
|
app.Handle("/", next).Methods("GET") |
||||||
|
srv := http.Server{ |
||||||
|
Addr: ":9999", |
||||||
|
Handler: app, |
||||||
|
} |
||||||
|
log.Fatal(srv.ListenAndServe()) |
||||||
|
} |
@ -1,17 +1,35 @@ |
|||||||
package main |
package main |
||||||
|
|
||||||
import ( |
import ( |
||||||
"git.echinacities.com/mogfee/protoc-gen-kit/example/service" |
"fmt" |
||||||
user "git.echinacities.com/mogfee/protoc-gen-kit/proto/v1" |
"git.diulo.com/mogfee/protoc-gen-kit/example/service" |
||||||
|
"git.diulo.com/mogfee/protoc-gen-kit/middleware" |
||||||
|
user "git.diulo.com/mogfee/protoc-gen-kit/proto/v1" |
||||||
|
"git.diulo.com/mogfee/protoc-gen-kit/xjson" |
||||||
"github.com/gin-gonic/gin" |
"github.com/gin-gonic/gin" |
||||||
|
"github.com/sirupsen/logrus" |
||||||
|
"os" |
||||||
) |
) |
||||||
|
|
||||||
func main() { |
func main() { |
||||||
|
gin.SetMode(gin.ReleaseMode) |
||||||
app := gin.Default() |
app := gin.Default() |
||||||
srv := service.UserService{} |
srv := service.UserService{} |
||||||
app.Use(func(c *gin.Context) { |
l := logrus.New() |
||||||
c.Set("userId", 11) |
f, err := os.Create("./app.log") |
||||||
|
if err != nil { |
||||||
|
panic(err) |
||||||
|
} |
||||||
|
defer f.Close() |
||||||
|
l.SetOutput(f) |
||||||
|
|
||||||
|
l.SetFormatter(&logrus.JSONFormatter{}) |
||||||
|
l.SetReportCaller(false) |
||||||
|
|
||||||
|
app.GET("/user/:name", func(c *gin.Context) { |
||||||
|
xjson.PrintData(c.FullPath()) |
||||||
}) |
}) |
||||||
user.RegisterUserHandler(app, &srv) |
user.RegisterUserHandler(app, &srv, middleware.JWT(""), middleware.Logger("user-server", l), middleware.Validate()) |
||||||
|
fmt.Println("http://localhost:8888") |
||||||
app.Run("localhost:8888") |
app.Run("localhost:8888") |
||||||
} |
} |
||||||
|
@ -0,0 +1,26 @@ |
|||||||
|
package middleware |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"fmt" |
||||||
|
"github.com/gin-gonic/gin" |
||||||
|
"google.golang.org/grpc/metadata" |
||||||
|
) |
||||||
|
|
||||||
|
func AddHeaderMdMiddle(c *gin.Context) Middleware { |
||||||
|
return func(handler Handler) Handler { |
||||||
|
return func(ctx context.Context, a any) (any, error) { |
||||||
|
fmt.Println("add_header_md") |
||||||
|
headers := metadata.MD{} |
||||||
|
headers1 := c.Request.Header.Clone() |
||||||
|
for k, v := range headers1 { |
||||||
|
headers.Set(k, v[0]) |
||||||
|
} |
||||||
|
headers["remote_ip"] = []string{c.RemoteIP()} |
||||||
|
headers["full_path"] = []string{c.FullPath()} |
||||||
|
ctx = metadata.NewIncomingContext(ctx, headers) |
||||||
|
|
||||||
|
return handler(ctx, a) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
package middleware |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"git.diulo.com/mogfee/protoc-gen-kit/xuser" |
||||||
|
"google.golang.org/grpc/metadata" |
||||||
|
) |
||||||
|
|
||||||
|
func JWT(authKey string) Middleware { |
||||||
|
return func(handler Handler) Handler { |
||||||
|
return func(ctx context.Context, a any) (any, error) { |
||||||
|
var token string |
||||||
|
if md, ok := metadata.FromIncomingContext(ctx); ok { |
||||||
|
token = md.Get("token")[0] |
||||||
|
} |
||||||
|
userId, err := xuser.ValidateUser(ctx.Value(token).(string)) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
ctx = xuser.WithContext(ctx, userId) |
||||||
|
return handler(ctx, a) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
package middleware |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"fmt" |
||||||
|
"git.diulo.com/mogfee/protoc-gen-kit/xlog" |
||||||
|
"github.com/sirupsen/logrus" |
||||||
|
"google.golang.org/grpc/metadata" |
||||||
|
"time" |
||||||
|
) |
||||||
|
|
||||||
|
func Logger(serverName string, log *logrus.Logger) Middleware { |
||||||
|
baseEntry := log.WithFields(logrus.Fields{ |
||||||
|
"serverName": serverName, |
||||||
|
}) |
||||||
|
return func(handler Handler) Handler { |
||||||
|
return func(ctx context.Context, a any) (any, error) { |
||||||
|
fmt.Println("add_log") |
||||||
|
st := time.Now() |
||||||
|
entry := baseEntry.WithFields(logrus.Fields{ |
||||||
|
"used_time": time.Since(st), |
||||||
|
"param": a, |
||||||
|
}) |
||||||
|
if md, ok := metadata.FromIncomingContext(ctx); ok { |
||||||
|
entry = entry.WithFields(logrus.Fields{ |
||||||
|
"ip": md.Get("remote_ip")[0], |
||||||
|
"full_path": md.Get("full_path")[0], |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
ctx = xlog.WithContext(ctx, entry) |
||||||
|
resp, err := handler(ctx, a) |
||||||
|
if err != nil { |
||||||
|
entry.WithContext(ctx).Errorf("%+v", err) |
||||||
|
} else { |
||||||
|
entry.WithContext(ctx).Info("") |
||||||
|
} |
||||||
|
return resp, err |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
package middleware |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"fmt" |
||||||
|
"github.com/gin-gonic/gin" |
||||||
|
) |
||||||
|
|
||||||
|
type Handler func(context.Context, any) (any, error) |
||||||
|
|
||||||
|
type Middleware func(Handler) Handler |
||||||
|
|
||||||
|
func Chain(m ...Middleware) Middleware { |
||||||
|
return func(handler Handler) Handler { |
||||||
|
for i := len(m) - 1; i >= 0; i-- { |
||||||
|
handler = m[i](handler) |
||||||
|
} |
||||||
|
return handler |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func HttpMiddleware(c *gin.Context, handler Handler, m ...Middleware) Handler { |
||||||
|
opts := []Middleware{Recover(), AddHeaderMdMiddle(c), func(handler Handler) Handler { |
||||||
|
return func(ctx context.Context, a any) (any, error) { |
||||||
|
res, err := handler(ctx, a) |
||||||
|
fmt.Println("sss", res) |
||||||
|
return &struct { |
||||||
|
Name string |
||||||
|
}{}, err |
||||||
|
} |
||||||
|
}} |
||||||
|
opts = append(opts, m...) |
||||||
|
return Chain(opts...)(handler) |
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
package middleware |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"fmt" |
||||||
|
) |
||||||
|
|
||||||
|
func Recover() Middleware { |
||||||
|
return func(handler Handler) Handler { |
||||||
|
return func(ctx context.Context, a any) (res any, err error) { |
||||||
|
go func() { |
||||||
|
if rev := recover(); rev != nil { |
||||||
|
err = fmt.Errorf("recover %v", rev) |
||||||
|
} |
||||||
|
}() |
||||||
|
res, err = handler(ctx, a) |
||||||
|
return |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
package middleware |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"fmt" |
||||||
|
) |
||||||
|
|
||||||
|
func Validate() Middleware { |
||||||
|
return func(handler Handler) Handler { |
||||||
|
return func(ctx context.Context, a any) (any, error) { |
||||||
|
fmt.Println("validate") |
||||||
|
fmt.Println(ctx.Value("user-id")) |
||||||
|
if r, ok := a.(interface { |
||||||
|
Validate() error |
||||||
|
}); ok { |
||||||
|
if err := r.Validate(); err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
} |
||||||
|
return handler(ctx, a) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,43 +1,60 @@ |
|||||||
package user |
package user |
||||||
|
|
||||||
import ( |
import ( |
||||||
"git.echinacities.com/mogfee/protoc-gen-kit/response" |
"context" |
||||||
|
"git.diulo.com/mogfee/protoc-gen-kit/middleware" |
||||||
|
"git.diulo.com/mogfee/protoc-gen-kit/response" |
||||||
|
"git.diulo.com/mogfee/protoc-gen-kit/xerrors" |
||||||
"github.com/gin-gonic/gin" |
"github.com/gin-gonic/gin" |
||||||
) |
) |
||||||
|
|
||||||
func RegisterUserHandler(app *gin.Engine, srv UserServer) { |
func RegisterUserHandler(app *gin.Engine, srv UserServer, m ...middleware.Middleware) { |
||||||
app.GET("/api/v1/user/list", httpListHandler(srv)) |
app.GET("/api/v1/user/list", httpListHandler(srv, m...)) |
||||||
app.POST("/api/v1/user/login", httpLoginHandler(srv)) |
app.POST("/api/v1/user/login", httpLoginHandler(srv, m...)) |
||||||
} |
} |
||||||
func httpListHandler(srv UserServer) func(c *gin.Context) { |
func httpListHandler(srv UserServer, m ...middleware.Middleware) func(c *gin.Context) { |
||||||
return func(c *gin.Context) { |
return func(c *gin.Context) { |
||||||
post := LoginRequest{} |
var post LoginRequest |
||||||
resp := response.New(c) |
resp := response.New(c) |
||||||
if err := resp.BindQuery(&post); err != nil { |
if err := resp.BindQuery(&post); err != nil { |
||||||
resp.Error(err) |
resp.Error(err) |
||||||
return |
return |
||||||
} |
} |
||||||
result, err := srv.List(c, &post) |
h := func(ctx context.Context, a any) (any, error) { |
||||||
|
return srv.List(ctx, a.(*LoginRequest)) |
||||||
|
} |
||||||
|
out, err := middleware.HttpMiddleware(c, h, m...)(c, &post) |
||||||
if err != nil { |
if err != nil { |
||||||
resp.Error(err) |
resp.Error(err) |
||||||
return |
} else { |
||||||
|
if v, ok := out.(*LoginResponse); ok { |
||||||
|
resp.Success(v) |
||||||
|
} else { |
||||||
|
resp.Error(xerrors.InternalServer("RESULT_TYPE_ERROR", "LoginResponse")) |
||||||
|
} |
||||||
} |
} |
||||||
resp.Success(result) |
|
||||||
} |
} |
||||||
} |
} |
||||||
func httpLoginHandler(srv UserServer) func(c *gin.Context) { |
func httpLoginHandler(srv UserServer, m ...middleware.Middleware) func(c *gin.Context) { |
||||||
return func(c *gin.Context) { |
return func(c *gin.Context) { |
||||||
post := LoginRequest{} |
var post LoginRequest |
||||||
resp := response.New(c) |
resp := response.New(c) |
||||||
if err := resp.BindJSON(&post); err != nil { |
if err := resp.BindJSON(&post); err != nil { |
||||||
resp.Error(err) |
resp.Error(err) |
||||||
return |
return |
||||||
} |
} |
||||||
result, err := srv.Login(c, &post) |
h := func(ctx context.Context, a any) (any, error) { |
||||||
|
return srv.List(ctx, a.(*LoginRequest)) |
||||||
|
} |
||||||
|
out, err := middleware.HttpMiddleware(c, h, m...)(c, &post) |
||||||
if err != nil { |
if err != nil { |
||||||
resp.Error(err) |
resp.Error(err) |
||||||
return |
} else { |
||||||
|
if v, ok := out.(*LoginResponse); ok { |
||||||
|
resp.Success(v) |
||||||
|
} else { |
||||||
|
resp.Error(xerrors.InternalServer("RESULT_TYPE_ERROR", "LoginResponse")) |
||||||
|
} |
||||||
} |
} |
||||||
resp.Success(result) |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -0,0 +1,19 @@ |
|||||||
|
package xlog |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"github.com/sirupsen/logrus" |
||||||
|
) |
||||||
|
|
||||||
|
type entryKey struct { |
||||||
|
} |
||||||
|
|
||||||
|
func WithContext(ctx context.Context, entry *logrus.Entry) context.Context { |
||||||
|
return context.WithValue(ctx, entryKey{}, entry) |
||||||
|
} |
||||||
|
func FromContext(ctx context.Context) *logrus.Entry { |
||||||
|
if v, ok := ctx.Value(entryKey{}).(*logrus.Entry); ok { |
||||||
|
return v |
||||||
|
} |
||||||
|
return &logrus.Entry{} |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
package xstring |
||||||
|
|
||||||
|
import "unicode" |
||||||
|
|
||||||
|
func Ucfirst(str string) string { |
||||||
|
for i, v := range str { |
||||||
|
return string(unicode.ToUpper(v)) + str[i+1:] |
||||||
|
} |
||||||
|
return "" |
||||||
|
} |
||||||
|
|
||||||
|
func Lcfirst(str string) string { |
||||||
|
for i, v := range str { |
||||||
|
return string(unicode.ToLower(v)) + str[i+1:] |
||||||
|
} |
||||||
|
return "" |
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
package xuser |
||||||
|
|
||||||
|
import "context" |
||||||
|
|
||||||
|
func ValidateUser(token string) (int64, error) { |
||||||
|
return 1, nil |
||||||
|
} |
||||||
|
|
||||||
|
type userIdKey struct { |
||||||
|
} |
||||||
|
|
||||||
|
func WithContext(ctx context.Context, userId int64) context.Context { |
||||||
|
return context.WithValue(ctx, userIdKey{}, userId) |
||||||
|
} |
||||||
|
func FromContext(ctx context.Context) int64 { |
||||||
|
if v, ok := ctx.Value(userIdKey{}).(int64); ok { |
||||||
|
return v |
||||||
|
} |
||||||
|
return 0 |
||||||
|
} |
Loading…
Reference in new issue