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>
This commit is contained in:
Andrew Bonventre 2017-08-02 16:37:59 -04:00
parent fcc44a6330
commit 4e70a1b26a
8 changed files with 40 additions and 26 deletions

View File

@ -10,7 +10,7 @@ binary. It can be tedious to recompile assets every time, but you can pass a
flag to load CSS/JS/templates from disk every time a page loads: 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 ## Recompiling static assets

View File

@ -421,9 +421,9 @@ func sanitizeFunc(src string) string {
} }
type PageInfo struct { type PageInfo struct {
Dirname string // directory containing the package Dirname string // directory containing the package
Err error // error or nil Err error // error or nil
Share bool // show share button on examples GoogleCN bool // page is being served from golang.google.cn
Mode PageInfoMode // display metadata from query string Mode PageInfoMode // display metadata from query string
@ -683,8 +683,8 @@ func (p *Presentation) example_htmlFunc(info *PageInfo, funcName string) string
err := p.ExampleHTML.Execute(&buf, struct { err := p.ExampleHTML.Execute(&buf, struct {
Name, Doc, Code, Play, Output string Name, Doc, Code, Play, Output string
Share bool GoogleCN bool
}{eg.Name, eg.Doc, code, play, out, info.Share}) }{eg.Name, eg.Doc, code, play, out, info.GoogleCN})
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }

View File

@ -9,6 +9,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings"
) )
// Page describes the contents of the top-level godoc webpage. // Page describes the contents of the top-level godoc webpage.
@ -19,7 +20,7 @@ type Page struct {
SrcPath string SrcPath string
Query string Query string
Body []byte Body []byte
Share bool GoogleCN bool // page is being served from golang.google.cn
// filled in by servePage // filled in by servePage
SearchBox bool SearchBox bool
@ -51,19 +52,25 @@ func (p *Presentation) ServeError(w http.ResponseWriter, r *http.Request, relpat
Title: "File " + relpath, Title: "File " + relpath,
Subtitle: relpath, Subtitle: relpath,
Body: applyTemplate(p.ErrorHTML, "errorHTML", err), 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 { if !onAppengine {
return false
}
if strings.HasSuffix(r.Host, ".cn") {
return true return true
} }
switch r.Header.Get("X-AppEngine-Country") { switch r.Header.Get("X-AppEngine-Country") {
case "", "ZZ", "CN": case "", "ZZ", "CN":
return false return true
} }
return true return false
} }

View File

@ -19,6 +19,7 @@ import (
"net/http" "net/http"
"net/http/httputil" "net/http/httputil"
"net/url" "net/url"
"strings"
"time" "time"
"golang.org/x/net/context" "golang.org/x/net/context"
@ -147,8 +148,8 @@ func cacheKey(body string) string {
} }
func share(w http.ResponseWriter, r *http.Request) { func share(w http.ResponseWriter, r *http.Request) {
if !allowShare(r) { if googleCN(r) {
http.Error(w, "Forbidden", http.StatusForbidden) http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
return return
} }
target, _ := url.Parse(playgroundURL) target, _ := url.Parse(playgroundURL)
@ -157,13 +158,19 @@ func share(w http.ResponseWriter, r *http.Request) {
p.ServeHTTP(w, r) 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() { if appengine.IsDevAppServer() {
return false
}
if strings.HasSuffix(r.Host, ".cn") {
return true return true
} }
switch r.Header.Get("X-AppEngine-Country") { switch r.Header.Get("X-AppEngine-Country") {
case "", "ZZ", "CN": case "", "ZZ", "CN":
return false return true
} }
return true return false
} }

View File

@ -126,7 +126,7 @@ func (p *Presentation) HandleSearch(w http.ResponseWriter, r *http.Request) {
Tabtitle: query, Tabtitle: query,
Query: query, Query: query,
Body: body.Bytes(), Body: body.Bytes(),
Share: allowShare(r), GoogleCN: googleCN(r),
}) })
} }

View File

@ -312,13 +312,13 @@ func (h *handlerServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
info.TypeInfoIndex[ti.Name] = i info.TypeInfoIndex[ti.Name] = i
} }
info.Share = allowShare(r) info.GoogleCN = googleCN(r)
h.p.ServePage(w, Page{ h.p.ServePage(w, Page{
Title: title, Title: title,
Tabtitle: tabtitle, Tabtitle: tabtitle,
Subtitle: subtitle, Subtitle: subtitle,
Body: applyTemplate(h.p.PackageHTML, "packageHTML", info), Body: applyTemplate(h.p.PackageHTML, "packageHTML", info),
Share: info.Share, GoogleCN: info.GoogleCN,
}) })
} }
@ -583,7 +583,7 @@ func (p *Presentation) serveTextFile(w http.ResponseWriter, r *http.Request, abs
SrcPath: relpath, SrcPath: relpath,
Tabtitle: relpath, Tabtitle: relpath,
Body: buf.Bytes(), Body: buf.Bytes(),
Share: allowShare(r), GoogleCN: googleCN(r),
}) })
} }
@ -654,7 +654,7 @@ func (p *Presentation) serveDirectory(w http.ResponseWriter, r *http.Request, ab
SrcPath: relpath, SrcPath: relpath,
Tabtitle: relpath, Tabtitle: relpath,
Body: applyTemplate(p.DirlistHTML, "dirlistHTML", list), Body: applyTemplate(p.DirlistHTML, "dirlistHTML", list),
Share: allowShare(r), GoogleCN: googleCN(r),
}) })
} }
@ -683,7 +683,7 @@ func (p *Presentation) ServeHTMLDoc(w http.ResponseWriter, r *http.Request, absp
page := Page{ page := Page{
Title: meta.Title, Title: meta.Title,
Subtitle: meta.Subtitle, Subtitle: meta.Subtitle,
Share: allowShare(r), GoogleCN: googleCN(r),
} }
// evaluate as template if indicated // evaluate as template if indicated

View File

@ -13,7 +13,7 @@
<div class="buttons"> <div class="buttons">
<a class="run" title="Run this code [shift-enter]">Run</a> <a class="run" title="Run this code [shift-enter]">Run</a>
<a class="fmt" title="Format this code">Format</a> <a class="fmt" title="Format this code">Format</a>
{{if $.Share}} {{if not $.GoogleCN}}
<a class="share" title="Share this code">Share</a> <a class="share" title="Share this code">Share</a>
{{end}} {{end}}
</div> </div>

View File

@ -55,7 +55,7 @@ func main() {
<div class="buttons"> <div class="buttons">
<a class="run" title="Run this code [shift-enter]">Run</a> <a class="run" title="Run this code [shift-enter]">Run</a>
<a class="fmt" title="Format this code">Format</a> <a class="fmt" title="Format this code">Format</a>
{{if $.Share}} {{if not $.GoogleCN}}
<a class="share" title="Share this code">Share</a> <a class="share" title="Share this code">Share</a>
{{end}} {{end}}
</div> </div>
@ -95,7 +95,7 @@ Except as <a href="https://developers.google.com/site-policies#restrictions">not
the content of this page is licensed under the the content of this page is licensed under the
Creative Commons Attribution 3.0 License, Creative Commons Attribution 3.0 License,
and code is licensed under a <a href="/LICENSE">BSD license</a>.<br> 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> <a href="http://www.google.com/intl/en/policies/privacy/">Privacy Policy</a>
</div> </div>