mirror of
https://github.com/tarampampam/error-pages.git
synced 2024-08-30 18:22:40 +00:00
feat: Non-existing pages now return styled 404
status page (with 404
status code) (#189)
* 🎨 style(CHANGELOG.md): add UNRELEASED section 🔧 chore(notfound/handler.go): refactor to use core.RespondWithErrorPage 🔧 chore(http/server.go): pass config, templatePicker, renderer and options to notfoundHandler 🔧 chore(hurl/404.hurl): update test to expect HTML response instead of plain text * 📝 docs(CHANGELOG.md): fix typo in changed section * 🔥 chore(CHANGELOG.md): release version 2.22.0 🔥 chore(flags.go): remove unused code for serve command
This commit is contained in:
parent
6a67510bdc
commit
d40e8879d1
@ -4,6 +4,14 @@ All notable changes to this package will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog][keepachangelog] and this project adheres to [Semantic Versioning][semver].
|
||||
|
||||
## v2.22.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Non-existing pages now return styled `404` status page (with `404` status code) [#188]
|
||||
|
||||
[#188]:https://github.com/tarampampam/error-pages/issues/188
|
||||
|
||||
## v2.21.0
|
||||
|
||||
### Changed
|
||||
|
@ -1,220 +0,0 @@
|
||||
package serve
|
||||
|
||||
// import (
|
||||
// "fmt"
|
||||
// "net"
|
||||
// "sort"
|
||||
// "strconv"
|
||||
// "strings"
|
||||
//
|
||||
// "github.com/spf13/pflag"
|
||||
//
|
||||
// "gh.tarampamp.am/error-pages/internal/env"
|
||||
// "gh.tarampamp.am/error-pages/internal/options"
|
||||
// )
|
||||
//
|
||||
// type flags struct {
|
||||
// Listen struct {
|
||||
// IP string
|
||||
// Port uint16
|
||||
// }
|
||||
// template struct {
|
||||
// name string
|
||||
// }
|
||||
// l10n struct {
|
||||
// disabled bool
|
||||
// }
|
||||
// defaultErrorPage string
|
||||
// defaultHTTPCode uint16
|
||||
// showDetails bool
|
||||
// proxyHTTPHeaders string // comma-separated
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// func (f *flags) Init(flagSet *pflag.FlagSet) {
|
||||
// flagSet.StringVarP(
|
||||
// &f.Listen.IP,
|
||||
// listenFlagName, "l",
|
||||
// "0.0.0.0",
|
||||
// fmt.Sprintf("IP address to Listen on [$%s]", env.ListenAddr),
|
||||
// )
|
||||
// flagSet.Uint16VarP(
|
||||
// &f.Listen.Port,
|
||||
// portFlagName, "p",
|
||||
// 8080, //nolint:gomnd // must be same as default healthcheck `--port` flag value
|
||||
// fmt.Sprintf("TCP prt number [$%s]", env.ListenPort),
|
||||
// )
|
||||
// flagSet.StringVarP(
|
||||
// &f.template.name,
|
||||
// templateNameFlagName, "t",
|
||||
// "",
|
||||
// fmt.Sprintf(
|
||||
// "template name (set \"%s\" to use a randomized or \"%s\" to use a randomized template on each request "+
|
||||
// "or \"%s/%s\" daily/hourly randomized) [$%s]",
|
||||
// useRandomTemplate,
|
||||
// useRandomTemplateOnEachRequest,
|
||||
// useRandomTemplateDaily,
|
||||
// useRandomTemplateHourly,
|
||||
// env.TemplateName,
|
||||
// ),
|
||||
// )
|
||||
// flagSet.StringVarP(
|
||||
// &f.defaultErrorPage,
|
||||
// defaultErrorPageFlagName, "",
|
||||
// "404",
|
||||
// fmt.Sprintf("default error page [$%s]", env.DefaultErrorPage),
|
||||
// )
|
||||
// flagSet.Uint16VarP(
|
||||
// &f.defaultHTTPCode,
|
||||
// defaultHTTPCodeFlagName, "",
|
||||
// 404, //nolint:gomnd
|
||||
// fmt.Sprintf("default HTTP response code [$%s]", env.DefaultHTTPCode),
|
||||
// )
|
||||
// flagSet.BoolVarP(
|
||||
// &f.showDetails,
|
||||
// showDetailsFlagName, "",
|
||||
// false,
|
||||
// fmt.Sprintf("show request details in response [$%s]", env.ShowDetails),
|
||||
// )
|
||||
// flagSet.StringVarP(
|
||||
// &f.proxyHTTPHeaders,
|
||||
// proxyHTTPHeadersFlagName, "",
|
||||
// "",
|
||||
// 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
|
||||
// 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)
|
||||
// }
|
||||
//
|
||||
// case portFlagName:
|
||||
// if envVar, exists := env.ListenPort.Lookup(); exists {
|
||||
// if p, err := strconv.ParseUint(envVar, 10, 16); err == nil {
|
||||
// f.Listen.Port = uint16(p)
|
||||
// } else {
|
||||
// lastErr = fmt.Errorf("wrong TCP port environment variable [%s] value", envVar)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// case templateNameFlagName:
|
||||
// if envVar, exists := env.TemplateName.Lookup(); exists {
|
||||
// f.template.name = strings.TrimSpace(envVar)
|
||||
// }
|
||||
//
|
||||
// case defaultErrorPageFlagName:
|
||||
// if envVar, exists := env.DefaultErrorPage.Lookup(); exists {
|
||||
// f.defaultErrorPage = strings.TrimSpace(envVar)
|
||||
// }
|
||||
//
|
||||
// case defaultHTTPCodeFlagName:
|
||||
// if envVar, exists := env.DefaultHTTPCode.Lookup(); exists {
|
||||
// if code, err := strconv.ParseUint(envVar, 10, 16); err == nil {
|
||||
// f.defaultHTTPCode = uint16(code)
|
||||
// } else {
|
||||
// lastErr = fmt.Errorf("wrong default HTTP response code environment variable [%s] value", envVar)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// case showDetailsFlagName:
|
||||
// if envVar, exists := env.ShowDetails.Lookup(); exists {
|
||||
// if b, err := strconv.ParseBool(envVar); err == nil {
|
||||
// f.showDetails = b
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// case proxyHTTPHeadersFlagName:
|
||||
// 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
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
//
|
||||
// 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)
|
||||
// }
|
||||
//
|
||||
// if f.defaultHTTPCode > 599 { //nolint:gomnd
|
||||
// return fmt.Errorf("wrong default HTTP response code [%d]", f.defaultHTTPCode)
|
||||
// }
|
||||
//
|
||||
// if strings.ContainsRune(f.proxyHTTPHeaders, ' ') {
|
||||
// return fmt.Errorf("whitespaces in the HTTP headers for proxying [%s] are not allowed", f.proxyHTTPHeaders)
|
||||
// }
|
||||
//
|
||||
// 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
|
||||
// }
|
@ -2,13 +2,27 @@ package notfound
|
||||
|
||||
import (
|
||||
"github.com/valyala/fasthttp"
|
||||
|
||||
"gh.tarampamp.am/error-pages/internal/config"
|
||||
"gh.tarampamp.am/error-pages/internal/http/core"
|
||||
"gh.tarampamp.am/error-pages/internal/options"
|
||||
"gh.tarampamp.am/error-pages/internal/tpl"
|
||||
)
|
||||
|
||||
type (
|
||||
templatePicker interface {
|
||||
// Pick the template name for responding.
|
||||
Pick() string
|
||||
}
|
||||
|
||||
renderer interface {
|
||||
Render(content []byte, props tpl.Properties) ([]byte, error)
|
||||
}
|
||||
)
|
||||
|
||||
// NewHandler creates handler missing requests handling.
|
||||
func NewHandler() fasthttp.RequestHandler {
|
||||
func NewHandler(cfg *config.Config, p templatePicker, rdr renderer, opt options.ErrorPage) fasthttp.RequestHandler {
|
||||
return func(ctx *fasthttp.RequestCtx) {
|
||||
ctx.SetContentType("text/plain; charset=utf-8")
|
||||
ctx.SetStatusCode(fasthttp.StatusNotFound)
|
||||
_, _ = ctx.WriteString("Wrong request URL. Error pages are available at the following URLs: /{code}.html")
|
||||
core.RespondWithErrorPage(ctx, cfg, p, rdr, "404", fasthttp.StatusNotFound, opt)
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ func (s *Server) Register(cfg *config.Config, templatePicker templatePicker, opt
|
||||
|
||||
s.router.GET("/metrics", metricsHandler.NewHandler(reg))
|
||||
|
||||
s.router.NotFound = notfoundHandler.NewHandler()
|
||||
s.router.NotFound = notfoundHandler.NewHandler(cfg, templatePicker, s.rdr, opt)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -3,5 +3,5 @@ GET http://{{ host }}:{{ port }}/not-found
|
||||
HTTP/* 404
|
||||
|
||||
[Asserts]
|
||||
header "Content-Type" contains "text/plain"
|
||||
body contains "Wrong request URL"
|
||||
header "Content-Type" contains "text/html"
|
||||
body contains "The server can not find the requested page"
|
||||
|
Loading…
Reference in New Issue
Block a user