Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions command/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
28 changes: 17 additions & 11 deletions pkg/httpserver/httpserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is an http.NotFound constant.

if opts.ExitOnUnmatchedRule {
logger.Fatalf("--exit-on-unmatched-rule is set, exiting")
Copy link
Member

@andrewkroh andrewkroh Nov 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be more graceful to asynchronously stop the server. With os.Exit being called from the handler there is no guarantee that the response has been flushed to the client before the program stops.

}
})

handler, err := newHandlerFromConfig(config, notFoundHandler, logger)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down