package server import ( "fmt" "net" "os" "github.com/gin-gonic/gin" ) // Option functions set unexported private fields in the ServerConfig. // Use it to set things like the storage backend and port. type Option func(*Config) error func validPortNumber(port int) error { if port <= 0 || port > 65535 { return fmt.Errorf("Invalid port number %q", port) } return nil } // OptionPort sets the port to listen on. Omitting the ServerOptionPort causes the server to use port 80. func OptionPort(port int) Option { return func(cfg *Config) error { cfg.port = port return validPortNumber(port) } } // OptionHandler serves the gin handler on the provided path. func OptionHandler(path string, handler gin.HandlerFunc) Option { return func(c *Config) error { if handler == nil || path == "" { return fmt.Errorf("handler and path must be set") } if c.handlers == nil { c.handlers = make(map[string]Handler) } if _, taken := c.handlers[path]; taken { return fmt.Errorf("handler path %q already registered", path) } c.handlers[path] = Handler(handler) return nil } } // OptionSecure creates an https server using the provided tls cert and key files. // // If the OptionPort is not set, then the `:https` Addr is used. func OptionSecure(certFile, keyFile string) Option { return func(cfg *Config) error { var f, err = os.Open(certFile) if err != nil { return fmt.Errorf("could not open cert file %q because of error: %w", certFile, err) } f.Close() f, err = os.Open(keyFile) if err != nil { return fmt.Errorf("could not open key file %q because of error: %w", keyFile, err) } f.Close() cfg.secure = true cfg.secureCertFile = certFile cfg.secureKeyFile = keyFile return nil } } // OptionListener is used to set a custom net.Listener for the server. // This server option is used in tests because some CICD environments don't allow ports to be opened. func OptionListener(l net.Listener) Option { return func(cfg *Config) error { cfg.listener = l return nil } }