mirror of
https://github.com/tarampampam/error-pages.git
synced 2024-08-30 18:22:40 +00:00
Added possibility to disable error pages auto-localization (#94)
This commit is contained in:
@ -15,6 +15,7 @@ import (
|
||||
func NewCommand(log *zap.Logger, configFile *string) *cobra.Command {
|
||||
var (
|
||||
generateIndex bool
|
||||
disableL10n bool
|
||||
cfg *config.Config
|
||||
)
|
||||
|
||||
@ -39,7 +40,7 @@ func NewCommand(log *zap.Logger, configFile *string) *cobra.Command {
|
||||
return errors.New("wrong arguments count")
|
||||
}
|
||||
|
||||
return run(log, cfg, args[0], generateIndex)
|
||||
return run(log, cfg, args[0], generateIndex, disableL10n)
|
||||
},
|
||||
}
|
||||
|
||||
@ -50,6 +51,13 @@ func NewCommand(log *zap.Logger, configFile *string) *cobra.Command {
|
||||
"generate index page",
|
||||
)
|
||||
|
||||
cmd.Flags().BoolVarP(
|
||||
&disableL10n,
|
||||
"disable-l10n", "",
|
||||
false,
|
||||
"disable error pages localization",
|
||||
)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@ -60,7 +68,7 @@ const (
|
||||
outDirPerm = os.FileMode(0775)
|
||||
)
|
||||
|
||||
func run(log *zap.Logger, cfg *config.Config, outDirectoryPath string, generateIndex bool) error { //nolint:funlen
|
||||
func run(log *zap.Logger, cfg *config.Config, outDirectoryPath string, generateIndex, disableL10n bool) error { //nolint:funlen,lll
|
||||
if len(cfg.Templates) == 0 {
|
||||
return errors.New("no loaded templates")
|
||||
}
|
||||
@ -92,6 +100,7 @@ func run(log *zap.Logger, cfg *config.Config, outDirectoryPath string, generateI
|
||||
Message: page.Message(),
|
||||
Description: page.Description(),
|
||||
ShowRequestDetails: false,
|
||||
L10nDisabled: disableL10n,
|
||||
})
|
||||
if renderingErr != nil {
|
||||
return renderingErr
|
||||
|
@ -30,7 +30,7 @@ func NewCommand(ctx context.Context, log *zap.Logger, configFile *string) *cobra
|
||||
return errors.New("path to the config file is required for this command")
|
||||
}
|
||||
|
||||
if err = f.overrideUsingEnv(cmd.Flags()); err != nil {
|
||||
if err = f.OverrideUsingEnv(cmd.Flags()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -38,18 +38,18 @@ func NewCommand(ctx context.Context, log *zap.Logger, configFile *string) *cobra
|
||||
return err
|
||||
}
|
||||
|
||||
return f.validate()
|
||||
return f.Validate()
|
||||
},
|
||||
RunE: func(*cobra.Command, []string) error { return run(ctx, log, f, cfg) },
|
||||
RunE: func(*cobra.Command, []string) error { return run(ctx, log, cfg, f) },
|
||||
}
|
||||
|
||||
f.init(cmd.Flags())
|
||||
f.Init(cmd.Flags())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// run current command.
|
||||
func run(parentCtx context.Context, log *zap.Logger, f flags, cfg *config.Config) error { //nolint:funlen
|
||||
func run(parentCtx context.Context, log *zap.Logger, cfg *config.Config, f flags) error { //nolint:funlen
|
||||
var (
|
||||
ctx, cancel = context.WithCancel(parentCtx) // serve context creation
|
||||
oss = breaker.NewOSSignals(ctx) // OS signals listener
|
||||
@ -70,9 +70,11 @@ func run(parentCtx context.Context, log *zap.Logger, f flags, cfg *config.Config
|
||||
var (
|
||||
templateNames = cfg.TemplateNames()
|
||||
picker interface{ Pick() string }
|
||||
|
||||
opt = f.ToOptions()
|
||||
)
|
||||
|
||||
switch f.template.name {
|
||||
switch opt.Template.Name {
|
||||
case useRandomTemplate:
|
||||
log.Info("A random template will be used")
|
||||
|
||||
@ -99,28 +101,19 @@ func run(parentCtx context.Context, log *zap.Logger, f flags, cfg *config.Config
|
||||
picker = pick.NewStringsSlice(templateNames, pick.First)
|
||||
|
||||
default:
|
||||
if t, found := cfg.Template(f.template.name); found {
|
||||
if t, found := cfg.Template(opt.Template.Name); found {
|
||||
log.Info("We will use the requested template", zap.String("name", t.Name()))
|
||||
picker = pick.NewStringsSlice([]string{t.Name()}, pick.First)
|
||||
} else {
|
||||
return errors.New("requested nonexistent template: " + f.template.name)
|
||||
return errors.New("requested nonexistent template: " + opt.Template.Name)
|
||||
}
|
||||
}
|
||||
|
||||
var proxyHTTPHeaders = f.HeadersToProxy()
|
||||
|
||||
// create HTTP server
|
||||
server := appHttp.NewServer(log)
|
||||
|
||||
// register server routes, middlewares, etc.
|
||||
if err := server.Register(
|
||||
cfg,
|
||||
picker,
|
||||
f.defaultErrorPage,
|
||||
f.defaultHTTPCode,
|
||||
f.showDetails,
|
||||
proxyHTTPHeaders,
|
||||
); err != nil {
|
||||
if err := server.Register(cfg, picker, opt); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -131,15 +124,16 @@ func run(parentCtx context.Context, log *zap.Logger, f flags, cfg *config.Config
|
||||
defer close(errCh)
|
||||
|
||||
log.Info("Server starting",
|
||||
zap.String("addr", f.listen.ip),
|
||||
zap.Uint16("port", f.listen.port),
|
||||
zap.String("default error page", f.defaultErrorPage),
|
||||
zap.Uint16("default HTTP response code", f.defaultHTTPCode),
|
||||
zap.Strings("proxy headers", proxyHTTPHeaders),
|
||||
zap.Bool("show request details", f.showDetails),
|
||||
zap.String("addr", f.Listen.IP),
|
||||
zap.Uint16("port", f.Listen.Port),
|
||||
zap.String("default error page", opt.Default.PageCode),
|
||||
zap.Uint16("default HTTP response code", opt.Default.HTTPCode),
|
||||
zap.Strings("proxy headers", opt.ProxyHTTPHeaders),
|
||||
zap.Bool("show request details", opt.ShowDetails),
|
||||
zap.Bool("localization disabled", opt.L10n.Disabled),
|
||||
)
|
||||
|
||||
if err := server.Start(f.listen.ip, f.listen.port); err != nil {
|
||||
if err := server.Start(f.Listen.IP, f.Listen.Port); err != nil {
|
||||
errCh <- err
|
||||
}
|
||||
}(startingErrCh)
|
||||
|
@ -9,60 +9,26 @@ import (
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/tarampampam/error-pages/internal/env"
|
||||
"github.com/tarampampam/error-pages/internal/options"
|
||||
)
|
||||
|
||||
type flags struct {
|
||||
listen struct {
|
||||
ip string
|
||||
port uint16
|
||||
Listen struct {
|
||||
IP string
|
||||
Port uint16
|
||||
}
|
||||
template struct {
|
||||
name string
|
||||
}
|
||||
l10n struct {
|
||||
disabled bool
|
||||
}
|
||||
defaultErrorPage string
|
||||
defaultHTTPCode uint16
|
||||
showDetails bool
|
||||
proxyHTTPHeaders string // comma-separated
|
||||
}
|
||||
|
||||
// HeadersToProxy converts a comma-separated string with headers list into strings slice (with a sorting and without
|
||||
// duplicates).
|
||||
func (f *flags) HeadersToProxy() []string {
|
||||
var raw = strings.Split(f.proxyHTTPHeaders, ",")
|
||||
|
||||
if len(raw) == 0 {
|
||||
return []string{}
|
||||
} else if len(raw) == 1 {
|
||||
if h := strings.TrimSpace(raw[0]); h != "" {
|
||||
return []string{h}
|
||||
} else {
|
||||
return []string{}
|
||||
}
|
||||
}
|
||||
|
||||
var m = make(map[string]struct{}, len(raw))
|
||||
|
||||
// make unique and ignore empty strings
|
||||
for _, h := range raw {
|
||||
if h = strings.TrimSpace(h); h != "" {
|
||||
if _, ok := m[h]; !ok {
|
||||
m[h] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert map into slice
|
||||
var headers = make([]string, 0, len(m))
|
||||
for h := range m {
|
||||
headers = append(headers, h)
|
||||
}
|
||||
|
||||
// make sort
|
||||
sort.Strings(headers)
|
||||
|
||||
return headers
|
||||
}
|
||||
|
||||
const (
|
||||
listenFlagName = "listen"
|
||||
portFlagName = "port"
|
||||
@ -71,6 +37,7 @@ const (
|
||||
defaultHTTPCodeFlagName = "default-http-code"
|
||||
showDetailsFlagName = "show-details"
|
||||
proxyHTTPHeadersFlagName = "proxy-headers"
|
||||
disableL10nFlagName = "disable-l10n"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -80,18 +47,18 @@ const (
|
||||
useRandomTemplateHourly = "random-hourly"
|
||||
)
|
||||
|
||||
func (f *flags) init(flagSet *pflag.FlagSet) {
|
||||
func (f *flags) Init(flagSet *pflag.FlagSet) {
|
||||
flagSet.StringVarP(
|
||||
&f.listen.ip,
|
||||
&f.Listen.IP,
|
||||
listenFlagName, "l",
|
||||
"0.0.0.0",
|
||||
fmt.Sprintf("IP address to listen on [$%s]", env.ListenAddr),
|
||||
fmt.Sprintf("IP address to Listen on [$%s]", env.ListenAddr),
|
||||
)
|
||||
flagSet.Uint16VarP(
|
||||
&f.listen.port,
|
||||
&f.Listen.Port,
|
||||
portFlagName, "p",
|
||||
8080, //nolint:gomnd // must be same as default healthcheck `--port` flag value
|
||||
fmt.Sprintf("TCP port number [$%s]", env.ListenPort),
|
||||
fmt.Sprintf("TCP prt number [$%s]", env.ListenPort),
|
||||
)
|
||||
flagSet.StringVarP(
|
||||
&f.template.name,
|
||||
@ -131,22 +98,28 @@ func (f *flags) init(flagSet *pflag.FlagSet) {
|
||||
"",
|
||||
fmt.Sprintf("proxy HTTP request headers list (comma-separated) [$%s]", env.ProxyHTTPHeaders),
|
||||
)
|
||||
flagSet.BoolVarP(
|
||||
&f.l10n.disabled,
|
||||
disableL10nFlagName, "",
|
||||
false,
|
||||
fmt.Sprintf("disable error pages localization [$%s]", env.DisableL10n),
|
||||
)
|
||||
}
|
||||
|
||||
func (f *flags) overrideUsingEnv(flagSet *pflag.FlagSet) (lastErr error) { //nolint:gocognit,gocyclo
|
||||
func (f *flags) OverrideUsingEnv(flagSet *pflag.FlagSet) (lastErr error) { //nolint:gocognit,gocyclo
|
||||
flagSet.VisitAll(func(flag *pflag.Flag) {
|
||||
// flag was NOT defined using CLI (flags should have maximal priority)
|
||||
if !flag.Changed { //nolint:nestif
|
||||
switch flag.Name {
|
||||
case listenFlagName:
|
||||
if envVar, exists := env.ListenAddr.Lookup(); exists {
|
||||
f.listen.ip = strings.TrimSpace(envVar)
|
||||
f.Listen.IP = strings.TrimSpace(envVar)
|
||||
}
|
||||
|
||||
case portFlagName:
|
||||
if envVar, exists := env.ListenPort.Lookup(); exists {
|
||||
if p, err := strconv.ParseUint(envVar, 10, 16); err == nil { //nolint:gomnd
|
||||
f.listen.port = uint16(p)
|
||||
f.Listen.Port = uint16(p)
|
||||
} else {
|
||||
lastErr = fmt.Errorf("wrong TCP port environment variable [%s] value", envVar)
|
||||
}
|
||||
@ -182,6 +155,13 @@ func (f *flags) overrideUsingEnv(flagSet *pflag.FlagSet) (lastErr error) { //nol
|
||||
if envVar, exists := env.ProxyHTTPHeaders.Lookup(); exists {
|
||||
f.proxyHTTPHeaders = strings.TrimSpace(envVar)
|
||||
}
|
||||
|
||||
case disableL10nFlagName:
|
||||
if envVar, exists := env.DisableL10n.Lookup(); exists {
|
||||
if b, err := strconv.ParseBool(envVar); err == nil {
|
||||
f.l10n.disabled = b
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -189,9 +169,9 @@ func (f *flags) overrideUsingEnv(flagSet *pflag.FlagSet) (lastErr error) { //nol
|
||||
return lastErr
|
||||
}
|
||||
|
||||
func (f *flags) validate() error {
|
||||
if net.ParseIP(f.listen.ip) == nil {
|
||||
return fmt.Errorf("wrong IP address [%s] for listening", f.listen.ip)
|
||||
func (f *flags) Validate() error {
|
||||
if net.ParseIP(f.Listen.IP) == nil {
|
||||
return fmt.Errorf("wrong IP address [%s] for listening", f.Listen.IP)
|
||||
}
|
||||
|
||||
if f.defaultHTTPCode > 599 { //nolint:gomnd
|
||||
@ -204,3 +184,52 @@ func (f *flags) validate() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// headersToProxy converts a comma-separated string with headers list into strings slice (with a sorting and without
|
||||
// duplicates).
|
||||
func (f *flags) headersToProxy() []string {
|
||||
var raw = strings.Split(f.proxyHTTPHeaders, ",")
|
||||
|
||||
if len(raw) == 0 {
|
||||
return []string{}
|
||||
} else if len(raw) == 1 {
|
||||
if h := strings.TrimSpace(raw[0]); h != "" {
|
||||
return []string{h}
|
||||
} else {
|
||||
return []string{}
|
||||
}
|
||||
}
|
||||
|
||||
var m = make(map[string]struct{}, len(raw))
|
||||
|
||||
// make unique and ignore empty strings
|
||||
for _, h := range raw {
|
||||
if h = strings.TrimSpace(h); h != "" {
|
||||
if _, ok := m[h]; !ok {
|
||||
m[h] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert map into slice
|
||||
var headers = make([]string, 0, len(m))
|
||||
for h := range m {
|
||||
headers = append(headers, h)
|
||||
}
|
||||
|
||||
// make sort
|
||||
sort.Strings(headers)
|
||||
|
||||
return headers
|
||||
}
|
||||
|
||||
func (f *flags) ToOptions() (o options.ErrorPage) {
|
||||
o.Default.PageCode = f.defaultErrorPage
|
||||
o.Default.HTTPCode = f.defaultHTTPCode
|
||||
o.L10n.Disabled = f.l10n.disabled
|
||||
o.Template.Name = f.template.name
|
||||
o.ShowDetails = f.showDetails
|
||||
o.ProxyHTTPHeaders = f.headersToProxy()
|
||||
|
||||
return o
|
||||
}
|
||||
|
Reference in New Issue
Block a user