From 67fe33aa62ec275c6b3c92fbb900fd62baf4cbd1 Mon Sep 17 00:00:00 2001 From: Andres Martinez Gotor Date: Wed, 17 Jan 2024 13:38:45 +0100 Subject: [PATCH] Datasources: Ensure the 'Host' custom header functions as expected (#80715) Supports "Host" custom header. Co-authored-by: Pei-Tang Huang --- .../datasources/service/datasource_test.go | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/pkg/services/datasources/service/datasource_test.go b/pkg/services/datasources/service/datasource_test.go index 86c6632ab46..f041ea09204 100644 --- a/pkg/services/datasources/service/datasource_test.go +++ b/pkg/services/datasources/service/datasource_test.go @@ -865,6 +865,75 @@ func TestService_GetHttpTransport(t *testing.T) { require.Equal(t, "Ok", bodyStr) }) + t.Run("Should set request Host if it is configured in custom headers within JsonData", func(t *testing.T) { + provider := httpclient.NewProvider() + + sjson := simplejson.NewFromAny(map[string]any{ + "httpHeaderName1": "Host", + }) + + sqlStore := db.InitTestDB(t) + secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore()) + secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger")) + quotaService := quotatest.New(false, nil) + dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{}) + require.NoError(t, err) + + ds := datasources.DataSource{ + ID: 1, + OrgID: 1, + Name: "kubernetes", + URL: "http://k8s:8001", + Type: "Kubernetes", + JsonData: sjson, + } + + secureJsonData, err := json.Marshal(map[string]string{ + "httpHeaderValue1": "example.com", + }) + require.NoError(t, err) + + err = secretsStore.Set(context.Background(), ds.OrgID, ds.Name, secretskvs.DataSourceSecretType, string(secureJsonData)) + require.NoError(t, err) + + headers := dsService.getCustomHeaders(sjson, map[string]string{"httpHeaderValue1": "example.com"}) + require.Equal(t, "example.com", headers["Host"]) + + // 1. Start HTTP test server which checks the request headers + backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Host == "example.com" { + w.WriteHeader(200) + _, err := w.Write([]byte("Ok")) + require.NoError(t, err) + return + } + + w.WriteHeader(503) + _, err := w.Write([]byte("Server name mismatch")) + require.NoError(t, err) + })) + defer backend.Close() + + // 2. Get HTTP transport from datasource which uses the test server as backend + ds.URL = backend.URL + rt, err := dsService.GetHTTPTransport(context.Background(), &ds, provider) + require.NoError(t, err) + require.NotNil(t, rt) + + // 3. Send test request which should have the Authorization header set + req := httptest.NewRequest("GET", backend.URL+"/test-host", nil) + res, err := rt.RoundTrip(req) + require.NoError(t, err) + t.Cleanup(func() { + err := res.Body.Close() + require.NoError(t, err) + }) + body, err := io.ReadAll(res.Body) + require.NoError(t, err) + bodyStr := string(body) + require.Equal(t, "Ok", bodyStr) + }) + t.Run("Should use request timeout if configured in JsonData", func(t *testing.T) { provider := httpclient.NewProvider()