Skip to content

Commit 3e93e18

Browse files
committed
Add HTTP headers to all services and to client
This commit enables users to pass additional HTTP headers on every service. Users can use the `Header(name, value string)` and the `Headers(http.Header)` methods to specify custom HTTP headers on the request level. Furthermore, users can specify a set of HTTP headers to sent on every invocation of `PerformRequest` by using `elastic.SetHeaders(http.Header)` when creating the client. Request-level HTTP headers have preference over client-level HTTP headers. Close #1200
1 parent 999c48f commit 3e93e18

File tree

106 files changed

+1479
-258
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+1479
-258
lines changed

CONTRIBUTORS

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ André Bierlein [@ligustah](https://github.com/ligustah)
2323
Andrew Dunham [@andrew-d](https://github.com/andrew-d)
2424
Andrew Gaul [@andrewgaul](https://github.com/andrewgaul)
2525
Andy Walker [@alaska](https://github.com/alaska)
26+
Arpit Agarwal [@arpiagar](https://github.com/arpiagar)
2627
Arquivei [@arquivei](https://github.com/arquivei)
2728
Artemiy Elozhenko [@artezh](https://github.com/artezh)
2829
arthurgustin [@arthurgustin](https://github.com/arthurgustin)

bulk.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ type BulkService struct {
4343
// estimated bulk size in bytes, up to the request index sizeInBytesCursor
4444
sizeInBytes int64
4545
sizeInBytesCursor int
46-
headers http.Header
46+
47+
headers http.Header
4748
}
4849

4950
// NewBulkService initializes a new BulkService.
@@ -138,7 +139,7 @@ func (s *BulkService) Add(requests ...BulkableRequest) *BulkService {
138139
return s
139140
}
140141

141-
// Header sets headers on the request
142+
// Header adds a header to the request.
142143
func (s *BulkService) Header(name string, value string) *BulkService {
143144
if s.headers == nil {
144145
s.headers = http.Header{}
@@ -147,6 +148,12 @@ func (s *BulkService) Header(name string, value string) *BulkService {
147148
return s
148149
}
149150

151+
// Headers specifies the headers of the request.
152+
func (s *BulkService) Headers(headers http.Header) *BulkService {
153+
s.headers = headers
154+
return s
155+
}
156+
150157
// EstimatedSizeInBytes returns the estimated size of all bulkable
151158
// requests added via Add.
152159
func (s *BulkService) EstimatedSizeInBytes() int64 {

cat_aliases.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func (s *CatAliasesService) Pretty(pretty bool) *CatAliasesService {
8282
return s
8383
}
8484

85-
// Header sets headers on the request
85+
// Header adds a header to the request.
8686
func (s *CatAliasesService) Header(name string, value string) *CatAliasesService {
8787
if s.headers == nil {
8888
s.headers = http.Header{}
@@ -91,6 +91,12 @@ func (s *CatAliasesService) Header(name string, value string) *CatAliasesService
9191
return s
9292
}
9393

94+
// Headers specifies the headers of the request.
95+
func (s *CatAliasesService) Headers(headers http.Header) *CatAliasesService {
96+
s.headers = headers
97+
return s
98+
}
99+
94100
// buildURL builds the URL for the operation.
95101
func (s *CatAliasesService) buildURL() (string, url.Values, error) {
96102
// Build URL

cat_allocation.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func (s *CatAllocationService) Pretty(pretty bool) *CatAllocationService {
9090
return s
9191
}
9292

93-
// Header sets headers on the request
93+
// Header adds a header to the request.
9494
func (s *CatAllocationService) Header(name string, value string) *CatAllocationService {
9595
if s.headers == nil {
9696
s.headers = http.Header{}
@@ -99,6 +99,12 @@ func (s *CatAllocationService) Header(name string, value string) *CatAllocationS
9999
return s
100100
}
101101

102+
// Headers specifies the headers of the request.
103+
func (s *CatAllocationService) Headers(headers http.Header) *CatAllocationService {
104+
s.headers = headers
105+
return s
106+
}
107+
102108
// buildURL builds the URL for the operation.
103109
func (s *CatAllocationService) buildURL() (string, url.Values, error) {
104110
// Build URL

cat_count.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func (s *CatCountService) Pretty(pretty bool) *CatCountService {
8383
return s
8484
}
8585

86-
// Header sets headers on the request
86+
// Header adds a header to the request.
8787
func (s *CatCountService) Header(name string, value string) *CatCountService {
8888
if s.headers == nil {
8989
s.headers = http.Header{}
@@ -92,6 +92,12 @@ func (s *CatCountService) Header(name string, value string) *CatCountService {
9292
return s
9393
}
9494

95+
// Headers specifies the headers of the request.
96+
func (s *CatCountService) Headers(headers http.Header) *CatCountService {
97+
s.headers = headers
98+
return s
99+
}
100+
95101
// buildURL builds the URL for the operation.
96102
func (s *CatCountService) buildURL() (string, url.Values, error) {
97103
// Build URL

cat_health.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func (s *CatHealthService) Pretty(pretty bool) *CatHealthService {
8080
return s
8181
}
8282

83-
// Header sets headers on the request
83+
// Header adds a header to the request.
8484
func (s *CatHealthService) Header(name string, value string) *CatHealthService {
8585
if s.headers == nil {
8686
s.headers = http.Header{}
@@ -89,6 +89,12 @@ func (s *CatHealthService) Header(name string, value string) *CatHealthService {
8989
return s
9090
}
9191

92+
// Headers specifies the headers of the request.
93+
func (s *CatHealthService) Headers(headers http.Header) *CatHealthService {
94+
s.headers = headers
95+
return s
96+
}
97+
9298
// buildURL builds the URL for the operation.
9399
func (s *CatHealthService) buildURL() (string, url.Values, error) {
94100
// Build URL

cat_indices.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func (s *CatIndicesService) Pretty(pretty bool) *CatIndicesService {
105105
return s
106106
}
107107

108-
// Header sets headers on the request
108+
// Header adds a header to the request.
109109
func (s *CatIndicesService) Header(name string, value string) *CatIndicesService {
110110
if s.headers == nil {
111111
s.headers = http.Header{}
@@ -114,6 +114,12 @@ func (s *CatIndicesService) Header(name string, value string) *CatIndicesService
114114
return s
115115
}
116116

117+
// Headers specifies the headers of the request.
118+
func (s *CatIndicesService) Headers(headers http.Header) *CatIndicesService {
119+
s.headers = headers
120+
return s
121+
}
122+
117123
// buildURL builds the URL for the operation.
118124
func (s *CatIndicesService) buildURL() (string, url.Values, error) {
119125
// Build URL

clear_scroll.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func (s *ClearScrollService) Pretty(pretty bool) *ClearScrollService {
4343
return s
4444
}
4545

46-
// Header sets headers on the request
46+
// Header adds a header to the request.
4747
func (s *ClearScrollService) Header(name string, value string) *ClearScrollService {
4848
if s.headers == nil {
4949
s.headers = http.Header{}
@@ -52,6 +52,12 @@ func (s *ClearScrollService) Header(name string, value string) *ClearScrollServi
5252
return s
5353
}
5454

55+
// Headers specifies the headers of the request.
56+
func (s *ClearScrollService) Headers(headers http.Header) *ClearScrollService {
57+
s.headers = headers
58+
return s
59+
}
60+
5561
// buildURL builds the URL for the operation.
5662
func (s *ClearScrollService) buildURL() (string, url.Values, error) {
5763
// Build URL

client.go

+18-2
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ type Client struct {
143143
gzipEnabled bool // gzip compression enabled or disabled (default)
144144
requiredPlugins []string // list of required plugins
145145
retrier Retrier // strategy for retries
146+
headers http.Header // a list of default headers to add to each request
146147
}
147148

148149
// NewClient creates a new client to work with Elasticsearch.
@@ -720,6 +721,15 @@ func SetRetrier(retrier Retrier) ClientOptionFunc {
720721
}
721722
}
722723

724+
// SetHeaders adds a list of default HTTP headers that will be added to
725+
// each requests executed by PerformRequest.
726+
func SetHeaders(headers http.Header) ClientOptionFunc {
727+
return func(c *Client) error {
728+
c.headers = headers
729+
return nil
730+
}
731+
}
732+
723733
// String returns a string representation of the client status.
724734
func (c *Client) String() string {
725735
c.connsMu.Lock()
@@ -1263,6 +1273,7 @@ func (c *Client) PerformRequest(ctx context.Context, opt PerformRequestOptions)
12631273
if opt.Retrier != nil {
12641274
retrier = opt.Retrier
12651275
}
1276+
defaultHeaders := c.headers
12661277
c.mu.RUnlock()
12671278

12681279
var err error
@@ -1312,21 +1323,26 @@ func (c *Client) PerformRequest(ctx context.Context, opt PerformRequestOptions)
13121323
c.errorf("elastic: cannot create request for %s %s: %v", strings.ToUpper(opt.Method), conn.URL()+pathWithParams, err)
13131324
return nil, err
13141325
}
1315-
13161326
if basicAuth {
13171327
req.SetBasicAuth(basicAuthUsername, basicAuthPassword)
13181328
}
13191329
if opt.ContentType != "" {
13201330
req.Header.Set("Content-Type", opt.ContentType)
13211331
}
1322-
13231332
if len(opt.Headers) > 0 {
13241333
for key, value := range opt.Headers {
13251334
for _, v := range value {
13261335
req.Header.Add(key, v)
13271336
}
13281337
}
13291338
}
1339+
if len(defaultHeaders) > 0 {
1340+
for key, value := range defaultHeaders {
1341+
for _, v := range value {
1342+
req.Header.Add(key, v)
1343+
}
1344+
}
1345+
}
13301346

13311347
// Set body
13321348
if opt.Body != nil {

client_test.go

+80-1
Original file line numberDiff line numberDiff line change
@@ -1434,6 +1434,7 @@ func TestPerformRequestWithCancel(t *testing.T) {
14341434
err error
14351435
}
14361436
ctx, cancel := context.WithCancel(context.Background())
1437+
defer cancel()
14371438

14381439
resc := make(chan result, 1)
14391440
go func() {
@@ -1492,7 +1493,7 @@ func TestPerformRequestWithTimeout(t *testing.T) {
14921493
}
14931494
}
14941495

1495-
func TestPerformRequestWithCustomHeader(t *testing.T) {
1496+
func TestPerformRequestWithCustomHTTPHeadersOnRequest(t *testing.T) {
14961497
client, err := NewClient()
14971498
if err != nil {
14981499
t.Fatal(err)
@@ -1518,6 +1519,84 @@ func TestPerformRequestWithCustomHeader(t *testing.T) {
15181519
}
15191520
}
15201521

1522+
func TestPerformRequestWithCustomHTTPHeadersOnClient(t *testing.T) {
1523+
client, err := NewClient(SetHeaders(http.Header{
1524+
"Custom-Id": []string{"olivere"},
1525+
"X-Opaque-Id": []string{"sandra"},
1526+
}))
1527+
if err != nil {
1528+
t.Fatal(err)
1529+
}
1530+
res, err := client.PerformRequest(context.TODO(), PerformRequestOptions{
1531+
Method: "GET",
1532+
Path: "/_tasks",
1533+
Params: url.Values{
1534+
"pretty": []string{"true"},
1535+
},
1536+
Headers: http.Header{
1537+
"X-Opaque-Id": []string{"123456"},
1538+
},
1539+
})
1540+
if err != nil {
1541+
t.Fatal(err)
1542+
}
1543+
if res == nil {
1544+
t.Fatal("expected response to be != nil")
1545+
}
1546+
// Request-level headers have preference
1547+
if want, have := "123456", res.Header.Get("X-Opaque-Id"); want != have {
1548+
t.Fatalf("want response header X-Opaque-Id=%q, have %q", want, have)
1549+
}
1550+
}
1551+
1552+
func TestPerformRequestWithCustomHTTPHeadersPriority(t *testing.T) {
1553+
var req *http.Request
1554+
h := func(r *http.Request) (*http.Response, error) {
1555+
req = new(http.Request)
1556+
*req = *r
1557+
return &http.Response{Request: r, StatusCode: http.StatusOK, Body: http.NoBody}, nil
1558+
}
1559+
tr := &failingTransport{path: "/", fail: h}
1560+
httpClient := &http.Client{Transport: tr}
1561+
1562+
client, err := NewClient(SetHttpClient(httpClient), SetHeaders(http.Header{
1563+
"Custom-Id": []string{"olivere"},
1564+
"X-Opaque-Id": []string{"sandra"}, // <- will be overridden by request-level header
1565+
}), SetSniff(false), SetHealthcheck(false))
1566+
if err != nil {
1567+
t.Fatal(err)
1568+
}
1569+
res, err := client.PerformRequest(context.TODO(), PerformRequestOptions{
1570+
Method: "GET",
1571+
Path: "/",
1572+
Params: url.Values{
1573+
"pretty": []string{"true"},
1574+
},
1575+
Headers: http.Header{
1576+
"X-Opaque-Id": []string{"123456"}, // <- request-level has preference
1577+
"X-Somewhat": []string{"somewhat"},
1578+
},
1579+
})
1580+
if err != nil {
1581+
t.Fatal(err)
1582+
}
1583+
if res == nil {
1584+
t.Fatal("expected response to be != nil")
1585+
}
1586+
if req == nil {
1587+
t.Fatal("expected to record HTTP request")
1588+
}
1589+
if want, have := "123456", req.Header.Get("X-Opaque-Id"); want != have {
1590+
t.Fatalf("want HTTP header X-Opaque-Id=%q, have %q", want, have)
1591+
}
1592+
if want, have := "olivere", req.Header.Get("Custom-Id"); want != have {
1593+
t.Fatalf("want HTTP header Custom-Id=%q, have %q", want, have)
1594+
}
1595+
if want, have := "somewhat", req.Header.Get("X-Somewhat"); want != have {
1596+
t.Fatalf("want HTTP header X-Somewhat=%q, have %q", want, have)
1597+
}
1598+
}
1599+
15211600
// -- Compression --
15221601

15231602
// Notice that the trace log does always print "Accept-Encoding: gzip"

cluster_health.go

+21-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package elastic
77
import (
88
"context"
99
"fmt"
10+
"net/http"
1011
"net/url"
1112
"strings"
1213

@@ -29,6 +30,7 @@ type ClusterHealthService struct {
2930
waitForNodes string
3031
waitForNoRelocatingShards *bool
3132
waitForStatus string
33+
headers http.Header
3234
}
3335

3436
// NewClusterHealthService creates a new ClusterHealthService.
@@ -112,6 +114,21 @@ func (s *ClusterHealthService) Pretty(pretty bool) *ClusterHealthService {
112114
return s
113115
}
114116

117+
// Header adds a header to the request.
118+
func (s *ClusterHealthService) Header(name string, value string) *ClusterHealthService {
119+
if s.headers == nil {
120+
s.headers = http.Header{}
121+
}
122+
s.headers.Add(name, value)
123+
return s
124+
}
125+
126+
// Headers specifies the headers of the request.
127+
func (s *ClusterHealthService) Headers(headers http.Header) *ClusterHealthService {
128+
s.headers = headers
129+
return s
130+
}
131+
115132
// buildURL builds the URL for the operation.
116133
func (s *ClusterHealthService) buildURL() (string, url.Values, error) {
117134
// Build URL
@@ -180,9 +197,10 @@ func (s *ClusterHealthService) Do(ctx context.Context) (*ClusterHealthResponse,
180197

181198
// Get HTTP response
182199
res, err := s.client.PerformRequest(ctx, PerformRequestOptions{
183-
Method: "GET",
184-
Path: path,
185-
Params: params,
200+
Method: "GET",
201+
Path: path,
202+
Params: params,
203+
Headers: s.headers,
186204
})
187205
if err != nil {
188206
return nil, err

0 commit comments

Comments
 (0)