1
0
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:
Sameer Ajmani 2015-07-15 14:49:51 -04:00
parent c5ca59aab8
commit 87156cb766
2 changed files with 5 additions and 94 deletions

View File

@ -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)
}

View File

@ -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)
}
}
}