[release-branch.go1.8] 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>
Reviewed-on: https://go-review.googlesource.com/81075
Reviewed-by: Russ Cox <rsc@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 1063244..fa37d16 100644
--- a/godoc/godoc.go
+++ b/godoc/godoc.go
@@ -438,9 +438,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
 
 	// package info
 	FSet       *token.FileSet         // nil if no package documentation
@@ -650,8 +650,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 35d6cfb..46b0202 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.
@@ -18,7 +19,7 @@
 	Subtitle string
 	Query    string
 	Body     []byte
-	Share    bool
+	GoogleCN bool // page is being served from golang.google.cn
 
 	// filled in by servePage
 	SearchBox  bool
@@ -50,19 +51,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 294610e..480fbab 100644
--- a/godoc/server.go
+++ b/godoc/server.go
@@ -307,13 +307,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,
 	})
 }
 
@@ -555,7 +555,7 @@
 		Title:    title + " " + relpath,
 		Tabtitle: relpath,
 		Body:     buf.Bytes(),
-		Share:    allowShare(r),
+		GoogleCN: googleCN(r),
 	})
 }
 
@@ -616,7 +616,7 @@
 		Title:    "Directory " + relpath,
 		Tabtitle: relpath,
 		Body:     applyTemplate(p.DirlistHTML, "dirlistHTML", list),
-		Share:    allowShare(r),
+		GoogleCN: googleCN(r),
 	})
 }
 
@@ -645,7 +645,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 a700982..d151818 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>
@@ -85,7 +85,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>