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
}