From 5a5c7f0e47c3bca17878bfa95bb945e36a17f98f Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 23 Nov 2022 14:58:13 +0100 Subject: [PATCH] Fix missing host header in http check (#15337) --- .changelog/15337.txt | 3 ++ client/serviceregistration/checks/client.go | 9 ++++- .../serviceregistration/checks/client_test.go | 39 ++++++++++++++++++- 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 .changelog/15337.txt diff --git a/.changelog/15337.txt b/.changelog/15337.txt new file mode 100644 index 000000000000..00396db20546 --- /dev/null +++ b/.changelog/15337.txt @@ -0,0 +1,3 @@ +```release-note:bug +check: Add support for sending custom host header +``` diff --git a/client/serviceregistration/checks/client.go b/client/serviceregistration/checks/client.go index 9fb0b484d27b..c0ddc79a126b 100644 --- a/client/serviceregistration/checks/client.go +++ b/client/serviceregistration/checks/client.go @@ -163,7 +163,14 @@ func (c *checker) checkHTTP(ctx context.Context, qc *QueryContext, q *Query) *st qr.Status = structs.CheckFailure return qr } - request.Header = q.Headers + for header, values := range q.Headers { + for _, value := range values { + request.Header.Add(header, value) + } + } + + request.Host = request.Header.Get("Host") + request.Body = io.NopCloser(strings.NewReader(q.Body)) request = request.WithContext(ctx) diff --git a/client/serviceregistration/checks/client_test.go b/client/serviceregistration/checks/client_test.go index 7b7b76e68957..c64f809f8b04 100644 --- a/client/serviceregistration/checks/client_test.go +++ b/client/serviceregistration/checks/client_test.go @@ -215,12 +215,14 @@ func TestChecker_Do_HTTP_extras(t *testing.T) { method string body []byte headers map[string][]string + host string ) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { method = r.Method body, _ = io.ReadAll(r.Body) headers = maps.Clone(r.Header) + host = r.Host w.WriteHeader(http.StatusOK) })) defer ts.Close() @@ -244,7 +246,7 @@ func TestChecker_Do_HTTP_extras(t *testing.T) { name string method string body string - headers map[string][]string + headers http.Header }{ { name: "method GET", @@ -269,6 +271,25 @@ func TestChecker_Do_HTTP_extras(t *testing.T) { [2]string{"Authorization", "Basic ZWxhc3RpYzpjaGFuZ2VtZQ=="}, ), }, + { + name: "host header", + method: "GET", + headers: makeHeaders(encoding, agent, + [2]string{"Host", "hello"}, + [2]string{"Test-Abc", "hello"}, + ), + }, + { + name: "host header without normalization", + method: "GET", + body: "", + // This is needed to prevent header normalization by http.Header.Set + headers: func() map[string][]string { + h := makeHeaders(encoding, agent, [2]string{"Test-Abc", "hello"}) + h["hoST"] = []string{"heLLO"} + return h + }(), + }, { name: "with body", method: "POST", @@ -312,9 +333,25 @@ func TestChecker_Do_HTTP_extras(t *testing.T) { must.Eq(t, http.StatusOK, result.StatusCode, must.Sprintf("test.URL: %s", ts.URL), must.Sprintf("headers: %v", tc.headers), + must.Sprintf("received headers: %v", tc.headers), ) must.Eq(t, tc.method, method) must.Eq(t, tc.body, string(body)) + + hostSent := false + + for key, values := range tc.headers { + if strings.EqualFold(key, "Host") && len(values) > 0 { + must.Eq(t, values[0], host) + hostSent = true + delete(tc.headers, key) + + } + } + if !hostSent { + must.Eq(t, nil, tc.headers["Host"]) + } + must.Eq(t, tc.headers, headers) }) }