blob: daf4dc98aba852121b25eb6a0e78564f5248b9f4 [file] [log] [blame]
Brad Fitzpatrickca3319f2013-07-17 17:17:12 +10001// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package godoc
6
7import (
Brad Fitzpatrickca3319f2013-07-17 17:17:12 +10008 "net/http"
Francesc Campoy3f4088e2016-09-20 16:58:29 -07009 "os"
10 "path/filepath"
Brad Fitzpatrickca3319f2013-07-17 17:17:12 +100011 "runtime"
Andrew Bonventre4e70a1b2017-08-02 16:37:59 -040012 "strings"
Chris Broadfootee6b0312018-09-04 09:55:45 -070013
Dmitri Shuralyovbd17c082019-03-05 16:56:02 -050014 "golang.org/x/tools/godoc/golangorgenv"
Brad Fitzpatrickca3319f2013-07-17 17:17:12 +100015)
16
17// Page describes the contents of the top-level godoc webpage.
18type Page struct {
19 Title string
20 Tabtitle string
21 Subtitle string
Sina Siadat5128de72016-09-16 17:12:50 +043022 SrcPath string
Brad Fitzpatrickca3319f2013-07-17 17:17:12 +100023 Query string
24 Body []byte
Andrew Bonventre4e70a1b2017-08-02 16:37:59 -040025 GoogleCN bool // page is being served from golang.google.cn
Agniva De Sarkerc75e7e62018-05-12 10:43:07 +053026 TreeView bool // page needs to contain treeview related js and css
Brad Fitzpatrickca3319f2013-07-17 17:17:12 +100027
Chris Broadfootee6b0312018-09-04 09:55:45 -070028 // filled in by ServePage
29 SearchBox bool
30 Playground bool
31 Version string
32 GoogleAnalytics string
Brad Fitzpatrickca3319f2013-07-17 17:17:12 +100033}
34
Brad Fitzpatrick4fc63232013-07-18 09:52:45 +100035func (p *Presentation) ServePage(w http.ResponseWriter, page Page) {
Brad Fitzpatrickca3319f2013-07-17 17:17:12 +100036 if page.Tabtitle == "" {
37 page.Tabtitle = page.Title
38 }
Brad Fitzpatrick4fc63232013-07-18 09:52:45 +100039 page.SearchBox = p.Corpus.IndexEnabled
Brad Fitzpatrick5395cfe2013-07-18 13:14:09 +100040 page.Playground = p.ShowPlayground
Brad Fitzpatrickca3319f2013-07-17 17:17:12 +100041 page.Version = runtime.Version()
Chris Broadfootee6b0312018-09-04 09:55:45 -070042 page.GoogleAnalytics = p.GoogleAnalytics
Brad Garciaefd232e2014-01-29 10:53:45 -050043 applyTemplateToResponseWriter(w, p.GodocHTML, page)
Brad Fitzpatrickca3319f2013-07-17 17:17:12 +100044}
45
Brad Fitzpatrick4fc63232013-07-18 09:52:45 +100046func (p *Presentation) ServeError(w http.ResponseWriter, r *http.Request, relpath string, err error) {
Brad Fitzpatrickca3319f2013-07-17 17:17:12 +100047 w.WriteHeader(http.StatusNotFound)
Francesc Campoy3f4088e2016-09-20 16:58:29 -070048 if perr, ok := err.(*os.PathError); ok {
49 rel, err := filepath.Rel(runtime.GOROOT(), perr.Path)
50 if err != nil {
51 perr.Path = "REDACTED"
52 } else {
53 perr.Path = filepath.Join("$GOROOT", rel)
54 }
55 }
Brad Fitzpatrick4fc63232013-07-18 09:52:45 +100056 p.ServePage(w, Page{
Chris Broadfootee6b0312018-09-04 09:55:45 -070057 Title: "File " + relpath,
58 Subtitle: relpath,
59 Body: applyTemplate(p.ErrorHTML, "errorHTML", err),
60 GoogleCN: googleCN(r),
61 GoogleAnalytics: p.GoogleAnalytics,
Brad Fitzpatrickca3319f2013-07-17 17:17:12 +100062 })
63}
Andrew Gerrand1330b282015-09-02 09:49:30 +100064
Dmitri Shuralyovbd17c082019-03-05 16:56:02 -050065// googleCN reports whether request r is considered
66// to be served from golang.google.cn.
Andrew Bonventre4e70a1b2017-08-02 16:37:59 -040067func googleCN(r *http.Request) bool {
68 if r.FormValue("googlecn") != "" {
69 return true
70 }
Andrew Bonventre4e70a1b2017-08-02 16:37:59 -040071 if strings.HasSuffix(r.Host, ".cn") {
Andrew Gerrand1330b282015-09-02 09:49:30 +100072 return true
73 }
Dmitri Shuralyovbd17c082019-03-05 16:56:02 -050074 if !golangorgenv.CheckCountry() {
75 return false
76 }
77 switch r.Header.Get("X-Appengine-Country") {
Andrew Gerrande1d85eb2015-09-28 17:00:17 +100078 case "", "ZZ", "CN":
Andrew Bonventre4e70a1b2017-08-02 16:37:59 -040079 return true
Andrew Gerrand1330b282015-09-02 09:49:30 +100080 }
Andrew Bonventre4e70a1b2017-08-02 16:37:59 -040081 return false
Andrew Gerrand1330b282015-09-02 09:49:30 +100082}