Ver código fonte

tsweb: add StdHandlerOpts that accepts an options struct

I'm about to add yet another StdHandler option.
Time to refactor.

Signed-off-by: Josh Bleecher Snyder <[email protected]>
Josh Bleecher Snyder 5 anos atrás
pai
commit
e98f2c57d6
2 arquivos alterados com 29 adições e 17 exclusões
  1. 28 16
      tsweb/tsweb.go
  2. 1 1
      tsweb/tsweb_test.go

+ 28 - 16
tsweb/tsweb.go

@@ -157,11 +157,17 @@ type ReturnHandler interface {
 	ServeHTTPReturn(http.ResponseWriter, *http.Request) error
 }
 
+type HandlerOptions struct {
+	Quiet200s bool // if set, do not log successfully handled HTTP requests
+	Logf      logger.Logf
+	Now       func() time.Time // if nil, defaults to time.Now
+}
+
 // StdHandler converts a ReturnHandler into a standard http.Handler.
 // Handled requests are logged using logf, as are any errors. Errors
 // are handled as specified by the Handler interface.
 func StdHandler(h ReturnHandler, logf logger.Logf) http.Handler {
-	return stdHandler(h, logf, time.Now, true)
+	return StdHandlerOpts(h, HandlerOptions{Logf: logf, Now: time.Now})
 }
 
 // ReturnHandlerFunc is an adapter to allow the use of ordinary
@@ -178,27 +184,32 @@ func (f ReturnHandlerFunc) ServeHTTPReturn(w http.ResponseWriter, r *http.Reques
 // StdHandlerNo200s is like StdHandler, but successfully handled HTTP
 // requests don't write an access log entry to logf.
 //
-// TODO(danderson): quick stopgap, probably want ...Options on StdHandler instead?
+// TODO(josharian): eliminate this and StdHandler in favor of StdHandlerOpts,
+// rename StdHandlerOpts to StdHandler. Will be a breaking API change.
 func StdHandlerNo200s(h ReturnHandler, logf logger.Logf) http.Handler {
-	return stdHandler(h, logf, time.Now, false)
+	return StdHandlerOpts(h, HandlerOptions{Logf: logf, Now: time.Now, Quiet200s: true})
 }
 
-func stdHandler(h ReturnHandler, logf logger.Logf, now func() time.Time, log200s bool) http.Handler {
-	return retHandler{h, logf, now, log200s}
+// StdHandlerOpts converts a ReturnHandler into a standard http.Handler.
+// Handled requests are logged using opts.Logf, as are any errors.
+// Errors are handled as specified by the Handler interface.
+func StdHandlerOpts(h ReturnHandler, opts HandlerOptions) http.Handler {
+	if opts.Now == nil {
+		opts.Now = time.Now
+	}
+	return retHandler{h, opts}
 }
 
 // retHandler is an http.Handler that wraps a Handler and handles errors.
 type retHandler struct {
-	rh      ReturnHandler
-	logf    logger.Logf
-	timeNow func() time.Time
-	log200s bool
+	rh   ReturnHandler
+	opts HandlerOptions
 }
 
 // ServeHTTP implements the http.Handler interface.
 func (h retHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	msg := AccessLogRecord{
-		When:       h.timeNow(),
+		When:       h.opts.Now(),
 		RemoteAddr: r.RemoteAddr,
 		Proto:      r.Proto,
 		TLS:        r.TLS != nil,
@@ -209,7 +220,7 @@ func (h retHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		Referer:    r.Referer(),
 	}
 
-	lw := &loggingResponseWriter{ResponseWriter: w, logf: h.logf}
+	lw := &loggingResponseWriter{ResponseWriter: w, logf: h.opts.Logf}
 	err := h.rh.ServeHTTPReturn(lw, r)
 	hErr, hErrOK := err.(HTTPError)
 
@@ -219,7 +230,7 @@ func (h retHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		lw.code = 200
 	}
 
-	msg.Seconds = h.timeNow().Sub(msg.When).Seconds()
+	msg.Seconds = h.opts.Now().Sub(msg.When).Seconds()
 	msg.Code = lw.code
 	msg.Bytes = lw.bytes
 
@@ -245,12 +256,12 @@ func (h retHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 			}
 		}
 		if lw.code != 0 {
-			h.logf("[unexpected] handler returned HTTPError %v, but already sent a response with code %d", hErr, lw.code)
+			h.opts.Logf("[unexpected] handler returned HTTPError %v, but already sent a response with code %d", hErr, lw.code)
 			break
 		}
 		msg.Code = hErr.Code
 		if msg.Code == 0 {
-			h.logf("[unexpected] HTTPError %v did not contain an HTTP status code, sending internal server error", hErr)
+			h.opts.Logf("[unexpected] HTTPError %v did not contain an HTTP status code, sending internal server error", hErr)
 			msg.Code = http.StatusInternalServerError
 		}
 		http.Error(lw, hErr.Msg, msg.Code)
@@ -264,8 +275,9 @@ func (h retHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		}
 	}
 
-	if msg.Code != 200 || h.log200s {
-		h.logf("%s", msg)
+	if msg.Code != 200 || !h.opts.Quiet200s {
+		h.opts.Logf("%s", msg)
+	}
 	}
 }
 

+ 1 - 1
tsweb/tsweb_test.go

@@ -248,7 +248,7 @@ func TestStdHandler(t *testing.T) {
 			clock.Reset()
 
 			rec := noopHijacker{httptest.NewRecorder(), false}
-			h := stdHandler(test.rh, logf, clock.Now, true)
+			h := StdHandlerOpts(test.rh, HandlerOptions{Logf: logf, Now: clock.Now})
 			h.ServeHTTP(&rec, test.r)
 			res := rec.Result()
 			if res.StatusCode != test.wantCode {