httpcaddyfile: Add error directive for the existing handler (#4034)

* httpcaddyfile: Add `error` directive for the existing handler

* httpcaddyfile: Move `error` to the end of the order
This commit is contained in:
Francis Lavoie 2021-03-12 15:25:49 -05:00 committed by GitHub
parent f137b82227
commit 0d7fe36007
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 1 deletions

View file

@ -42,6 +42,7 @@ func init() {
RegisterHandlerDirective("redir", parseRedir) RegisterHandlerDirective("redir", parseRedir)
RegisterHandlerDirective("respond", parseRespond) RegisterHandlerDirective("respond", parseRespond)
RegisterHandlerDirective("abort", parseAbort) RegisterHandlerDirective("abort", parseAbort)
RegisterHandlerDirective("error", parseError)
RegisterHandlerDirective("route", parseRoute) RegisterHandlerDirective("route", parseRoute)
RegisterHandlerDirective("handle", parseHandle) RegisterHandlerDirective("handle", parseHandle)
RegisterDirective("handle_errors", parseHandleErrors) RegisterDirective("handle_errors", parseHandleErrors)
@ -566,6 +567,16 @@ func parseAbort(h Helper) (caddyhttp.MiddlewareHandler, error) {
return &caddyhttp.StaticResponse{Abort: true}, nil return &caddyhttp.StaticResponse{Abort: true}, nil
} }
// parseError parses the error directive.
func parseError(h Helper) (caddyhttp.MiddlewareHandler, error) {
se := new(caddyhttp.StaticError)
err := se.UnmarshalCaddyfile(h.Dispenser)
if err != nil {
return nil, err
}
return se, nil
}
// parseRoute parses the route directive. // parseRoute parses the route directive.
func parseRoute(h Helper) (caddyhttp.MiddlewareHandler, error) { func parseRoute(h Helper) (caddyhttp.MiddlewareHandler, error) {
sr := new(caddyhttp.Subroute) sr := new(caddyhttp.Subroute)

View file

@ -70,6 +70,7 @@ var directiveOrder = []string{
"file_server", "file_server",
"acme_server", "acme_server",
"abort", "abort",
"error",
} }
// directiveIsOrdered returns true if dir is // directiveIsOrdered returns true if dir is

View file

@ -20,6 +20,7 @@ import (
"strconv" "strconv"
"github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
) )
func init() { func init() {
@ -50,6 +51,50 @@ func (StaticError) CaddyModule() caddy.ModuleInfo {
} }
} }
// UnmarshalCaddyfile sets up the handler from Caddyfile tokens. Syntax:
//
// error [<matcher>] <status>|<message> [<status>] {
// message <text>
// }
//
// If there is just one argument (other than the matcher), it is considered
// to be a status code if it's a valid positive integer of 3 digits.
func (e *StaticError) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
for d.Next() {
args := d.RemainingArgs()
switch len(args) {
case 1:
if len(args[0]) == 3 {
if num, err := strconv.Atoi(args[0]); err == nil && num > 0 {
e.StatusCode = WeakString(args[0])
break
}
}
e.Error = args[0]
case 2:
e.Error = args[0]
e.StatusCode = WeakString(args[1])
default:
return d.ArgErr()
}
for d.NextBlock(0) {
switch d.Val() {
case "message":
if e.Error != "" {
return d.Err("message already specified")
}
if !d.AllArgs(&e.Error) {
return d.ArgErr()
}
default:
return d.Errf("unrecognized subdirective '%s'", d.Val())
}
}
}
return nil
}
func (e StaticError) ServeHTTP(w http.ResponseWriter, r *http.Request, _ Handler) error { func (e StaticError) ServeHTTP(w http.ResponseWriter, r *http.Request, _ Handler) error {
repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer) repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
@ -66,4 +111,7 @@ func (e StaticError) ServeHTTP(w http.ResponseWriter, r *http.Request, _ Handler
} }
// Interface guard // Interface guard
var _ MiddlewareHandler = (*StaticError)(nil) var (
_ MiddlewareHandler = (*StaticError)(nil)
_ caddyfile.Unmarshaler = (*StaticError)(nil)
)