package service import ( "net" "net/http" "github.com/go-gost/core/auth" "github.com/go-gost/core/service" "github.com/prometheus/client_golang/prometheus/promhttp" ) const ( DefaultPath = "/metrics" ) type options struct { path string auther auth.Authenticator } type Option func(*options) func PathOption(path string) Option { return func(o *options) { o.path = path } } func AutherOption(auther auth.Authenticator) Option { return func(o *options) { o.auther = auther } } type metricService struct { s *http.Server ln net.Listener } func NewService(addr string, opts ...Option) (service.Service, error) { ln, err := net.Listen("tcp", addr) if err != nil { return nil, err } var options options for _, opt := range opts { opt(&options) } if options.path == "" { options.path = DefaultPath } mux := http.NewServeMux() mux.Handle(options.path, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if options.auther != nil { u, p, _ := r.BasicAuth() if _, ok := options.auther.Authenticate(r.Context(), u, p); !ok { w.WriteHeader(http.StatusUnauthorized) return } } promhttp.Handler().ServeHTTP(w, r) })) return &metricService{ s: &http.Server{ Handler: mux, }, ln: ln, }, nil } func (s *metricService) Serve() error { return s.s.Serve(s.ln) } func (s *metricService) Addr() net.Addr { return s.ln.Addr() } func (s *metricService) Close() error { return s.s.Close() }