-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhttpstub.go
78 lines (67 loc) · 1.71 KB
/
httpstub.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package httpstub
import (
"net/http"
"net/http/httptest"
"strings"
)
// Server is a configurable stub server.
type Server struct {
URL string
srv *httptest.Server
endpoints []*Endpoint
defaultContentType string
}
// New starts a new stub server.
func New() *Server {
s := &Server{}
ts := httptest.NewServer(s)
s.srv = ts
s.URL = ts.URL
return s
}
// Close shuts down the server and releases the port it was listening on.
func (s *Server) Close() {
s.srv.Close()
}
// Path creates an endpoint to respond to a request URL path. Paths can be static prefixes or may contain * to signify a path component wildcard, so /u/*/n matches /u/2/n.
func (s *Server) Path(p string) *Endpoint {
e := &Endpoint{
path: p,
contentType: s.defaultContentType,
}
s.endpoints = append(s.endpoints, e)
return e
}
// WithDefaultContentType sets the default content type for the server. Evaluated when creating endpoints, so must be set first.
func (s *Server) WithDefaultContentType(t string) *Server {
s.defaultContentType = t
return s
}
// ServeHTTP sets *Server implement http.Handler.
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
for _, e := range s.endpoints {
// find the first matching endpoint
if !matches(r.URL.Path, e.path) {
continue
}
e.ServeHTTP(w, r)
return
}
}
// matches checks the request path against an endpoint path prefix pattern, comparing each path component one by one, treating * as a wildcard
func matches(req, endp string) bool {
pc := strings.Split(req, "/")
ec := strings.Split(endp, "/")
if len(ec) > len(pc) {
return false
}
for i, c := range ec {
if c == "*" {
continue
}
if c != pc[i] {
return false
}
}
return true
}