Skip to content

Commit 5c849de

Browse files
committed
make headers modification concurrent-safe
1 parent f587e92 commit 5c849de

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 NewClient(rawURL, schema string, headers map[string]string) *Client {
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
5959
}
@@ -84,20 +84,22 @@ func (c *Client) Ping() bool {
8484

8585
// SetApiKey sets api key header for subsequent requests.
8686
func (c *Client) SetApiKey(apiKey string) *Client {
87-
c.Transport.header.Set("apikey", apiKey)
87+
c.Transport.SetHeader("apikey", apiKey)
8888
return c
8989
}
9090

9191
// SetAuthToken sets authorization header for subsequent requests.
9292
func (c *Client) SetAuthToken(authToken string) *Client {
93-
c.Transport.header.Set("Authorization", "Bearer "+authToken)
93+
c.Transport.SetHeader("Authorization", "Bearer "+authToken)
9494
return c
9595
}
9696

9797
// ChangeSchema modifies the schema for subsequent requests.
9898
func (c *Client) ChangeSchema(schema string) *Client {
99-
c.Transport.header.Set("Accept-Profile", schema)
100-
c.Transport.header.Set("Content-Profile", schema)
99+
c.Transport.SetHeaders(map[string]string{
100+
"Accept-Profile": schema,
101+
"Content-Profile": schema,
102+
})
101103
return c
102104
}
103105

@@ -156,17 +158,35 @@ func (c *Client) Rpc(name string, count string, rpcBody interface{}) string {
156158
}
157159

158160
type transport struct {
159-
header http.Header
160161
baseURL url.URL
161162
Parent http.RoundTripper
163+
164+
mu sync.RWMutex
165+
header http.Header
166+
}
167+
168+
func (t *transport) SetHeader(key, value string) {
169+
t.mu.Lock()
170+
defer t.mu.Unlock()
171+
t.header.Set(key, value)
172+
}
173+
174+
func (t *transport) SetHeaders(headers map[string]string) {
175+
t.mu.Lock()
176+
defer t.mu.Unlock()
177+
for key, value := range headers {
178+
t.header.Set(key, value)
179+
}
162180
}
163181

164-
func (t transport) RoundTrip(req *http.Request) (*http.Response, error) {
182+
func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
183+
t.mu.RLock()
165184
for headerName, values := range t.header {
166185
for _, val := range values {
167186
req.Header.Add(headerName, val)
168187
}
169188
}
189+
t.mu.RUnlock()
170190

171191
req.URL = t.baseURL.ResolveReference(req.URL)
172192

0 commit comments

Comments
 (0)