From f259ed52bb3764ce4fd5d88f1712cb43247c2639 Mon Sep 17 00:00:00 2001 From: jhwz <52683873+jhwz@users.noreply.github.com> Date: Thu, 7 Jul 2022 07:50:07 +1200 Subject: admin: support ETag on config endpoints (#4579) * admin: support ETags * support etags Co-authored-by: Matt Holt --- admin_test.go | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) (limited to 'admin_test.go') diff --git a/admin_test.go b/admin_test.go index 608a32c..32f20c6 100644 --- a/admin_test.go +++ b/admin_test.go @@ -15,7 +15,9 @@ package caddy import ( + "encoding/hex" "encoding/json" + "net/http" "reflect" "sync" "testing" @@ -139,10 +141,57 @@ func TestLoadConcurrent(t *testing.T) { wg.Done() }() } - wg.Wait() } +type fooModule struct { + IntField int + StrField string +} + +func (fooModule) CaddyModule() ModuleInfo { + return ModuleInfo{ + ID: "foo", + New: func() Module { return new(fooModule) }, + } +} +func (fooModule) Start() error { return nil } +func (fooModule) Stop() error { return nil } + +func TestETags(t *testing.T) { + RegisterModule(fooModule{}) + + if err := Load([]byte(`{"apps": {"foo": {"strField": "abc", "intField": 0}}}`), true); err != nil { + t.Fatalf("loading: %s", err) + } + + const key = "/" + rawConfigKey + "/apps/foo" + + // try update the config with the wrong etag + err := changeConfig(http.MethodPost, key, []byte(`{"strField": "abc", "intField": 1}}`), "/"+rawConfigKey+" not_an_etag", false) + if apiErr, ok := err.(APIError); !ok || apiErr.HTTPStatus != http.StatusPreconditionFailed { + t.Fatalf("expected precondition failed; got %v", err) + } + + // get the etag + hash := etagHasher() + if err := readConfig(key, hash); err != nil { + t.Fatalf("reading: %s", err) + } + + // do the same update with the correct key + err = changeConfig(http.MethodPost, key, []byte(`{"strField": "abc", "intField": 1}`), key+" "+hex.EncodeToString(hash.Sum(nil)), false) + if err != nil { + t.Fatalf("expected update to work; got %v", err) + } + + // now try another update. The hash should no longer match and we should get precondition failed + err = changeConfig(http.MethodPost, key, []byte(`{"strField": "abc", "intField": 2}`), key+" "+hex.EncodeToString(hash.Sum(nil)), false) + if apiErr, ok := err.(APIError); !ok || apiErr.HTTPStatus != http.StatusPreconditionFailed { + t.Fatalf("expected precondition failed; got %v", err) + } +} + func BenchmarkLoad(b *testing.B) { for i := 0; i < b.N; i++ { Load(testCfg, true) -- cgit v1.2.3