Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 14, 05:15 UTC
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
Francis Lavoie committed
Mar 12, 2021 at 15:25 UTC
0d7fe36007d5fbadaa6057b6543500d63147e6c0
3 files changed
+61
-1
caddyconfig/httpcaddyfile/builtins.go
+11
@@ -42,6 +42,7 @@ func init() {
42
RegisterHandlerDirective("redir", parseRedir)
43
RegisterHandlerDirective("respond", parseRespond)
44
RegisterHandlerDirective("abort", parseAbort)
45
+ RegisterHandlerDirective("error", parseError)
46
RegisterHandlerDirective("route", parseRoute)
47
RegisterHandlerDirective("handle", parseHandle)
48
RegisterDirective("handle_errors", parseHandleErrors)
@@ -566,6 +567,16 @@ func parseAbort(h Helper) (caddyhttp.MiddlewareHandler, error) {
567
return &caddyhttp.StaticResponse{Abort: true}, nil
568
}
569
570
+// parseError parses the error directive.
571
+func parseError(h Helper) (caddyhttp.MiddlewareHandler, error) {
572
+ se := new(caddyhttp.StaticError)
573
+ err := se.UnmarshalCaddyfile(h.Dispenser)
574
+ if err != nil {
575
+ return nil, err
576
+ }
577
+ return se, nil
578
+}
579
+
580
// parseRoute parses the route directive.
581
func parseRoute(h Helper) (caddyhttp.MiddlewareHandler, error) {
582
sr := new(caddyhttp.Subroute)
caddyconfig/httpcaddyfile/directives.go
+1
@@ -70,6 +70,7 @@ var directiveOrder = []string{
70
"file_server",
71
"acme_server",
72
"abort",
73
+ "error",
74
}
75
76
// directiveIsOrdered returns true if dir is
modules/caddyhttp/staticerror.go
+49
-1
@@ -20,6 +20,7 @@ import (
20
"strconv"
21
22
"github.com/caddyserver/caddy/v2"
23
+ "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
24
)
25
26
func init() {
@@ -50,6 +51,50 @@ func (StaticError) CaddyModule() caddy.ModuleInfo {
51
}
52
}
53
54
+// UnmarshalCaddyfile sets up the handler from Caddyfile tokens. Syntax:
55
+//
56
+// error [<matcher>] <status>|<message> [<status>] {
57
+// message <text>
58
+// }
59
+//
60
+// If there is just one argument (other than the matcher), it is considered
61
+// to be a status code if it's a valid positive integer of 3 digits.
62
+func (e *StaticError) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
63
+ for d.Next() {
64
+ args := d.RemainingArgs()
65
+ switch len(args) {
66
+ case 1:
67
+ if len(args[0]) == 3 {
68
+ if num, err := strconv.Atoi(args[0]); err == nil && num > 0 {
69
+ e.StatusCode = WeakString(args[0])
70
+ break
71
+ }
72
+ }
73
+ e.Error = args[0]
74
+ case 2:
75
+ e.Error = args[0]
76
+ e.StatusCode = WeakString(args[1])
77
+ default:
78
+ return d.ArgErr()
79
+ }
80
+
81
+ for d.NextBlock(0) {
82
+ switch d.Val() {
83
+ case "message":
84
+ if e.Error != "" {
85
+ return d.Err("message already specified")
86
+ }
87
+ if !d.AllArgs(&e.Error) {
88
+ return d.ArgErr()
89
+ }
90
+ default:
91
+ return d.Errf("unrecognized subdirective '%s'", d.Val())
92
+ }
93
+ }
94
+ }
95
+ return nil
96
+}
97
+
98
func (e StaticError) ServeHTTP(w http.ResponseWriter, r *http.Request, _ Handler) error {
99
repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
100
@@ -66,4 +111,7 @@ func (e StaticError) ServeHTTP(w http.ResponseWriter, r *http.Request, _ Handler
111
}
112
113
// Interface guard
69
-var _ MiddlewareHandler = (*StaticError)(nil)
114
+var (
115
+ _ MiddlewareHandler = (*StaticError)(nil)
116
+ _ caddyfile.Unmarshaler = (*StaticError)(nil)
117
+)