diff --git a/internal/core/local_runtime/setup_python_environment.go b/internal/core/local_runtime/setup_python_environment.go index 50324c491..05164f0c4 100644 --- a/internal/core/local_runtime/setup_python_environment.go +++ b/internal/core/local_runtime/setup_python_environment.go @@ -197,15 +197,7 @@ func (p *LocalPluginRuntime) installDependencies( parent.SetAttributes(attribute.String("uv.path", uvPath), attribute.StringSlice("uv.args", args)) cmd.Env = append(cmd.Env, "VIRTUAL_ENV="+virtualEnvPath, "PATH="+os.Getenv("PATH")) cmd.Env = append(cmd.Env, "UV_CACHE_DIR="+uvCacheDir) - if p.appConfig.HttpProxy != "" { - cmd.Env = append(cmd.Env, fmt.Sprintf("HTTP_PROXY=%s", p.appConfig.HttpProxy)) - } - if p.appConfig.HttpsProxy != "" { - cmd.Env = append(cmd.Env, fmt.Sprintf("HTTPS_PROXY=%s", p.appConfig.HttpsProxy)) - } - if p.appConfig.NoProxy != "" { - cmd.Env = append(cmd.Env, fmt.Sprintf("NO_PROXY=%s", p.appConfig.NoProxy)) - } + cmd.Env = append(cmd.Env, p.appConfig.ProxyEnv()...) cmd.Dir = p.State.WorkingPath // get stdout and stderr diff --git a/internal/core/local_runtime/subprocess.go b/internal/core/local_runtime/subprocess.go index 37d9855ab..3f5e0d40b 100644 --- a/internal/core/local_runtime/subprocess.go +++ b/internal/core/local_runtime/subprocess.go @@ -33,15 +33,7 @@ func (r *LocalPluginRuntime) getInstanceCmd() (*exec.Cmd, error) { } cmd.Env = cmd.Environ() - if r.appConfig.HttpsProxy != "" { - cmd.Env = append(cmd.Env, fmt.Sprintf("HTTPS_PROXY=%s", r.appConfig.HttpsProxy)) - } - if r.appConfig.HttpProxy != "" { - cmd.Env = append(cmd.Env, fmt.Sprintf("HTTP_PROXY=%s", r.appConfig.HttpProxy)) - } - if r.appConfig.NoProxy != "" { - cmd.Env = append(cmd.Env, fmt.Sprintf("NO_PROXY=%s", r.appConfig.NoProxy)) - } + cmd.Env = append(cmd.Env, r.appConfig.ProxyEnv()...) cmd.Env = append(cmd.Env, "INSTALL_METHOD=local", "PATH="+os.Getenv("PATH")) cmd.Dir = r.State.WorkingPath return cmd, nil diff --git a/internal/types/app/config_test.go b/internal/types/app/config_test.go index b2592ffe8..d7790927b 100644 --- a/internal/types/app/config_test.go +++ b/internal/types/app/config_test.go @@ -4,6 +4,7 @@ import ( "crypto/tls" "os" "path/filepath" + "runtime" "testing" "github.com/kelseyhightower/envconfig" @@ -86,6 +87,61 @@ func TestConfigRedisKeyPrefixField(t *testing.T) { assert.Equal(t, "enterprise-a", cfg.RedisKeyPrefix) } +func TestConfigProxyLowercaseFallbacks(t *testing.T) { + t.Setenv("HTTP_PROXY", "") + t.Setenv("HTTPS_PROXY", "") + t.Setenv("NO_PROXY", "") + t.Setenv("http_proxy", "http://lowercase-http:8080") + t.Setenv("https_proxy", "http://lowercase-https:8443") + t.Setenv("no_proxy", "localhost,127.0.0.1") + + cfg := Config{} + require.NoError(t, envconfig.Process("", &cfg)) + cfg.SetDefault() + + assert.Equal(t, "http://lowercase-http:8080", cfg.HttpProxy) + assert.Equal(t, "http://lowercase-https:8443", cfg.HttpsProxy) + assert.Equal(t, "localhost,127.0.0.1", cfg.NoProxy) +} + +func TestConfigProxyUppercaseTakesPrecedence(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Windows environment variables are case-insensitive") + } + + t.Setenv("HTTP_PROXY", "http://uppercase-http:8080") + t.Setenv("http_proxy", "http://lowercase-http:8080") + t.Setenv("HTTPS_PROXY", "http://uppercase-https:8443") + t.Setenv("https_proxy", "http://lowercase-https:8443") + t.Setenv("NO_PROXY", "internal") + t.Setenv("no_proxy", "localhost") + + cfg := Config{} + require.NoError(t, envconfig.Process("", &cfg)) + cfg.SetDefault() + + assert.Equal(t, "http://uppercase-http:8080", cfg.HttpProxy) + assert.Equal(t, "http://uppercase-https:8443", cfg.HttpsProxy) + assert.Equal(t, "internal", cfg.NoProxy) +} + +func TestConfigProxyEnvIncludesUppercaseAndLowercase(t *testing.T) { + cfg := Config{ + HttpProxy: "http://proxy-http:8080", + HttpsProxy: "http://proxy-https:8443", + NoProxy: "localhost", + } + + assert.ElementsMatch(t, []string{ + "HTTP_PROXY=http://proxy-http:8080", + "http_proxy=http://proxy-http:8080", + "HTTPS_PROXY=http://proxy-https:8443", + "https_proxy=http://proxy-https:8443", + "NO_PROXY=localhost", + "no_proxy=localhost", + }, cfg.ProxyEnv()) +} + func TestRedisTLSConfig(t *testing.T) { tests := []struct { name string diff --git a/internal/types/app/default.go b/internal/types/app/default.go index eedaaa0c3..53d63618c 100644 --- a/internal/types/app/default.go +++ b/internal/types/app/default.go @@ -6,6 +6,7 @@ import ( ) func (config *Config) SetDefault() { + config.SetProxyEnvFallbacks() switch config.DBType { case DB_TYPE_OCEANBASE, DB_TYPE_SEEKDB: config.DBType = DB_TYPE_MYSQL diff --git a/internal/types/app/proxy.go b/internal/types/app/proxy.go new file mode 100644 index 000000000..5d707dc31 --- /dev/null +++ b/internal/types/app/proxy.go @@ -0,0 +1,49 @@ +package app + +import ( + "fmt" + "os" +) + +func (config *Config) SetProxyEnvFallbacks() { + if config == nil { + return + } + + if config.HttpProxy == "" { + config.HttpProxy = os.Getenv("http_proxy") + } + if config.HttpsProxy == "" { + config.HttpsProxy = os.Getenv("https_proxy") + } + if config.NoProxy == "" { + config.NoProxy = os.Getenv("no_proxy") + } +} + +func (config *Config) ProxyEnv() []string { + if config == nil { + return nil + } + + env := []string{} + if config.HttpProxy != "" { + env = append(env, + fmt.Sprintf("HTTP_PROXY=%s", config.HttpProxy), + fmt.Sprintf("http_proxy=%s", config.HttpProxy), + ) + } + if config.HttpsProxy != "" { + env = append(env, + fmt.Sprintf("HTTPS_PROXY=%s", config.HttpsProxy), + fmt.Sprintf("https_proxy=%s", config.HttpsProxy), + ) + } + if config.NoProxy != "" { + env = append(env, + fmt.Sprintf("NO_PROXY=%s", config.NoProxy), + fmt.Sprintf("no_proxy=%s", config.NoProxy), + ) + } + return env +}