playground: allow explicit GOPROXY variable Setting the PLAY_GOPROXY variable of the playground modifies where the playground fetches module information from. This allows users to install the playground inside their company VPN and use private modules. The variable isn't named "GOPROXY" to not confuse which context the URL is used for. The name PLAY_* is adopted from the existing env variable ALLOW_PLAY_MODULE_DOWNLOADS. Fixes golang/go#32740 Change-Id: Idcd0530c1c28342414e0bc5439fca6a2272e1eaa Reviewed-on: https://go-review.googlesource.com/c/playground/+/184558 Reviewed-by: Andrew Bonventre <andybons@golang.org>
diff --git a/sandbox.go b/sandbox.go index c4a865d..2050832 100644 --- a/sandbox.go +++ b/sandbox.go
@@ -370,7 +370,7 @@ return nil, fmt.Errorf("error creating temp directory: %v", err) } defer os.RemoveAll(goPath) - cmd.Env = append(cmd.Env, "GO111MODULE=on", "GOPROXY=https://proxy.golang.org") + cmd.Env = append(cmd.Env, "GO111MODULE=on", "GOPROXY="+playgroundGoproxy()) } else { goPath = os.Getenv("GOPATH") // contains old code.google.com/p/go-tour, etc cmd.Env = append(cmd.Env, "GO111MODULE=off") // in case it becomes on by default later @@ -451,13 +451,24 @@ // these packages to still run, so the Dockerfile adds these packages // at this name in $GOPATH. Any snippets using this old name wouldn't // have expected (or been able to use) third-party packages anyway, - // so disabling modules and proxy.golang.org fetches is acceptable. + // so disabling modules and proxy fetches is acceptable. return false } v, _ := strconv.ParseBool(os.Getenv("ALLOW_PLAY_MODULE_DOWNLOADS")) return v } +// playgroundGoproxy returns the GOPROXY environment config the playground should use. +// It is fetched from the environment variable PLAY_GOPROXY. A missing or empty +// value for PLAY_GOPROXY returns the default value of https://proxy.golang.org. +func playgroundGoproxy() string { + proxypath := os.Getenv("PLAY_GOPROXY") + if proxypath != "" { + return proxypath + } + return "https://proxy.golang.org" +} + func (s *server) healthCheck() error { resp, err := compileAndRun(&request{Body: healthProg}) if err != nil {
diff --git a/server_test.go b/server_test.go index 9cc19da..773a093 100644 --- a/server_test.go +++ b/server_test.go
@@ -272,5 +272,36 @@ t.Errorf("%d. allow = %v; want %v; files:\n%s", i, got, tt.want, filesAsString(files)) } } +} +func TestPlaygroundGoproxy(t *testing.T) { + const envKey = "PLAY_GOPROXY" + defer os.Setenv(envKey, os.Getenv(envKey)) + + tests := []struct { + name string + env string + want string + }{ + {name: "missing", env: "", want: "https://proxy.golang.org"}, + {name: "set_to_default", env: "https://proxy.golang.org", want: "https://proxy.golang.org"}, + {name: "changed", env: "https://company.intranet", want: "https://company.intranet"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.env != "" { + if err := os.Setenv(envKey, tt.env); err != nil { + t.Errorf("unable to set environment variable for test: %s", err) + } + } else { + if err := os.Unsetenv(envKey); err != nil { + t.Errorf("unable to unset environment variable for test: %s", err) + } + } + got := playgroundGoproxy() + if got != tt.want { + t.Errorf("playgroundGoproxy = %s; want %s; env: %s", got, tt.want, tt.env) + } + }) + } }
diff --git a/vet.go b/vet.go index 32edeca..a9cae12 100644 --- a/vet.go +++ b/vet.go
@@ -60,7 +60,7 @@ if modules { cmd.Env = append(cmd.Env, "GO111MODULE=on", - "GOPROXY=https://proxy.golang.org", + "GOPROXY="+playgroundGoproxy(), ) } out, err := cmd.CombinedOutput()