16
17
import (
18
"context"
19
+ "io"
20
"net/http"
21
"net/http/httptest"
22
"strings"
150
"its health state was polluted by vhost A's health check against the same address")
151
}
152
}
153
+
154
+// TestActiveHealthCheckBodyKeepsUnknownPlaceholders is a regression test for
155
+// https://github.com/caddyserver/caddy/issues/7021: an active health check
156
+// body is user-supplied and is commonly JSON, so its braces must not be read
157
+// as placeholders and blanked. Only globals are available to this replacer, so
158
+// replacing everything sent an empty body for any JSON health_request_body.
159
+func TestActiveHealthCheckBodyKeepsUnknownPlaceholders(t *testing.T) {
160
+ resetDynamicHosts()
161
+ defer drainHostsPool()
162
+
163
+ const jsonBody = `{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}`
164
+
165
+ var gotBody atomic.Value
166
+ srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
167
+ body, err := io.ReadAll(r.Body)
168
+ if err != nil {
169
+ t.Errorf("reading request body: %v", err)
170
+ }
171
+ gotBody.Store(string(body))
172
+ w.WriteHeader(http.StatusOK)
173
+ }))
174
+ defer srv.Close()
175
+ addr := strings.TrimPrefix(srv.URL, "http://")
176
+
177
+ h, u, cancel := newActiveHandler(t, addr, "/health", 1)
178
+ defer cancel()
179
+
180
+ h.HealthChecks.Active.Body = jsonBody
181
+
182
+ runActiveHealthCheck(t, h, u)
183
+
184
+ if got, want := gotBody.Load(), jsonBody; got != want {
185
+ t.Errorf("health check body = %q, want %q", got, want)
186
+ }
187
+}
188
+
189
+// TestActiveHealthCheckBodyStillReplacesKnownPlaceholders guards the other
190
+// direction: switching to ReplaceKnown must not stop real placeholders from
191
+// being replaced.
192
+func TestActiveHealthCheckBodyStillReplacesKnownPlaceholders(t *testing.T) {
193
+ resetDynamicHosts()
194
+ defer drainHostsPool()
195
+
196
+ t.Setenv("CADDY_TEST_HEALTH_TOKEN", "s3cret")
197
+
198
+ var gotBody atomic.Value
199
+ srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
200
+ body, err := io.ReadAll(r.Body)
201
+ if err != nil {
202
+ t.Errorf("reading request body: %v", err)
203
+ }
204
+ gotBody.Store(string(body))
205
+ w.WriteHeader(http.StatusOK)
206
+ }))
207
+ defer srv.Close()
208
+ addr := strings.TrimPrefix(srv.URL, "http://")
209
+
210
+ h, u, cancel := newActiveHandler(t, addr, "/health", 1)
211
+ defer cancel()
212
+
213
+ h.HealthChecks.Active.Body = `{"token":"{env.CADDY_TEST_HEALTH_TOKEN}"}`
214
+
215
+ runActiveHealthCheck(t, h, u)
216
+
217
+ if got, want := gotBody.Load(), `{"token":"s3cret"}`; got != want {
218
+ t.Errorf("health check body = %q, want %q", got, want)
219
+ }
220
+}