diff --git a/CHANGELOG.md b/CHANGELOG.md index a9df78b..42f3dca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added +- Added `exit-on-unmatched-rule` flag: [#63](https://github.com/elastic/stream/pull/63) + ### Changed ### Fixed diff --git a/command/root.go b/command/root.go index b6722e0..e0b0a6d 100644 --- a/command/root.go +++ b/command/root.go @@ -114,6 +114,7 @@ func ExecuteContext(ctx context.Context) error { httpCommand.PersistentFlags().StringVar(&httpOpts.TLSCertificate, "tls-cert", "", "Path to the TLS certificate") httpCommand.PersistentFlags().StringVar(&httpOpts.TLSKey, "tls-key", "", "Path to the TLS key file") httpCommand.PersistentFlags().StringVar(&httpOpts.ConfigPath, "config", "", "Path to the config file") + httpCommand.PersistentFlags().BoolVar(&httpOpts.ExitOnUnmatchedRule, "exit-on-unmatched-rule", false, "If set to true it will exit if no rule matches a request") rootCmd.AddCommand(httpCommand) rootCmd.AddCommand(versionCmd) diff --git a/pkg/httpserver/httpserver.go b/pkg/httpserver/httpserver.go index 02ec062..5c11a4c 100644 --- a/pkg/httpserver/httpserver.go +++ b/pkg/httpserver/httpserver.go @@ -31,11 +31,12 @@ type Server struct { type Options struct { *output.Options - TLSCertificate string // TLS certificate file path. - TLSKey string // TLS key file path. - ReadTimeout time.Duration // HTTP Server read timeout. - WriteTimeout time.Duration // HTTP Server write timeout. - ConfigPath string // Config path. + TLSCertificate string // TLS certificate file path. + TLSKey string // TLS key file path. + ReadTimeout time.Duration // HTTP Server read timeout. + WriteTimeout time.Duration // HTTP Server write timeout. + ConfigPath string // Config path. + ExitOnUnmatchedRule bool // If true it will exit if a request does not match any rule. } func New(opts *Options, logger *zap.SugaredLogger) (*Server, error) { @@ -53,7 +54,15 @@ func New(opts *Options, logger *zap.SugaredLogger) (*Server, error) { return nil, err } - handler, err := newHandlerFromConfig(config, logger) + notFoundHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + logger.Debugf("request did not match with any rule: %s", strRequest(r)) + w.WriteHeader(404) + if opts.ExitOnUnmatchedRule { + logger.Fatalf("--exit-on-unmatched-rule is set, exiting") + } + }) + + handler, err := newHandlerFromConfig(config, notFoundHandler, logger) if err != nil { return nil, err } @@ -104,7 +113,7 @@ func (o *Server) Close() error { return o.server.Shutdown(ctx) } -func newHandlerFromConfig(config *config, logger *zap.SugaredLogger) (http.Handler, error) { +func newHandlerFromConfig(config *config, notFoundHandler http.HandlerFunc, logger *zap.SugaredLogger) (http.Handler, error) { router := mux.NewRouter() var buf bytes.Buffer @@ -221,10 +230,7 @@ func newHandlerFromConfig(config *config, logger *zap.SugaredLogger) (http.Handl }) } - router.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - logger.Debugf("request did not match with any rule: %s", strRequest(r)) - w.WriteHeader(404) - }) + router.NotFoundHandler = notFoundHandler return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // merge together form params into the url ones to make checks easier