@marcel91200 / caddy Mirror · read-only / commits / e7336cc3
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 12, 14:30 UTC

replacer: use RWMutex to protect static provider (#6184)

Mohammed Al Sahaf committed Mar 21, 2024 at 21:15 UTC e7336cc3bfcf60eb775c60509d521e92a5a3b6fe
2 files changed +18 -3
replacer.go
+14 -3
@@ -22,13 +22,15 @@ import (
22 "runtime"
23 "strconv"
24 "strings"
25 + "sync"
26 "time"
27 )
28
29 // NewReplacer returns a new Replacer.
30 func NewReplacer() *Replacer {
31 rep := &Replacer{
31 - static: make(map[string]any),
32 + static: make(map[string]any),
33 + mapMutex: &sync.RWMutex{},
34 }
35 rep.providers = []ReplacerFunc{
36 globalDefaultReplacements,
@@ -41,7 +43,8 @@ func NewReplacer() *Replacer {
43 // without the global default replacements.
44 func NewEmptyReplacer() *Replacer {
45 rep := &Replacer{
44 - static: make(map[string]any),
46 + static: make(map[string]any),
47 + mapMutex: &sync.RWMutex{},
48 }
49 rep.providers = []ReplacerFunc{
50 rep.fromStatic,
@@ -54,7 +57,9 @@ func NewEmptyReplacer() *Replacer {
57 // use NewReplacer to make one.
58 type Replacer struct {
59 providers []ReplacerFunc
57 - static map[string]any
60 +
61 + static map[string]any
62 + mapMutex *sync.RWMutex
63 }
64
65 // Map adds mapFunc to the list of value providers.
@@ -65,7 +70,9 @@ func (r *Replacer) Map(mapFunc ReplacerFunc) {
70
71 // Set sets a custom variable to a static value.
72 func (r *Replacer) Set(variable string, value any) {
73 + r.mapMutex.Lock()
74 r.static[variable] = value
75 + r.mapMutex.Unlock()
76 }
77
78 // Get gets a value from the replacer. It returns
@@ -89,11 +96,15 @@ func (r *Replacer) GetString(variable string) (string, bool) {
96 // Delete removes a variable with a static value
97 // that was created using Set.
98 func (r *Replacer) Delete(variable string) {
99 + r.mapMutex.Lock()
100 delete(r.static, variable)
101 + r.mapMutex.Unlock()
102 }
103
104 // fromStatic provides values from r.static.
105 func (r *Replacer) fromStatic(key string) (any, bool) {
106 + r.mapMutex.RLock()
107 + defer r.mapMutex.RUnlock()
108 val, ok := r.static[key]
109 return val, ok
110 }
replacer_test.go
+4
@@ -19,6 +19,7 @@ import (
19 "os"
20 "path/filepath"
21 "runtime"
22 + "sync"
23 "testing"
24 )
25
@@ -238,6 +239,7 @@ func TestReplacerSet(t *testing.T) {
239
240 func TestReplacerReplaceKnown(t *testing.T) {
241 rep := Replacer{
242 + mapMutex: &sync.RWMutex{},
243 providers: []ReplacerFunc{
244 // split our possible vars to two functions (to test if both functions are called)
245 func(key string) (val any, ok bool) {
@@ -310,6 +312,7 @@ func TestReplacerReplaceKnown(t *testing.T) {
312
313 func TestReplacerDelete(t *testing.T) {
314 rep := Replacer{
315 + mapMutex: &sync.RWMutex{},
316 static: map[string]any{
317 "key1": "val1",
318 "key2": "val2",
@@ -463,5 +466,6 @@ func testReplacer() Replacer {
466 return Replacer{
467 providers: make([]ReplacerFunc, 0),
468 static: make(map[string]any),
469 + mapMutex: &sync.RWMutex{},
470 }
471 }