Skip to content

Commit 3f39d54

Browse files
committed
Transport: Add support for global request headers
hdr := http.Header{} hdr.Set("Accept", "application/yaml") hdr.Set("Authorization", "Bearer 46ToAxZ2ZGZCaDhEVVNJQ0J1dUYzdGZxa1BB") es, err := elasticsearch.NewClient( elasticsearch.Config{ Header: hdr, }, ) res, _ := es.Info() fmt.Println(res) # [200 OK] --- # name: "es1" # ... Related: * #136 * #84 * #106 (comment)
1 parent fc7f75e commit 3f39d54

5 files changed

+95
-0
lines changed

elasticsearch.go

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ type Config struct {
3737
CloudID string // Endpoint for the Elastic Service (https://elastic.co/cloud).
3838
APIKey string // Base64-encoded token for authorization; if set, overrides username and password.
3939

40+
Header http.Header // Global HTTP request header.
41+
4042
// PEM-encoded certificate authorities.
4143
// When set, an empty certificate pool will be created, and the certificates will be appended to it.
4244
// The option is only valid when the transport is not specified, or when it's http.Transport.
@@ -139,6 +141,7 @@ func NewClient(cfg Config) (*Client, error) {
139141
Password: cfg.Password,
140142
APIKey: cfg.APIKey,
141143

144+
Header: cfg.Header,
142145
CACert: cfg.CACert,
143146

144147
RetryOnStatus: cfg.RetryOnStatus,

estransport/estransport.go

+17
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type Config struct {
5454
Password string
5555
APIKey string
5656

57+
Header http.Header
5758
CACert []byte
5859

5960
RetryOnStatus []int
@@ -83,6 +84,7 @@ type Client struct {
8384
username string
8485
password string
8586
apikey string
87+
header http.Header
8688

8789
retryOnStatus []int
8890
disableRetry bool
@@ -144,6 +146,7 @@ func New(cfg Config) (*Client, error) {
144146
username: cfg.Username,
145147
password: cfg.Password,
146148
apikey: cfg.APIKey,
149+
header: cfg.Header,
147150

148151
retryOnStatus: cfg.RetryOnStatus,
149152
disableRetry: cfg.DisableRetry,
@@ -205,6 +208,7 @@ func (c *Client) Perform(req *http.Request) (*http.Response, error) {
205208

206209
// Update request
207210
c.setReqUserAgent(req)
211+
c.setReqGlobalHeader(req)
208212

209213
if req.Body != nil && req.Body != http.NoBody && req.GetBody == nil {
210214
if !c.disableRetry || (c.logger != nil && c.logger.RequestBodyEnabled()) {
@@ -376,6 +380,19 @@ func (c *Client) setReqUserAgent(req *http.Request) *http.Request {
376380
return req
377381
}
378382

383+
func (c *Client) setReqGlobalHeader(req *http.Request) *http.Request {
384+
if len(c.header) > 0 {
385+
for k, v := range c.header {
386+
if req.Header.Get(k) != k {
387+
for _, vv := range v {
388+
req.Header.Add(k, vv)
389+
}
390+
}
391+
}
392+
}
393+
return req
394+
}
395+
379396
func (c *Client) logRoundTrip(
380397
req *http.Request,
381398
res *http.Response,

estransport/estransport_benchmark_test.go

+19
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,23 @@ func BenchmarkTransport(b *testing.B) {
5353
}
5454
}
5555
})
56+
57+
b.Run("Headers", func(b *testing.B) {
58+
hdr := http.Header{}
59+
hdr.Set("Accept", "application/yaml")
60+
61+
for i := 0; i < b.N; i++ {
62+
tp, _ := estransport.New(estransport.Config{
63+
URLs: []*url.URL{{Scheme: "http", Host: "foo"}},
64+
Header: hdr,
65+
Transport: newFakeTransport(b),
66+
})
67+
68+
req, _ := http.NewRequest("GET", "/abc", nil)
69+
_, err := tp.Perform(req)
70+
if err != nil {
71+
b.Fatalf("Unexpected error: %s", err)
72+
}
73+
}
74+
})
5675
}

estransport/estransport_integration_test.go

+28
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,31 @@ func TestTransportRetries(t *testing.T) {
7070
})
7171
}
7272
}
73+
74+
func TestTransportHeaders(t *testing.T) {
75+
u, _ := url.Parse("http://localhost:9200")
76+
77+
hdr := http.Header{}
78+
hdr.Set("Accept", "application/yaml")
79+
80+
tp, _ := estransport.New(estransport.Config{
81+
URLs: []*url.URL{u},
82+
Header: hdr,
83+
})
84+
85+
req, _ := http.NewRequest("GET", "/", nil)
86+
res, err := tp.Perform(req)
87+
if err != nil {
88+
t.Fatalf("Unexpected error: %s", err)
89+
}
90+
defer res.Body.Close()
91+
92+
body, err := ioutil.ReadAll(res.Body)
93+
if err != nil {
94+
t.Fatalf("Unexpected error: %s", err)
95+
}
96+
97+
if !bytes.HasPrefix(body, []byte("---")) {
98+
t.Errorf("Unexpected response body:\n%s", body)
99+
}
100+
}

estransport/estransport_internal_test.go

+28
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,34 @@ func TestTransportPerform(t *testing.T) {
339339
}
340340
})
341341

342+
t.Run("Sets global HTTP request headers", func(t *testing.T) {
343+
hdr := http.Header{}
344+
hdr.Set("X-Foo", "bar")
345+
346+
tp, _ := New(Config{Header: hdr})
347+
348+
{
349+
// Set the global HTTP header
350+
req, _ := http.NewRequest("GET", "/abc", nil)
351+
tp.setReqGlobalHeader(req)
352+
353+
if req.Header.Get("X-Foo") != "bar" {
354+
t.Errorf("Unexpected global HTTP request header value: %s", req.Header.Get("X-Foo"))
355+
}
356+
}
357+
358+
{
359+
// Do NOT overwrite an existing request header
360+
req, _ := http.NewRequest("GET", "/abc", nil)
361+
req.Header.Set("X-Foo", "baz")
362+
tp.setReqGlobalHeader(req)
363+
364+
if req.Header.Get("X-Foo") != "baz" {
365+
t.Errorf("Unexpected global HTTP request header value: %s", req.Header.Get("X-Foo"))
366+
}
367+
}
368+
})
369+
342370
t.Run("Error No URL", func(t *testing.T) {
343371
tp, _ := New(Config{
344372
URLs: []*url.URL{},

0 commit comments

Comments
 (0)