commit
						40e21be5e3
					
				@ -0,0 +1,82 @@ | 
				
			||||
package httpdebug | 
				
			||||
 | 
				
			||||
import ( | 
				
			||||
	"bytes" | 
				
			||||
	"fmt" | 
				
			||||
	"io" | 
				
			||||
	"io/ioutil" | 
				
			||||
	"log" | 
				
			||||
	"net/http" | 
				
			||||
	"unicode" | 
				
			||||
) | 
				
			||||
 | 
				
			||||
// Wrap returns an http handler that serves h while logging requests and responses to stderr.
 | 
				
			||||
func Wrap(h http.Handler) http.Handler { | 
				
			||||
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | 
				
			||||
		log.Println(r.Method, r.URL.Path, r.Proto) | 
				
			||||
 | 
				
			||||
		hBuf := &bytes.Buffer{} | 
				
			||||
		r.Header.Write(hBuf) | 
				
			||||
		log.Println(hBuf.String()) | 
				
			||||
 | 
				
			||||
		requestBuf := &bytes.Buffer{} | 
				
			||||
		responseBuf := &bytes.Buffer{} | 
				
			||||
 | 
				
			||||
		defer r.Body.Close() | 
				
			||||
 | 
				
			||||
		r.Body = ioutil.NopCloser(io.TeeReader(r.Body, requestBuf)) | 
				
			||||
 | 
				
			||||
		h.ServeHTTP(rw{ | 
				
			||||
			ResponseWriter: w, | 
				
			||||
			w:              responseBuf, | 
				
			||||
		}, r) | 
				
			||||
 | 
				
			||||
		if requestBuf.Len() > 1024 { | 
				
			||||
			trimmed := &bytes.Buffer{} | 
				
			||||
			io.CopyN(trimmed, requestBuf, 128) | 
				
			||||
			requestBuf = trimmed | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		log.Println() | 
				
			||||
		log.Println(logsafe(requestBuf.String())) | 
				
			||||
 | 
				
			||||
		hBuf.Reset() | 
				
			||||
		w.Header().Write(hBuf) | 
				
			||||
		log.Println(hBuf.String()) | 
				
			||||
 | 
				
			||||
		responseBuf = trim(responseBuf, 128) | 
				
			||||
 | 
				
			||||
		log.Println() | 
				
			||||
		log.Println(logsafe(responseBuf.String())) | 
				
			||||
	}) | 
				
			||||
} | 
				
			||||
 | 
				
			||||
type rw struct { | 
				
			||||
	http.ResponseWriter | 
				
			||||
	w io.Writer | 
				
			||||
} | 
				
			||||
 | 
				
			||||
func (rw rw) Write(b []byte) (int, error) { | 
				
			||||
	rw.w.Write(b) | 
				
			||||
	return rw.ResponseWriter.Write(b) | 
				
			||||
} | 
				
			||||
 | 
				
			||||
func logsafe(str string) string { | 
				
			||||
	buf := &bytes.Buffer{} | 
				
			||||
 | 
				
			||||
	for _, r := range str { | 
				
			||||
		if unicode.IsPrint(r) || unicode.IsSpace(r) { | 
				
			||||
			fmt.Fprintf(buf, "%c", r) | 
				
			||||
		} else { | 
				
			||||
			fmt.Fprintf(buf, "%x", r) | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	return buf.String() | 
				
			||||
} | 
				
			||||
 | 
				
			||||
func trim(b *bytes.Buffer, n int) *bytes.Buffer { | 
				
			||||
	trimmed := &bytes.Buffer{} | 
				
			||||
	io.CopyN(trimmed, b, int64(n)) | 
				
			||||
	return trimmed | 
				
			||||
} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue