From a7b791d0a0cd8e7be164d7f3fdb33450c1868b1c Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Wed, 17 Jun 2026 09:39:53 +0200 Subject: [PATCH] config: resolve LoadHTTPConfigFile paths relative to the config file LoadHTTPConfigFile called SetDirectory with filepath.Dir(filepath.Dir(filename)), resolving relative file paths (http_headers files, *_file credentials) against the config file's grandparent directory instead of its own directory. This contradicts the SetDirectory contract and every other config loader. The behavior was masked by the testdata fixtures, which prefixed file paths with the config file's own directory name (e.g. files: [testdata/headers-file] for a config living in testdata/) to compensate. Drop those redundant prefixes and add a regression test that loads a config from a temp dir and asserts a plain relative path resolves next to the config file. Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- config/http_config.go | 2 +- config/http_config_test.go | 29 +++++++++++++++++++ .../http.conf.basic-auth.bad-username.yaml | 2 +- .../testdata/http.conf.basic-auth.good.yaml | 2 +- .../http.conf.basic-auth.too-much.bad.yaml | 2 +- ...tp.conf.basic-auth.username-file.good.yaml | 4 +-- .../http.conf.headers-multiple.good.yaml | 2 +- config/testdata/http.conf.headers.good.yaml | 2 +- 8 files changed, 37 insertions(+), 8 deletions(-) diff --git a/config/http_config.go b/config/http_config.go index 689ea627c..88457375f 100644 --- a/config/http_config.go +++ b/config/http_config.go @@ -325,7 +325,7 @@ func LoadHTTPConfigFile(filename string) (*HTTPClientConfig, []byte, error) { if err != nil { return nil, nil, err } - cfg.SetDirectory(filepath.Dir(filepath.Dir(filename))) + cfg.SetDirectory(filepath.Dir(filename)) return cfg, content, nil } diff --git a/config/http_config_test.go b/config/http_config_test.go index 708e993b3..4d61ae12f 100644 --- a/config/http_config_test.go +++ b/config/http_config_test.go @@ -2720,3 +2720,32 @@ func TestMultipleHeaders(t *testing.T) { _, err = client.Get(ts.URL) require.NoErrorf(t, err, "can't fetch URL: %v", err) } + +// TestLoadHTTPConfigFileResolvesPathsRelativeToConfigFile ensures that relative +// file paths inside a config loaded with LoadHTTPConfigFile are resolved +// relative to the directory containing the config file, as documented by the +// SetDirectory contract. +func TestLoadHTTPConfigFileResolvesPathsRelativeToConfigFile(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "header-value", r.Header.Get("X-Test")) + w.WriteHeader(http.StatusNoContent) + })) + t.Cleanup(ts.Close) + + dir := t.TempDir() + require.NoError(t, os.WriteFile(filepath.Join(dir, "header-value"), []byte("header-value\n"), 0o644)) + require.NoError(t, os.WriteFile(filepath.Join(dir, "http.yml"), []byte(`http_headers: + X-Test: + files: [header-value] +`), 0o644)) + + cfg, _, err := LoadHTTPConfigFile(filepath.Join(dir, "http.yml")) + require.NoErrorf(t, err, "Error loading HTTP client config: %v", err) + require.Equal(t, filepath.Join(dir, "header-value"), cfg.HTTPHeaders.Headers["X-Test"].Files[0]) + + client, err := NewClientFromConfig(*cfg, "test") + require.NoErrorf(t, err, "Error creating HTTP Client: %v", err) + + _, err = client.Get(ts.URL) + require.NoErrorf(t, err, "can't fetch URL: %v", err) +} diff --git a/config/testdata/http.conf.basic-auth.bad-username.yaml b/config/testdata/http.conf.basic-auth.bad-username.yaml index bfb911b84..7b2f74ea0 100644 --- a/config/testdata/http.conf.basic-auth.bad-username.yaml +++ b/config/testdata/http.conf.basic-auth.bad-username.yaml @@ -1,4 +1,4 @@ basic_auth: username: user - username_file: testdata/basic-auth-username + username_file: basic-auth-username password: foo \ No newline at end of file diff --git a/config/testdata/http.conf.basic-auth.good.yaml b/config/testdata/http.conf.basic-auth.good.yaml index 5e7aa41f5..8b96a4136 100644 --- a/config/testdata/http.conf.basic-auth.good.yaml +++ b/config/testdata/http.conf.basic-auth.good.yaml @@ -1,3 +1,3 @@ basic_auth: username: user - password_file: testdata/basic-auth-password + password_file: basic-auth-password diff --git a/config/testdata/http.conf.basic-auth.too-much.bad.yaml b/config/testdata/http.conf.basic-auth.too-much.bad.yaml index 7cfb92200..f282bf7ca 100644 --- a/config/testdata/http.conf.basic-auth.too-much.bad.yaml +++ b/config/testdata/http.conf.basic-auth.too-much.bad.yaml @@ -1,4 +1,4 @@ basic_auth: username: user password: foo - password_file: testdata/basic-auth-password + password_file: basic-auth-password diff --git a/config/testdata/http.conf.basic-auth.username-file.good.yaml b/config/testdata/http.conf.basic-auth.username-file.good.yaml index 24c3c3cb8..102dbe77c 100644 --- a/config/testdata/http.conf.basic-auth.username-file.good.yaml +++ b/config/testdata/http.conf.basic-auth.username-file.good.yaml @@ -1,3 +1,3 @@ basic_auth: - username_file: testdata/basic-auth-username - password_file: testdata/basic-auth-password \ No newline at end of file + username_file: basic-auth-username + password_file: basic-auth-password \ No newline at end of file diff --git a/config/testdata/http.conf.headers-multiple.good.yaml b/config/testdata/http.conf.headers-multiple.good.yaml index f9dcdc050..b8e6d7e02 100644 --- a/config/testdata/http.conf.headers-multiple.good.yaml +++ b/config/testdata/http.conf.headers-multiple.good.yaml @@ -5,4 +5,4 @@ http_headers: values: [value2a] secrets: [value2b, value2c] three: - files: [testdata/headers-file-a, testdata/headers-file-b, testdata/headers-file-c] + files: [headers-file-a, headers-file-b, headers-file-c] diff --git a/config/testdata/http.conf.headers.good.yaml b/config/testdata/http.conf.headers.good.yaml index f8a023643..5b46cf7fa 100644 --- a/config/testdata/http.conf.headers.good.yaml +++ b/config/testdata/http.conf.headers.good.yaml @@ -4,4 +4,4 @@ http_headers: two: secrets: [value2] three: - files: [testdata/headers-file] + files: [headers-file]