godoc: add GoogleCN property to pages

Use that property to determine whether to show share functionality
or link to sites that are blocked in mainland China.

This change requires https://go-review.googlesource.com/c/52872

Change-Id: I47327f9dbd2624206564fa99eb1cc6a10b4f46db
Reviewed-on: https://go-review.googlesource.com/52873
Reviewed-by: Chris Broadfoot <cbro@golang.org>
diff --git a/godoc/README.md b/godoc/README.md
index 1c495c8..52bc8a4 100644
--- a/godoc/README.md
+++ b/godoc/README.md
@@ -10,7 +10,7 @@
 flag to load CSS/JS/templates from disk every time a page loads:
 
 ```
-godoc --templates=$GOPATH/src/golang.org/x/tools/godoc/static --http=:6060
+godoc -templates=$GOPATH/src/golang.org/x/tools/godoc/static -http=:6060
 ```
 
 ## Recompiling static assets
diff --git a/godoc/godoc.go b/godoc/godoc.go
index a9e8b3b..5c6d982 100644
--- a/godoc/godoc.go
+++ b/godoc/godoc.go
@@ -421,9 +421,9 @@
 }
 
 type PageInfo struct {
-	Dirname string // directory containing the package
-	Err     error  // error or nil
-	Share   bool   // show share button on examples
+	Dirname  string // directory containing the package
+	Err      error  // error or nil
+	GoogleCN bool   // page is being served from golang.google.cn
 
 	Mode PageInfoMode // display metadata from query string
 
@@ -683,8 +683,8 @@
 
 		err := p.ExampleHTML.Execute(&buf, struct {
 			Name, Doc, Code, Play, Output string
-			Share                         bool
-		}{eg.Name, eg.Doc, code, play, out, info.Share})
+			GoogleCN                      bool
+		}{eg.Name, eg.Doc, code, play, out, info.GoogleCN})
 		if err != nil {
 			log.Print(err)
 		}
diff --git a/godoc/page.go b/godoc/page.go
index 0c7bf00..10e86e5 100644
--- a/godoc/page.go
+++ b/godoc/page.go
@@ -9,6 +9,7 @@
 	"os"
 	"path/filepath"
 	"runtime"
+	"strings"
 )
 
 // Page describes the contents of the top-level godoc webpage.
@@ -19,7 +20,7 @@
 	SrcPath  string
 	Query    string
 	Body     []byte
-	Share    bool
+	GoogleCN bool // page is being served from golang.google.cn
 
 	// filled in by servePage
 	SearchBox  bool
@@ -51,19 +52,25 @@
 		Title:    "File " + relpath,
 		Subtitle: relpath,
 		Body:     applyTemplate(p.ErrorHTML, "errorHTML", err),
-		Share:    allowShare(r),
+		GoogleCN: googleCN(r),
 	})
 }
 
-var onAppengine = false // overriden in appengine.go when on app engine
+var onAppengine = false // overridden in appengine.go when on app engine
 
-func allowShare(r *http.Request) bool {
+func googleCN(r *http.Request) bool {
+	if r.FormValue("googlecn") != "" {
+		return true
+	}
 	if !onAppengine {
+		return false
+	}
+	if strings.HasSuffix(r.Host, ".cn") {
 		return true
 	}
 	switch r.Header.Get("X-AppEngine-Country") {
 	case "", "ZZ", "CN":
-		return false
+		return true
 	}
-	return true
+	return false
 }
diff --git a/godoc/proxy/proxy.go b/godoc/proxy/proxy.go
index e8cb18e..0ddaa00 100644
--- a/godoc/proxy/proxy.go
+++ b/godoc/proxy/proxy.go
@@ -19,6 +19,7 @@
 	"net/http"
 	"net/http/httputil"
 	"net/url"
+	"strings"
 	"time"
 
 	"golang.org/x/net/context"
@@ -147,8 +148,8 @@
 }
 
 func share(w http.ResponseWriter, r *http.Request) {
-	if !allowShare(r) {
-		http.Error(w, "Forbidden", http.StatusForbidden)
+	if googleCN(r) {
+		http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
 		return
 	}
 	target, _ := url.Parse(playgroundURL)
@@ -157,13 +158,19 @@
 	p.ServeHTTP(w, r)
 }
 
-func allowShare(r *http.Request) bool {
+func googleCN(r *http.Request) bool {
+	if r.FormValue("googlecn") != "" {
+		return true
+	}
 	if appengine.IsDevAppServer() {
+		return false
+	}
+	if strings.HasSuffix(r.Host, ".cn") {
 		return true
 	}
 	switch r.Header.Get("X-AppEngine-Country") {
 	case "", "ZZ", "CN":
-		return false
+		return true
 	}
-	return true
+	return false
 }
diff --git a/godoc/search.go b/godoc/search.go
index 63d9e76..d61193f 100644
--- a/godoc/search.go
+++ b/godoc/search.go
@@ -126,7 +126,7 @@
 		Tabtitle: query,
 		Query:    query,
 		Body:     body.Bytes(),
-		Share:    allowShare(r),
+		GoogleCN: googleCN(r),
 	})
 }
 
diff --git a/godoc/server.go b/godoc/server.go
index c9b4056..3b452e5 100644
--- a/godoc/server.go
+++ b/godoc/server.go
@@ -312,13 +312,13 @@
 		info.TypeInfoIndex[ti.Name] = i
 	}
 
-	info.Share = allowShare(r)
+	info.GoogleCN = googleCN(r)
 	h.p.ServePage(w, Page{
 		Title:    title,
 		Tabtitle: tabtitle,
 		Subtitle: subtitle,
 		Body:     applyTemplate(h.p.PackageHTML, "packageHTML", info),
-		Share:    info.Share,
+		GoogleCN: info.GoogleCN,
 	})
 }
 
@@ -583,7 +583,7 @@
 		SrcPath:  relpath,
 		Tabtitle: relpath,
 		Body:     buf.Bytes(),
-		Share:    allowShare(r),
+		GoogleCN: googleCN(r),
 	})
 }
 
@@ -654,7 +654,7 @@
 		SrcPath:  relpath,
 		Tabtitle: relpath,
 		Body:     applyTemplate(p.DirlistHTML, "dirlistHTML", list),
-		Share:    allowShare(r),
+		GoogleCN: googleCN(r),
 	})
 }
 
@@ -683,7 +683,7 @@
 	page := Page{
 		Title:    meta.Title,
 		Subtitle: meta.Subtitle,
-		Share:    allowShare(r),
+		GoogleCN: googleCN(r),
 	}
 
 	// evaluate as template if indicated
diff --git a/godoc/static/example.html b/godoc/static/example.html
index 3bc0eb9..1e86b25 100644
--- a/godoc/static/example.html
+++ b/godoc/static/example.html
@@ -13,7 +13,7 @@
 				<div class="buttons">
 					<a class="run" title="Run this code [shift-enter]">Run</a>
 					<a class="fmt" title="Format this code">Format</a>
-					{{if $.Share}}
+					{{if not $.GoogleCN}}
 					<a class="share" title="Share this code">Share</a>
 					{{end}}
 				</div>
diff --git a/godoc/static/godoc.html b/godoc/static/godoc.html
index 92b10aa..b7f6c11 100644
--- a/godoc/static/godoc.html
+++ b/godoc/static/godoc.html
@@ -55,7 +55,7 @@
 	<div class="buttons">
 		<a class="run" title="Run this code [shift-enter]">Run</a>
 		<a class="fmt" title="Format this code">Format</a>
-		{{if $.Share}}
+		{{if not $.GoogleCN}}
 		<a class="share" title="Share this code">Share</a>
 		{{end}}
 	</div>
@@ -95,7 +95,7 @@
 the content of this page is licensed under the
 Creative Commons Attribution 3.0 License,
 and code is licensed under a <a href="/LICENSE">BSD license</a>.<br>
-<a href="/doc/tos.html">Terms of Service</a> | 
+<a href="/doc/tos.html">Terms of Service</a> |
 <a href="http://www.google.com/intl/en/policies/privacy/">Privacy Policy</a>
 </div>