Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 11, 04:45 UTC
admin: fix warnings and status code in /load API (#7267)
* admin: fix warnings and status code in /load API * fix admin.go: gci import formatting --------- Signed-off-by: Matt Holt <mholt@users.noreply.github.com> Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
amir daraby committed
Sep 23, 2026 at 18:25 UTC
7e82a6b5281480f464d00d680ffb5573cf2d34a3
4 files changed
+41
-25
admin.go
+5
-3
@@ -46,6 +46,7 @@ import (
46
"go.uber.org/zap"
47
"go.uber.org/zap/zapcore"
48
49
+ "github.com/caddyserver/caddy/v2/caddyconfig/warning"
50
"github.com/caddyserver/caddy/v2/internal"
51
)
52
@@ -1394,9 +1395,10 @@ func (f AdminHandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request) erro
1395
// and client responses. If Message is unset, then
1396
// Err.Error() will be serialized in its place.
1397
type APIError struct {
1397
- HTTPStatus int `json:"-"`
1398
- Err error `json:"-"`
1399
- Message string `json:"error"`
1398
+ HTTPStatus int `json:"-"`
1399
+ Err error `json:"-"`
1400
+ Message string `json:"error"`
1401
+ Warnings []warning.Warning `json:"warnings,omitempty"`
1402
}
1403
1404
func (e APIError) Error() string {
caddyconfig/configadapters.go
+2
-14
@@ -19,6 +19,7 @@ import (
19
"fmt"
20
21
"github.com/caddyserver/caddy/v2"
22
+ "github.com/caddyserver/caddy/v2/caddyconfig/warning"
23
)
24
25
// Adapter is a type which can adapt a configuration to Caddy JSON.
@@ -28,20 +29,7 @@ type Adapter interface {
29
}
30
31
// Warning represents a warning or notice related to conversion.
31
-type Warning struct {
32
- File string `json:"file,omitempty"`
33
- Line int `json:"line,omitempty"`
34
- Directive string `json:"directive,omitempty"`
35
- Message string `json:"message,omitempty"`
36
-}
37
-
38
-func (w Warning) String() string {
39
- var directive string
40
- if w.Directive != "" {
41
- directive = fmt.Sprintf(" (%s)", w.Directive)
42
- }
43
- return fmt.Sprintf("%s:%d%s: %s", w.File, w.Line, directive, w.Message)
44
-}
32
+type Warning = warning.Warning
33
34
// JSON encodes val as JSON, returning it as a json.RawMessage. Any
35
// marshaling errors (which are highly unlikely with correct code)
caddyconfig/load.go
+15
-8
@@ -91,23 +91,19 @@ func (adminLoad) handleLoad(w http.ResponseWriter, r *http.Request) error {
91
}
92
body := buf.Bytes()
93
94
+ var warnings []Warning
95
// if the config is formatted other than Caddy's native
96
// JSON, we need to adapt it before loading it
97
if ctHeader := r.Header.Get("Content-Type"); ctHeader != "" {
97
- result, warnings, err := adaptByContentType(ctHeader, body)
98
+ result, wns, err := adaptByContentType(ctHeader, body)
99
if err != nil {
100
return caddy.APIError{
101
HTTPStatus: http.StatusBadRequest,
102
Err: err,
103
+ Warnings: wns,
104
}
105
}
104
- if len(warnings) > 0 {
105
- respBody, err := json.Marshal(warnings)
106
- if err != nil {
107
- caddy.Log().Named("admin.api.load").Error(err.Error())
108
- }
109
- _, _ = w.Write(respBody) //nolint:gosec // false positive: no XSS here
110
- }
106
+ warnings = wns
107
body = result
108
}
109
@@ -118,6 +114,7 @@ func (adminLoad) handleLoad(w http.ResponseWriter, r *http.Request) error {
114
return caddy.APIError{
115
HTTPStatus: http.StatusBadRequest,
116
Err: fmt.Errorf("loading config: %v", err),
117
+ Warnings: warnings,
118
}
119
}
120
@@ -130,6 +127,16 @@ func (adminLoad) handleLoad(w http.ResponseWriter, r *http.Request) error {
127
128
caddy.Log().Named("admin.api").Info("load complete")
129
130
+ // Send any warnings back even if there were no errors
131
+ if len(warnings) > 0 {
132
+ out := struct {
133
+ Warnings []Warning `json:"warnings"`
134
+ }{
135
+ Warnings: warnings,
136
+ }
137
+ return json.NewEncoder(w).Encode(out)
138
+ }
139
+
140
return nil
141
}
142
caddyconfig/warning/warning.go
new
+19
@@ -0,0 +1,19 @@
1
+package warning
2
+
3
+import "fmt"
4
+
5
+// Warning represents a warning or notice related to conversion.
6
+type Warning struct {
7
+ File string `json:"file,omitempty"`
8
+ Line int `json:"line,omitempty"`
9
+ Directive string `json:"directive,omitempty"`
10
+ Message string `json:"message,omitempty"`
11
+}
12
+
13
+func (w Warning) String() string {
14
+ var directive string
15
+ if w.Directive != "" {
16
+ directive = fmt.Sprintf(" (%s)", w.Directive)
17
+ }
18
+ return fmt.Sprintf("%s:%d%s: %s", w.File, w.Line, directive, w.Message)
19
+}