-
Notifications
You must be signed in to change notification settings - Fork 2
/
mock_http.go
156 lines (132 loc) · 4.18 KB
/
mock_http.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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package mock
import (
"bufio"
"fmt"
"github.com/golang/glog"
"github.com/jarcoal/httpmock"
"net/http"
"net/http/httputil"
"strings"
)
// RoundTripperFunc callable definition
type RoundTripperFunc func(*http.Request) (*http.Response, error)
// RoundTrip calls RoundTripperFunc
func (fn RoundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) {
return fn(req)
}
// MockedHTTPRequest mock http requests
type MockedHTTPRequest struct {
method string
path string
response string
query map[string]string
}
func (m MockedHTTPRequest) String() string {
return fmt.Sprintf("%s: %s", m.method, m.path)
}
// NewMockedHTTPRequest return instance of MockedHTTPRequest
func NewMockedHTTPRequest(method string, path string, response string) MockedHTTPRequest {
return MockedHTTPRequest{method: method, path: path, response: response}
}
// NewMockedHTTPRequestWithQuery return instance of MockedHTTPRequest with query
func NewMockedHTTPRequestWithQuery(method string, path string, response string, query map[string]string) MockedHTTPRequest {
return MockedHTTPRequest{method: method, path: path, response: response, query: query}
}
func (m MockedHTTPRequest) register() {
url := fmt.Sprintf("=~%s", m.path)
httpmock.RegisterResponder(m.method, url, func(request *http.Request) (*http.Response, error) {
logRequest(request)
return m.mockRequest(request)
})
}
func logRequest(r *http.Request) {
if glog.V(4) {
dump, err := httputil.DumpRequest(r, true)
if err != nil {
glog.Warningf("Could not dump http request for %s: %s", r.URL.Path, err)
} else {
glog.Infof("Mock HTTP request dump:\n %s", string(dump))
}
} else {
method := r.Method
if method == "" {
method = " GET"
}
glog.Infof("Processing Mock HTTP request %s %s", method, r.URL.Path)
}
}
func (m *MockedHTTPRequest) mockRequest(req *http.Request) (*http.Response, error) {
resp, err := http.ReadResponse(bufio.NewReader(strings.NewReader(m.response)), req)
if err != nil {
return nil, err
}
return resp, nil
}
// HTTPMockHandler handles requests
type HTTPMockHandler struct {
}
// NewHTTPMockHandler return instance of HTTPMockHandler
func NewHTTPMockHandler() *HTTPMockHandler {
return &HTTPMockHandler{}
}
// Stop reset transport
func (h *HTTPMockHandler) Stop() {
httpmock.Deactivate()
}
// Cleanup reset transport
func (h *HTTPMockHandler) Cleanup() {
httpmock.Reset()
}
// register one or more MockedHTTPRequest
func (h *HTTPMockHandler) Register(httpMocks ...MockedHTTPRequest) {
for _, httpMock := range httpMocks {
httpMock.register()
}
}
// Sniff return response
func (h *HTTPMockHandler) Sniff() {
http.DefaultTransport = RoundTripperFunc(func(req *http.Request) (*http.Response, error) {
return h.dumpRequestResponseWithTransport(req, httpmock.InitialTransport)
})
}
// Start handling request
func (h *HTTPMockHandler) Start() {
httpmock.Activate()
}
// RegisterLocalServer set local server
func (h *HTTPMockHandler) RegisterLocalServer(localServer string, methods ...string) {
url := "=~^" + localServer
if len(methods) == 0 {
methods = []string{"GET", "POST", "PATCH"}
}
for _, m := range methods {
httpmock.RegisterResponder(m, url, func(request *http.Request) (*http.Response, error) {
return httpmock.InitialTransport.RoundTrip(request)
})
}
}
func (h *HTTPMockHandler) dumpRequestResponseWithTransport(req *http.Request, bkpDefaultTransport http.RoundTripper) (*http.Response, error) {
h.dumpRequest(req)
response, err := bkpDefaultTransport.RoundTrip(req)
if err != nil {
return nil, fmt.Errorf("error during http round trip for %s: %s", req.URL.Path, err)
}
h.dumpResponse(response, req)
return response, nil
}
func (h *HTTPMockHandler) dumpRequest(req *http.Request) {
dump, err := httputil.DumpRequest(req, true)
if err != nil {
glog.Warningf("Could not dump http request for %s: %s", req.URL.Path, err)
} else {
glog.Infof("HTTP request dump:\n %s", string(dump))
}
}
func (h *HTTPMockHandler) dumpResponse(response *http.Response, req *http.Request) {
dump, err := httputil.DumpResponse(response, true)
if err != nil {
glog.Warningf("Could not dump http response for %s: %s", req.URL.Path, err)
} else {
glog.Infof("HTTP response dump:\n %s", string(dump))
}
}