cmd/godoc: restrict requests to HTTPS and canonical host names

Fixes golang/go#12684

Change-Id: Ibb49e604bfd92c902c9fd2bf9506ded60b2a9d8d
Reviewed-on: https://go-review.googlesource.com/14814
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Andrew Gerrand 2015-09-22 13:53:20 +10:00
parent 5a90b2958f
commit 40b1b219de
2 changed files with 45 additions and 6 deletions

View File

@ -20,9 +20,12 @@ import (
"golang.org/x/tools/godoc/vfs"
"golang.org/x/tools/godoc/vfs/mapfs"
"golang.org/x/tools/godoc/vfs/zipfs"
"appengine"
)
func init() {
enforceHosts = !appengine.IsDevAppServer()
playEnabled = true
log.Println("initializing godoc ...")

View File

@ -15,6 +15,7 @@ package main
import (
"log"
"net/http"
"strings"
"text/template"
"golang.org/x/tools/godoc"
@ -27,16 +28,51 @@ var (
fs = vfs.NameSpace{}
)
var enforceHosts = false // set true in production on app engine
// hostEnforcerHandler redirects requests to "http://foo.golang.org/bar"
// to "https://golang.org/bar".
// It permits requests to the host "godoc-test.golang.org" for testing.
type hostEnforcerHandler struct {
h http.Handler
}
func (h hostEnforcerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if !enforceHosts {
h.h.ServeHTTP(w, r)
return
}
if r.TLS == nil || !h.validHost(r.Host) {
r.URL.Scheme = "https"
if !h.validHost(r.Host) {
r.URL.Host = "golang.org"
}
http.Redirect(w, r, r.URL.String(), http.StatusFound)
return
}
h.h.ServeHTTP(w, r)
}
func (h hostEnforcerHandler) validHost(host string) bool {
switch strings.ToLower(host) {
case "golang.org", "godoc-test.golang.org":
return true
}
return false
}
func registerHandlers(pres *godoc.Presentation) {
if pres == nil {
panic("nil Presentation")
}
http.HandleFunc("/doc/codewalk/", codewalk)
http.Handle("/doc/play/", pres.FileServer())
http.Handle("/robots.txt", pres.FileServer())
http.Handle("/", pres)
http.Handle("/pkg/C/", redirect.Handler("/cmd/cgo/"))
redirect.Register(nil)
mux := http.NewServeMux()
mux.HandleFunc("/doc/codewalk/", codewalk)
mux.Handle("/doc/play/", pres.FileServer())
mux.Handle("/robots.txt", pres.FileServer())
mux.Handle("/", pres)
mux.Handle("/pkg/C/", redirect.Handler("/cmd/cgo/"))
redirect.Register(mux)
http.Handle("/", hostEnforcerHandler{mux})
}
func readTemplate(name string) *template.Template {