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

Implement a very simple request cache

This really only makes sense for the proxy mode, otherwise it would
"cache" the already loaded responses, but the responses *are* the cache.

Maybe the cache should be a separate variable and we should forbid to
use `-cache` without `-proxy-url`?
Lu Stadler лет назад: 7
Родитель
Сommit
bc1a334e24
1 измененных файлов с 19 добавлено и 10 удалено
  1. 19 10
      go/fake-http/fake-http.go

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

28
	proxyClientKey  string
28
	proxyClientKey  string
29
29
30
	proxyMinikube bool
30
	proxyMinikube bool
31
	cache         bool
31
}
32
}
32
33
33
func init() {
34
func init() {
37
	flag.StringVar(&flags.proxyClientKey, "proxy-client-key", "", "Client key to use when connecting to proxy")
38
	flag.StringVar(&flags.proxyClientKey, "proxy-client-key", "", "Client key to use when connecting to proxy")
38
39
39
	flag.BoolVar(&flags.proxyMinikube, "proxy-minikube", false, "Shortcut for -proxy-url https://$(minikube ip):8443 -proxy-client-cert ~/.minikube/client.crt -proxy-client-key ~/.minikube/client.key")
40
	flag.BoolVar(&flags.proxyMinikube, "proxy-minikube", false, "Shortcut for -proxy-url https://$(minikube ip):8443 -proxy-client-cert ~/.minikube/client.crt -proxy-client-key ~/.minikube/client.key")
41
	flag.BoolVar(&flags.cache, "cache", false, "Cache all requests")
40
}
42
}
41
43
42
func main() {
44
func main() {
69
	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
71
	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
70
		responses.Load(responsesPath)
72
		responses.Load(responsesPath)
71
73
74
		stub := responses.Match(req)
75
		haveCachedStub := flags.cache && stub != nil
72
		var resp *http.Response
76
		var resp *http.Response
73
		if flags.proxyURL != "" {
77
		if flags.proxyURL != "" && !haveCachedStub {
74
			resp = respondWithProxy(flags.proxyURL, &cert, w, req)
78
			resp = respondWithProxy(flags.proxyURL, &cert, w, req)
75
		} else {
79
		} else {
76
			resp = respondWithStub(responses, w, req)
80
			resp = respondWithStub(stub, w, req)
77
		}
81
		}
78
82
79
		requestLog.Log(req, resp)
83
		e := requestLog.Log(req, resp)
84
		if flags.cache {
85
			responses.Add(e.AsResponse())
86
		}
80
	})
87
	})
81
88
82
	http.HandleFunc("/_log", func(w http.ResponseWriter, req *http.Request) {
89
	http.HandleFunc("/_log", func(w http.ResponseWriter, req *http.Request) {
140
	return nil
147
	return nil
141
}
148
}
142
149
143
func respondWithStub(responses Responses, w http.ResponseWriter, req *http.Request) *http.Response {
144
	resp := responses.Match(req)
145
	if resp == nil {
146
		resp = &Response{Status: 404, Body: "Not found"}
147
	}
148
150
func respondWithStub(resp *Response, w http.ResponseWriter, req *http.Request) *http.Response {
149
	time.Sleep(resp.Delay)
151
	time.Sleep(resp.Delay)
150
	if resp.RandomDelay > 0 {
152
	if resp.RandomDelay > 0 {
151
		time.Sleep(time.Duration(rand.Intn(int(resp.RandomDelay))))
153
		time.Sleep(time.Duration(rand.Intn(int(resp.RandomDelay))))
227
type Log []LogEntry
229
type Log []LogEntry
228
230
229
// Log logs the request/response pair.
231
// Log logs the request/response pair.
230
func (l *Log) Log(req *http.Request, resp *http.Response) {
232
func (l *Log) Log(req *http.Request, resp *http.Response) *LogEntry {
231
	userAgent := req.Header.Get("User-Agent")
233
	userAgent := req.Header.Get("User-Agent")
232
	log.Printf("%s %s - %d (%s, %q)", req.Method, req.URL, resp.StatusCode, req.RemoteAddr, userAgent)
234
	log.Printf("%s %s - %d (%s, %q)", req.Method, req.URL, resp.StatusCode, req.RemoteAddr, userAgent)
233
235
249
	}
251
	}
250
	io.Copy(e.responseBody, resp.Body)
252
	io.Copy(e.responseBody, resp.Body)
251
	*l = append(*l, e)
253
	*l = append(*l, e)
254
	return &e
252
}
255
}
253
256
254
// AsResponses returns the log as a list of response definition.
257
// AsResponses returns the log as a list of response definition.
351
	return nil
354
	return nil
352
}
355
}
353
356
357
// Add adds the response to the log, to include it in future Match
358
// calls.
359
func (rs *Responses) Add(r Response) {
360
	*rs = append(*rs, r)
361
}
362
354
// Load loads responses from the YAML file at path.
363
// Load loads responses from the YAML file at path.
355
func (rs *Responses) Load(path string) {
364
func (rs *Responses) Load(path string) {
356
	if path == "" {
365
	if path == "" {