mirror of
https://github.com/golang/go
synced 2024-11-18 12:54:44 -07:00
tools/godoc: remove server's dependence on "expvar".
Importing "expvar" exports server variables on /debug/vars by default. This raises security concerns in some environments. Users should opt-in to this instead. If users need godoc metrics, we can provide a function in the godoc package to read them. Change-Id: Ie12e695d5958b646e82e7e00de651cc1913aa98d Reviewed-on: https://go-review.googlesource.com/12270 Reviewed-by: Andrew Gerrand <adg@golang.org>
This commit is contained in:
parent
c5ca59aab8
commit
87156cb766
@ -7,7 +7,6 @@ package godoc
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"expvar"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/build"
|
||||
@ -460,27 +459,18 @@ func (w *writerCapturesErr) Write(p []byte) (int, error) {
|
||||
return n, err
|
||||
}
|
||||
|
||||
var httpErrors *expvar.Map
|
||||
|
||||
func init() {
|
||||
httpErrors = expvar.NewMap("httpWriteErrors").Init()
|
||||
}
|
||||
|
||||
// applyTemplateToResponseWriter uses an http.ResponseWriter as the io.Writer
|
||||
// for the call to template.Execute. It uses an io.Writer wrapper to capture
|
||||
// errors from the underlying http.ResponseWriter. If an error is found, an
|
||||
// expvar will be incremented. Other template errors will be logged. This is
|
||||
// done to keep from polluting log files with error messages due to networking
|
||||
// issues, such as client disconnects and http HEAD protocol violations.
|
||||
// errors from the underlying http.ResponseWriter. Errors are logged only when
|
||||
// they come from the template processing and not the Writer; this avoid
|
||||
// polluting log files with error messages due to networking issues, such as
|
||||
// client disconnects and http HEAD protocol violations.
|
||||
func applyTemplateToResponseWriter(rw http.ResponseWriter, t *template.Template, data interface{}) {
|
||||
w := &writerCapturesErr{w: rw}
|
||||
err := t.Execute(w, data)
|
||||
// There are some cases where template.Execute does not return an error when
|
||||
// rw returns an error, and some where it does. So check w.err first.
|
||||
if w.err != nil {
|
||||
// For http errors, increment an expvar.
|
||||
httpErrors.Add(w.err.Error(), 1)
|
||||
} else if err != nil {
|
||||
if w.err == nil && err != nil {
|
||||
// Log template errors.
|
||||
log.Printf("%s.Execute: %s", t.Name(), err)
|
||||
}
|
||||
|
@ -1,79 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package godoc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"expvar"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
var (
|
||||
// NOTE: with no plain-text in the template, template.Execute will not
|
||||
// return an error when http.ResponseWriter.Write does return an error.
|
||||
tmpl = template.Must(template.New("test").Parse("{{.Foo}}"))
|
||||
)
|
||||
|
||||
type withFoo struct {
|
||||
Foo int
|
||||
}
|
||||
|
||||
type withoutFoo struct {
|
||||
}
|
||||
|
||||
type errResponseWriter struct {
|
||||
}
|
||||
|
||||
func (*errResponseWriter) Header() http.Header {
|
||||
return http.Header{}
|
||||
}
|
||||
|
||||
func (*errResponseWriter) WriteHeader(int) {
|
||||
}
|
||||
|
||||
func (*errResponseWriter) Write(p []byte) (int, error) {
|
||||
return 0, errors.New("error")
|
||||
}
|
||||
|
||||
func TestApplyTemplateToResponseWriter(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
desc string
|
||||
rw http.ResponseWriter
|
||||
data interface{}
|
||||
expVars int
|
||||
}{
|
||||
{
|
||||
desc: "no error",
|
||||
rw: &httptest.ResponseRecorder{},
|
||||
data: &withFoo{},
|
||||
expVars: 0,
|
||||
},
|
||||
{
|
||||
desc: "template error",
|
||||
rw: &httptest.ResponseRecorder{},
|
||||
data: &withoutFoo{},
|
||||
expVars: 0,
|
||||
},
|
||||
{
|
||||
desc: "ResponseWriter error",
|
||||
rw: &errResponseWriter{},
|
||||
data: &withFoo{},
|
||||
expVars: 1,
|
||||
},
|
||||
} {
|
||||
httpErrors.Init()
|
||||
applyTemplateToResponseWriter(tc.rw, tmpl, tc.data)
|
||||
gotVars := 0
|
||||
httpErrors.Do(func(expvar.KeyValue) {
|
||||
gotVars++
|
||||
})
|
||||
if gotVars != tc.expVars {
|
||||
t.Errorf("applyTemplateToResponseWriter(%q): got %d vars, want %d", tc.desc, gotVars, tc.expVars)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user