internal/env: use golangorgenv package from x/tools

This change de-duplicates the same configuration used between
the previous x/tools/godoc/env package and x/website's own
internal/env package. It does so by using the new golangorgenv
package.

This makes it possible to remove the old GODOC_PROD and
GODOC_ENFORCE_HOSTS env vars from app.prod.yaml.

The IsProd configuration value was very generic and yet being
used only in one place. Replace it with a more targeted one.
The new name does a better job of communicating what the
implications of setting or not setting it are.

Apply the same change to logic of googleCN as in CL 165459.

Update the required version of the x/tools module to a newer version
that includes CL 160837, which is required for this change.

Starting with this change, we're changing the x/website policy in that
it's now allowed to start using newer versions of subrepos from the
master branch, rather than only using the release-branches of subrepos.
This is in line with the goal of making x/website more self-contained
and less constrained by the Go release schedule.

Updates golang/go#29206

Change-Id: If8847e9276fb18e3ded56fabbf915cdd19176699
Reviewed-on: https://go-review.googlesource.com/c/website/+/165837
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/cmd/golangorg/app.prod.yaml b/cmd/golangorg/app.prod.yaml
index 9716567..732d4b2 100644
--- a/cmd/golangorg/app.prod.yaml
+++ b/cmd/golangorg/app.prod.yaml
@@ -3,10 +3,9 @@
 env: flex
 
 env_variables:
-  GOLANGORG_PROD: true
+  GOLANGORG_CHECK_COUNTRY: true
+  GOLANGORG_REQUIRE_DL_SECRET_KEY: true
   GOLANGORG_ENFORCE_HOSTS: true
-  GODOC_PROD: true                    # TODO: remove in the future
-  GODOC_ENFORCE_HOSTS: true           # TODO: remove in the future
   GOLANGORG_REDIS_ADDR: 10.0.0.4:6379 # instance "gophercache"
   GOLANGORG_ANALYTICS: UA-11222381-2
   DATASTORE_PROJECT_ID: golang-org
diff --git a/go.mod b/go.mod
index 7bac778..62d4bb6 100644
--- a/go.mod
+++ b/go.mod
@@ -6,11 +6,11 @@
 	github.com/googleapis/gax-go v2.0.0+incompatible // indirect
 	go.opencensus.io v0.19.0 // indirect
 	golang.org/x/crypto v0.0.0-20181025213731-e84da0312774
-	golang.org/x/net v0.0.0-20190206173232-65e2d4e15006
+	golang.org/x/net v0.0.0-20190213061140-3a22650c66bd
 	golang.org/x/oauth2 v0.0.0-20190115181402-5dab4167f31c // indirect
 	golang.org/x/sys v0.0.0-20190209173611-3b5209105503 // indirect
 	golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db // indirect
-	golang.org/x/tools v0.0.0-20190219175448-49d818b07734
+	golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3
 	google.golang.org/api v0.1.0 // indirect
 	google.golang.org/appengine v1.4.0
 	google.golang.org/genproto v0.0.0-20190123001331-8819c946db44 // indirect
diff --git a/go.sum b/go.sum
index 5a2300a..f5ca2a3 100644
--- a/go.sum
+++ b/go.sum
@@ -51,8 +51,8 @@
 golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20181217023233-e147a9138326/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190206173232-65e2d4e15006 h1:bfLnR+k0tq5Lqt6dflRLcZiz6UaXCMt3vhYJ1l4FQ80=
-golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd h1:HuTn7WObtcDo9uEEU7rEqL0jYthdXAmZ6PP+meazmaU=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890 h1:uESlIz09WIHT2I+pasSXcpLYqYK8wHcdCetU3VuMBJE=
 golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -73,8 +73,8 @@
 golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190219175448-49d818b07734 h1:bNQjVDSQE5kjDZie/YsDogCCryxCd9ZJ+EC++Erg5SY=
-golang.org/x/tools v0.0.0-20190219175448-49d818b07734/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3 h1:2oZsfYnKfYzL4I57uYiRFsUf0bqlLkiuw8nnj3+voUA=
+golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4=
 google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
 google.golang.org/api v0.0.0-20181220000619-583d854617af/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
 google.golang.org/api v0.1.0 h1:K6z2u68e86TPdSdefXdzvXgR1zEMa+459vBSfWYAZkI=
diff --git a/internal/dl/server.go b/internal/dl/server.go
index 4501491..342863f 100644
--- a/internal/dl/server.go
+++ b/internal/dl/server.go
@@ -252,7 +252,7 @@
 			// The code is left here for SDK use and in case a fresh
 			// deployment is ever needed.  "gophers rule" is not the
 			// real key.
-			if env.IsProd() {
+			if env.RequireDLSecretKey() {
 				panic("lost key from datastore")
 			}
 			theKey.Secret = "gophers rule"
diff --git a/internal/env/env.go b/internal/env/env.go
index 1803f6c..8fcf5a9 100644
--- a/internal/env/env.go
+++ b/internal/env/env.go
@@ -2,35 +2,54 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package env provides environment information for the godoc server running on
-// golang.org.
+// Package env provides environment information for the golangorg server
+// running on golang.org.
 package env
 
 import (
 	"log"
 	"os"
 	"strconv"
+
+	"golang.org/x/tools/godoc/golangorgenv"
 )
 
 var (
-	isProd       = boolEnv("GOLANGORG_PROD")
-	enforceHosts = boolEnv("GOLANGORG_ENFORCE_HOSTS")
+	requireDLSecretKey = boolEnv("GOLANGORG_REQUIRE_DL_SECRET_KEY")
 )
 
-// IsProd reports whether the server is running in its production configuration
-// on golang.org.
-func IsProd() bool {
-	return isProd
+// RequireDLSecretKey reports whether the download server secret key
+// is expected to already exist, and the download server should panic
+// on missing key instead of creating a new one.
+func RequireDLSecretKey() bool {
+	return requireDLSecretKey
+}
+
+// Use the golangorgenv package for common configuration, instead
+// of duplicating it. This reduces the risk of divergence between
+// the environment variables that this env package uses, and ones
+// that golangorgenv uses.
+//
+// TODO(dmitshur): When the golang.org/x/tools/playground package becomes unused,
+// and golang.org/x/tools/godoc is modified to accept configuration explicitly,
+// the golang.org/x/tools/godoc/golangorgenv package can be deleted.
+// At that time, its implementation can be inlined into this package, as needed.
+
+// CheckCountry reports whether country restrictions should be enforced.
+func CheckCountry() bool {
+	return golangorgenv.CheckCountry()
 }
 
 // EnforceHosts reports whether host filtering should be enforced.
 func EnforceHosts() bool {
-	return enforceHosts
+	return golangorgenv.EnforceHosts()
 }
 
 func boolEnv(key string) bool {
 	v := os.Getenv(key)
 	if v == "" {
+		// TODO(dmitshur): In the future, consider detecting if running in App Engine,
+		// and if so, making the environment variables mandatory rather than optional.
 		return false
 	}
 	b, err := strconv.ParseBool(v)
diff --git a/internal/proxy/proxy.go b/internal/proxy/proxy.go
index e465aab..cc740d6 100644
--- a/internal/proxy/proxy.go
+++ b/internal/proxy/proxy.go
@@ -152,17 +152,19 @@
 	io.Copy(w, resp.Body)
 }
 
+// googleCN reports whether request r is considered
+// to be served from golang.google.cn.
 func googleCN(r *http.Request) bool {
 	if r.FormValue("googlecn") != "" {
 		return true
 	}
-	if !env.IsProd() {
-		return false
-	}
 	if strings.HasSuffix(r.Host, ".cn") {
 		return true
 	}
-	switch r.Header.Get("X-AppEngine-Country") {
+	if !env.CheckCountry() {
+		return false
+	}
+	switch r.Header.Get("X-Appengine-Country") {
 	case "", "ZZ", "CN":
 		return true
 	}