Skip to content

Commit 7d7f517

Browse files
authored
Merge pull request #65 from stevenctl/main
make headers modification concurrent-safe
2 parents d758353 + 5c849de commit 7d7f517

File tree

1 file changed

+35
-15
lines changed

1 file changed

+35
-15
lines changed

client.go

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"net/http"
99
"net/url"
1010
"path"
11+
"sync"
1112
)
1213

1314
var (
@@ -44,16 +45,15 @@ func NewClientWithError(rawURL, schema string, headers map[string]string) (*Clie
4445
}
4546

4647
// Set required headers
47-
c.Transport.header.Set("Accept", "application/json")
48-
c.Transport.header.Set("Content-Type", "application/json")
49-
c.Transport.header.Set("Accept-Profile", schema)
50-
c.Transport.header.Set("Content-Profile", schema)
51-
c.Transport.header.Set("X-Client-Info", "postgrest-go/"+version)
52-
48+
c.Transport.SetHeaders(map[string]string{
49+
"Accept": "application/json",
50+
"Content-Type": "application/json",
51+
"Accept-Profile": schema,
52+
"Content-Profile": schema,
53+
"X-Client-Info": "postgrest-go/" + version,
54+
})
5355
// Set optional headers if they exist
54-
for key, value := range headers {
55-
c.Transport.header.Set(key, value)
56-
}
56+
c.Transport.SetHeaders(headers)
5757

5858
return &c, nil
5959
}
@@ -96,20 +96,22 @@ func (c *Client) Ping() bool {
9696

9797
// SetApiKey sets api key header for subsequent requests.
9898
func (c *Client) SetApiKey(apiKey string) *Client {
99-
c.Transport.header.Set("apikey", apiKey)
99+
c.Transport.SetHeader("apikey", apiKey)
100100
return c
101101
}
102102

103103
// SetAuthToken sets authorization header for subsequent requests.
104104
func (c *Client) SetAuthToken(authToken string) *Client {
105-
c.Transport.header.Set("Authorization", "Bearer "+authToken)
105+
c.Transport.SetHeader("Authorization", "Bearer "+authToken)
106106
return c
107107
}
108108

109109
// ChangeSchema modifies the schema for subsequent requests.
110110
func (c *Client) ChangeSchema(schema string) *Client {
111-
c.Transport.header.Set("Accept-Profile", schema)
112-
c.Transport.header.Set("Content-Profile", schema)
111+
c.Transport.SetHeaders(map[string]string{
112+
"Accept-Profile": schema,
113+
"Content-Profile": schema,
114+
})
113115
return c
114116
}
115117

@@ -174,17 +176,35 @@ func (c *Client) Rpc(name string, count string, rpcBody interface{}) string {
174176
}
175177

176178
type transport struct {
177-
header http.Header
178179
baseURL url.URL
179180
Parent http.RoundTripper
181+
182+
mu sync.RWMutex
183+
header http.Header
184+
}
185+
186+
func (t *transport) SetHeader(key, value string) {
187+
t.mu.Lock()
188+
defer t.mu.Unlock()
189+
t.header.Set(key, value)
190+
}
191+
192+
func (t *transport) SetHeaders(headers map[string]string) {
193+
t.mu.Lock()
194+
defer t.mu.Unlock()
195+
for key, value := range headers {
196+
t.header.Set(key, value)
197+
}
180198
}
181199

182-
func (t transport) RoundTrip(req *http.Request) (*http.Response, error) {
200+
func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
201+
t.mu.RLock()
183202
for headerName, values := range t.header {
184203
for _, val := range values {
185204
req.Header.Add(headerName, val)
186205
}
187206
}
207+
t.mu.RUnlock()
188208

189209
req.URL = t.baseURL.ResolveReference(req.URL)
190210

0 commit comments

Comments
 (0)