github.com/jgarto/itcv@v0.0.0-20180826224514-4eea09c1aa0d/_vendor/src/golang.org/x/tools/cmd/godoc/handlers.go (about) 1 // Copyright 2010 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 5 // The /doc/codewalk/ tree is synthesized from codewalk descriptions, 6 // files named $GOROOT/doc/codewalk/*.xml. 7 // For an example and a description of the format, see 8 // http://golang.org/doc/codewalk/codewalk or run godoc -http=:6060 9 // and see http://localhost:6060/doc/codewalk/codewalk . 10 // That page is itself a codewalk; the source code for it is 11 // $GOROOT/doc/codewalk/codewalk.xml. 12 13 package main 14 15 import ( 16 "encoding/json" 17 "go/format" 18 "log" 19 "net/http" 20 "strings" 21 "text/template" 22 23 "golang.org/x/tools/godoc" 24 "golang.org/x/tools/godoc/redirect" 25 "golang.org/x/tools/godoc/vfs" 26 ) 27 28 var ( 29 pres *godoc.Presentation 30 fs = vfs.NameSpace{} 31 ) 32 33 var enforceHosts = false // set true in production on app engine 34 35 // hostEnforcerHandler redirects requests to "http://foo.golang.org/bar" 36 // to "https://golang.org/bar". 37 // It permits requests to the host "godoc-test.golang.org" for testing and 38 // golang.google.cn for Chinese users. 39 type hostEnforcerHandler struct { 40 h http.Handler 41 } 42 43 func (h hostEnforcerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 44 if !enforceHosts { 45 h.h.ServeHTTP(w, r) 46 return 47 } 48 if r.TLS == nil || !h.validHost(r.Host) { 49 r.URL.Scheme = "https" 50 if h.validHost(r.Host) { 51 r.URL.Host = r.Host 52 } else { 53 r.URL.Host = "golang.org" 54 } 55 http.Redirect(w, r, r.URL.String(), http.StatusFound) 56 return 57 } 58 w.Header().Set("Strict-Transport-Security", "max-age=31536000; preload") 59 h.h.ServeHTTP(w, r) 60 } 61 62 func (h hostEnforcerHandler) validHost(host string) bool { 63 switch strings.ToLower(host) { 64 case "golang.org", "godoc-test.golang.org", "golang.google.cn": 65 return true 66 } 67 return false 68 } 69 70 func registerHandlers(pres *godoc.Presentation) *http.ServeMux { 71 if pres == nil { 72 panic("nil Presentation") 73 } 74 mux := http.NewServeMux() 75 mux.HandleFunc("/doc/codewalk/", codewalk) 76 mux.Handle("/doc/play/", pres.FileServer()) 77 mux.Handle("/robots.txt", pres.FileServer()) 78 mux.Handle("/", pres) 79 mux.Handle("/pkg/C/", redirect.Handler("/cmd/cgo/")) 80 mux.HandleFunc("/fmt", fmtHandler) 81 redirect.Register(mux) 82 83 http.Handle("/", hostEnforcerHandler{mux}) 84 85 return mux 86 } 87 88 func readTemplate(name string) *template.Template { 89 if pres == nil { 90 panic("no global Presentation set yet") 91 } 92 path := "lib/godoc/" + name 93 94 // use underlying file system fs to read the template file 95 // (cannot use template ParseFile functions directly) 96 data, err := vfs.ReadFile(fs, path) 97 if err != nil { 98 log.Fatal("readTemplate: ", err) 99 } 100 // be explicit with errors (for app engine use) 101 t, err := template.New(name).Funcs(pres.FuncMap()).Parse(string(data)) 102 if err != nil { 103 log.Fatal("readTemplate: ", err) 104 } 105 return t 106 } 107 108 func readTemplates(p *godoc.Presentation, html bool) { 109 p.PackageText = readTemplate("package.txt") 110 p.SearchText = readTemplate("search.txt") 111 112 if html || p.HTMLMode { 113 codewalkHTML = readTemplate("codewalk.html") 114 codewalkdirHTML = readTemplate("codewalkdir.html") 115 p.CallGraphHTML = readTemplate("callgraph.html") 116 p.DirlistHTML = readTemplate("dirlist.html") 117 p.ErrorHTML = readTemplate("error.html") 118 p.ExampleHTML = readTemplate("example.html") 119 p.GodocHTML = readTemplate("godoc.html") 120 p.ImplementsHTML = readTemplate("implements.html") 121 p.MethodSetHTML = readTemplate("methodset.html") 122 p.PackageHTML = readTemplate("package.html") 123 p.PackageRootHTML = readTemplate("packageroot.html") 124 p.SearchHTML = readTemplate("search.html") 125 p.SearchDocHTML = readTemplate("searchdoc.html") 126 p.SearchCodeHTML = readTemplate("searchcode.html") 127 p.SearchTxtHTML = readTemplate("searchtxt.html") 128 p.SearchDescXML = readTemplate("opensearch.xml") 129 } 130 } 131 132 type fmtResponse struct { 133 Body string 134 Error string 135 } 136 137 // fmtHandler takes a Go program in its "body" form value, formats it with 138 // standard gofmt formatting, and writes a fmtResponse as a JSON object. 139 func fmtHandler(w http.ResponseWriter, r *http.Request) { 140 resp := new(fmtResponse) 141 body, err := format.Source([]byte(r.FormValue("body"))) 142 if err != nil { 143 resp.Error = err.Error() 144 } else { 145 resp.Body = string(body) 146 } 147 w.Header().Set("Content-type", "application/json; charset=utf-8") 148 json.NewEncoder(w).Encode(resp) 149 }