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"
"golang.org/x/tools/godoc/vfs/mapfs" "golang.org/x/tools/godoc/vfs/mapfs"
"golang.org/x/tools/godoc/vfs/zipfs" "golang.org/x/tools/godoc/vfs/zipfs"
"appengine"
) )
func init() { func init() {
enforceHosts = !appengine.IsDevAppServer()
playEnabled = true playEnabled = true
log.Println("initializing godoc ...") log.Println("initializing godoc ...")

View File

@ -15,6 +15,7 @@ package main
import ( import (
"log" "log"
"net/http" "net/http"
"strings"
"text/template" "text/template"
"golang.org/x/tools/godoc" "golang.org/x/tools/godoc"
@ -27,16 +28,51 @@ var (
fs = vfs.NameSpace{} 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) { func registerHandlers(pres *godoc.Presentation) {
if pres == nil { if pres == nil {
panic("nil Presentation") panic("nil Presentation")
} }
http.HandleFunc("/doc/codewalk/", codewalk) mux := http.NewServeMux()
http.Handle("/doc/play/", pres.FileServer()) mux.HandleFunc("/doc/codewalk/", codewalk)
http.Handle("/robots.txt", pres.FileServer()) mux.Handle("/doc/play/", pres.FileServer())
http.Handle("/", pres) mux.Handle("/robots.txt", pres.FileServer())
http.Handle("/pkg/C/", redirect.Handler("/cmd/cgo/")) mux.Handle("/", pres)
redirect.Register(nil) mux.Handle("/pkg/C/", redirect.Handler("/cmd/cgo/"))
redirect.Register(mux)
http.Handle("/", hostEnforcerHandler{mux})
} }
func readTemplate(name string) *template.Template { func readTemplate(name string) *template.Template {