package server import ( "bufio" "deploy/pkg/config" "os/exec" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" ) type HTTPServer struct { Engine *gin.Engine Logger *logrus.Logger } func NewServer(logger *logrus.Logger) *HTTPServer { e := gin.Default() s := &HTTPServer{ Engine: e, Logger: logger, } return s } func (s *HTTPServer) setHandler(check map[string]string, script string) gin.HandlerFunc { return func(c *gin.Context) { if len(check) > 0 { for k, v := range check { if c.GetHeader(k) != v { s.Logger.WithFields(logrus.Fields{ "method": c.Request.Method, "path": c.Request.URL.Path, "header": k, }).Warnf("header value not match\n") c.AbortWithStatus(403) return } } } // ctx := c.Copy() go func() { cmd := exec.Command(script) // r, w := io.Pipe() nlog := s.Logger.WithFields(logrus.Fields{"script": script}) reader, err := cmd.StdoutPipe() if err != nil { nlog.Warnf("setup pipe out fail: %+v\n", err) } errReader, err := cmd.StderrPipe() if err != nil { nlog.Warnf("setup pipe out fail: %+v\n", err) } if err := cmd.Start(); err != nil { nlog.Warnf("start script fail: %+v\n", err) } go func() { in := bufio.NewScanner(reader) for in.Scan() { nlog.Debugf(in.Text()) } if err := in.Err(); err != nil { nlog.Warnf("script error: %+v\n", err) } }() go func() { in := bufio.NewScanner(errReader) for in.Scan() { nlog.Debugf(in.Text()) } if err := in.Err(); err != nil { nlog.Warnf("script error: %+v\n", err) } }() }() c.String(200, "ok") } } func (s *HTTPServer) SetRoutes(listens []config.Listen) error { if len(listens) == 0 { return nil } for _, v := range listens { if v.HTTP == nil { continue } switch v.HTTP.Method { case "POST": s.Engine.POST(v.HTTP.Path, s.setHandler(v.HTTP.Headers, v.HTTP.Script)) break case "GET": s.Engine.GET(v.HTTP.Path, s.setHandler(v.HTTP.Headers, v.HTTP.Script)) break default: break } } return nil }