package service import ( "context" "crypto/tls" "fmt" "net" "net/http" "time" "mstore/app/handler" "mstore/app/logger" "mstore/app/router" ) const protocol = "tcp" type ServiceParams struct { Handler *handler.Handler X509Cert string X509Key string Portnum int64 Address string } type Service struct { hand *handler.Handler rout *router.Router logg *logger.Logger address string portnum int64 x509cert []byte x509key []byte listen net.Listener hsrv *http.Server } func NewService(params *ServiceParams) (*Service, error) { var err error svc := &Service{ hand: params.Handler, x509cert: []byte(params.X509Cert), x509key: []byte(params.X509Key), portnum: params.Portnum, address: params.Address, } svc.logg = logger.NewLogger("service") return svc, err } func (svc *Service) Build() error { var err error svc.logg.Infof("Service build ") svc.rout = router.NewRouter() svc.rout.Get("/v3/api/service/hello", svc.hand.SendHello) svc.rout.Head("/v3/api/file/{filepath}", svc.hand.FileExists) svc.rout.Put("/v3/api/file/{filepath}", svc.hand.PutFile) svc.rout.Get("/v3/api/file/{filepath}", svc.hand.GetFile) svc.rout.Delete("/v3/api/file/{filepath}", svc.hand.DeleteFile) svc.rout.Get("/v3/api/files/{filepath}", svc.hand.ListFiles) selector := svc.rout.Selector() for _, item := range selector.Routes { svc.logg.Infof("%s\t%s", item.Method, item.RawPath) } const useTLS = true if useTLS { tlsCert, err := tls.X509KeyPair(svc.x509cert, svc.x509key) if err != nil { return err } tlsConfig := tls.Config{ Certificates: []tls.Certificate{tlsCert}, ClientAuth: tls.NoClientCert, InsecureSkipVerify: true, } listenAddress := fmt.Sprintf("%s:%d", svc.address, svc.portnum) svc.listen, err = tls.Listen(protocol, listenAddress, &tlsConfig) if err != nil { return err } } else { listenAddress := fmt.Sprintf("%s:%d", svc.address, svc.portnum) svc.listen, err = net.Listen(protocol, listenAddress) if err != nil { return err } } svc.logg.Infof("Service listening at %v", svc.listen.Addr()) svc.hsrv = &http.Server{ Handler: svc.rout, } return err } func (svc *Service) Run() error { var err error svc.logg.Infof("Service run") err = svc.hsrv.Serve(svc.listen) if err == http.ErrServerClosed { svc.logg.Warningf("Service Closed") err = nil } if err != nil { return err } return err } func (svc *Service) Stop() { if svc.hsrv != nil { svc.logg.Infof("Service stop") downWaiting := 10 * time.Second ctx, cancel := context.WithTimeout(context.Background(), downWaiting) defer cancel() err := svc.hsrv.Shutdown(ctx) if err != nil { svc.logg.Errorf("Error service shutdown: %v", err) } } }