Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions env/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,3 +278,65 @@ func TestLookupEnvReferenceScheme(t *testing.T) {
})
}
}

func TestLookupEnvRejectsErrorStatus(t *testing.T) {
var status atomic.Int32
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
code := int(status.Load())
w.WriteHeader(code)
if code >= 200 && code <= 299 {
w.Write([]byte("fetched-value"))
return
}
w.Write([]byte(http.StatusText(code)))
}))
t.Cleanup(ts.Close)
const key = "_TEST_ENV_STATUS"
t.Setenv(key, "env://minio:minio123@"+strings.TrimPrefix(ts.URL, "http://"))

for _, code := range []int{http.StatusOK, http.StatusCreated, 299} {
t.Setenv("_"+key, "")
os.Unsetenv("_" + key)
status.Store(int32(code))
if v, _, _, err := LookupEnv(key); err != nil || v != "fetched-value" {
t.Errorf("HTTP %d: LookupEnv = %q, %v; want fetched-value", code, v, err)
}
if c := os.Getenv("_" + key); c != "fetched-value" {
t.Errorf("HTTP %d: cache = %q, want fetched-value", code, c)
}
}

for _, code := range []int{
http.StatusMultipleChoices,
http.StatusUnauthorized,
http.StatusForbidden,
http.StatusNotFound,
http.StatusInternalServerError,
http.StatusServiceUnavailable,
} {
t.Setenv("_"+key, "")
os.Unsetenv("_" + key)
status.Store(int32(code))
v, _, _, err := LookupEnv(key)
if err == nil || v != "" {
t.Errorf("HTTP %d: LookupEnv = %q, %v; want an error", code, v, err)
}
if c, ok := os.LookupEnv("_" + key); ok {
t.Errorf("HTTP %d: cached %q, want no cache", code, c)
}
}

t.Setenv("_"+key, "")
os.Unsetenv("_" + key)
status.Store(http.StatusOK)
if v, _, _, err := LookupEnv(key); err != nil || v != "fetched-value" {
t.Fatalf("HTTP 200: LookupEnv = %q, %v; want fetched-value", v, err)
}
status.Store(http.StatusServiceUnavailable)
if v, _, _, err := LookupEnv(key); err != nil || v != "fetched-value" {
t.Errorf("HTTP 503 after a fetch: LookupEnv = %q, %v; want the cached fetched-value", v, err)
}
if c := os.Getenv("_" + key); c != "fetched-value" {
t.Errorf("HTTP 503 after a fetch: cache = %q, want fetched-value", c)
}
}
6 changes: 6 additions & 0 deletions env/web_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ func getEnvValueFromHTTP(urlStr, envKey string) (string, string, string, error)
}
defer resp.Body.Close()

// The body of an error response is not the value: returning it would
// also replace the cached value that LookupEnv falls back to.
if resp.StatusCode < 200 || resp.StatusCode > 299 {
return "", "", "", fmt.Errorf("env webhook returned %s", resp.Status)
}

envValueBytes, err := io.ReadAll(resp.Body)
if err != nil {
return "", "", "", err
Expand Down
Loading