@@ -3,47 +3,56 @@ package openapi3filter
3
3
import (
4
4
"encoding/json"
5
5
"fmt"
6
+ "sync"
6
7
)
7
8
8
9
func encodeBody (body interface {}, mediaType string ) ([]byte , error ) {
9
- encoder , ok := bodyEncoders [ mediaType ]
10
- if ! ok {
11
- return nil , & ParseError {
12
- Kind : KindUnsupportedFormat ,
13
- Reason : fmt . Sprintf ( "%s %q" , prefixUnsupportedCT , mediaType ) ,
14
- }
10
+ if encoder := RegisteredBodyEncoder ( mediaType ); encoder != nil {
11
+ return encoder ( body )
12
+ }
13
+ return nil , & ParseError {
14
+ Kind : KindUnsupportedFormat ,
15
+ Reason : fmt . Sprintf ( "%s %q" , prefixUnsupportedCT , mediaType ),
15
16
}
16
- return encoder (body )
17
17
}
18
18
19
+ // BodyEncoder really is an (encoding/json).Marshaler
19
20
type BodyEncoder func (body interface {}) ([]byte , error )
20
21
22
+ var bodyEncodersM sync.RWMutex
21
23
var bodyEncoders = map [string ]BodyEncoder {
22
24
"application/json" : json .Marshal ,
23
25
}
24
26
27
+ // RegisterBodyEncoder enables package-wide decoding of contentType values
25
28
func RegisterBodyEncoder (contentType string , encoder BodyEncoder ) {
26
29
if contentType == "" {
27
30
panic ("contentType is empty" )
28
31
}
29
32
if encoder == nil {
30
33
panic ("encoder is not defined" )
31
34
}
35
+ bodyEncodersM .Lock ()
32
36
bodyEncoders [contentType ] = encoder
37
+ bodyEncodersM .Unlock ()
33
38
}
34
39
35
- // This call is not thread-safe: body encoders should not be created/destroyed by multiple goroutines.
40
+ // UnregisterBodyEncoder disables package-wide decoding of contentType values
36
41
func UnregisterBodyEncoder (contentType string ) {
37
42
if contentType == "" {
38
43
panic ("contentType is empty" )
39
44
}
45
+ bodyEncodersM .Lock ()
40
46
delete (bodyEncoders , contentType )
47
+ bodyEncodersM .Unlock ()
41
48
}
42
49
43
50
// RegisteredBodyEncoder returns the registered body encoder for the given content type.
44
51
//
45
52
// If no encoder was registered for the given content type, nil is returned.
46
- // This call is not thread-safe: body encoders should not be created/destroyed by multiple goroutines.
47
53
func RegisteredBodyEncoder (contentType string ) BodyEncoder {
48
- return bodyEncoders [contentType ]
54
+ bodyEncodersM .RLock ()
55
+ mayBE := bodyEncoders [contentType ]
56
+ bodyEncodersM .RUnlock ()
57
+ return mayBE
49
58
}
0 commit comments