Просмотр исходного кода

Refactor log into self-managing objects

Lu Stadler лет назад: 7
Родитель
Сommit
1bd93213d3
1 измененных файлов с 50 добавлено и 19 удалено
  1. 50 19
      go/fake-http/fake-http.go

+ 50 - 19
go/fake-http/fake-http.go

@ -10,7 +10,6 @@ import (
10 10
	"io/ioutil"
11 11
	"log"
12 12
	"net/http"
13
	"net/http/httputil"
14 13
	"net/url"
15 14
	"os"
16 15
	"os/exec"
@ -58,7 +57,7 @@ func main() {
58 57
		responsesPath = flag.Arg(0)
59 58
	}
60 59
61
	requestLog := make([]LogEntry, 0)
60
	requestLog := Log(make([]LogEntry, 0))
62 61
63 62
	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
64 63
		responses.Load(responsesPath)
@ -73,12 +72,6 @@ func main() {
73 72
		userAgent := req.Header.Get("User-Agent")
74 73
		log.Printf("%s %s - %d (%s, %q)", req.Method, req.URL, resp.StatusCode, req.RemoteAddr, userAgent)
75 74
76
		out, err := httputil.DumpRequest(req, true)
77
		if err != nil {
78
			log.Printf("Error: Dumping request: %s", err)
79
			return
80
		}
81
82 75
		if resp.Header.Get("Content-Type") == "application/json" {
83 76
			pretty, err := prettyfyJSON(resp.Body)
84 77
			if err != nil {
@ -89,17 +82,14 @@ func main() {
89 82
			}
90 83
		}
91 84
92
		requestLog = append(requestLog, LogEntry{
93
			Request:  out,
94
			Response: asResponse(req, resp),
95
		})
85
		requestLog.Log(req, resp)
96 86
	})
97 87
98 88
	http.HandleFunc("/_log", func(w http.ResponseWriter, req *http.Request) {
99 89
		if strings.Contains(req.Header.Get("Accept"), "application/yaml") {
100 90
			rs := make([]Response, len(requestLog))
101 91
			for i, log := range requestLog {
102
				rs[i] = log.Response
92
				rs[i] = log.AsResponse()
103 93
			}
104 94
			err := renderYAML(w, rs)
105 95
			if err != nil {
@ -110,9 +100,9 @@ func main() {
110 100
111 101
		for i := len(requestLog) - 1; i >= 0; i-- {
112 102
			w.Write([]byte("------------------------------------------------------\n"))
113
			w.Write(requestLog[i].Request)
114
			w.Write([]byte("\n\n"))
115
			requestLog[i].Response.AsHTTP().Write(w)
103
			requestLog[i].Request().Write(w)
104
			w.Write([]byte("\n"))
105
			requestLog[i].Response().Write(w)
116 106
			w.Write([]byte("\n"))
117 107
		}
118 108
	})
@ -253,10 +243,51 @@ func renderYAML(w http.ResponseWriter, responses []Response) error {
253 243
	return nil
254 244
}
255 245
256
// LogEntry is a request/respond pair for logging.
246
// Log collects HTTP requests/responses for later display and
247
// processing.
248
type Log []LogEntry
249
250
// Log logs the request/response pair.
251
func (l *Log) Log(req *http.Request, resp *http.Response) {
252
	e := LogEntry{
253
		request:      req,
254
		requestBody:  new(bytes.Buffer),
255
		response:     resp,
256
		responseBody: new(bytes.Buffer),
257
	}
258
	io.Copy(e.requestBody, req.Body)
259
	io.Copy(e.responseBody, resp.Body)
260
	*l = append(*l, e)
261
}
262
263
// LogEntry is a request/response pair for logging.
257 264
type LogEntry struct {
258
	Request  Request
259
	Response Response
265
	request      *http.Request
266
	requestBody  *bytes.Buffer
267
	response     *http.Response
268
	responseBody *bytes.Buffer
269
}
270
271
// AsResponse returns a Response representation of the entry.
272
func (e LogEntry) AsResponse() Response {
273
	return Response{
274
		Method: e.request.Method,
275
		Path:   e.request.URL.Path,
276
		Status: e.response.StatusCode,
277
		Body:   e.responseBody.String(),
278
	}
279
}
280
281
// Request returns the stored http.Request.
282
func (e LogEntry) Request() *http.Request {
283
	e.request.Body = ioutil.NopCloser(bytes.NewReader(e.requestBody.Bytes()))
284
	return e.request
285
}
286
287
// Response returns the stored http.Response.
288
func (e LogEntry) Response() *http.Response {
289
	e.response.Body = ioutil.NopCloser(bytes.NewReader(e.responseBody.Bytes()))
290
	return e.response
260 291
}
261 292
262 293
// Request is a stored serialized HTTP request.