Skip to content

Commit 2b9652d

Browse files
Merge pull request #258 from SpectoLabs/refactoring
Refactoring around Hoverfly.processRequest
2 parents 560939b + 0c6b86a commit 2b9652d

21 files changed

+263
-276
lines changed

core/admin.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1026,7 +1026,7 @@ func (d *Hoverfly) DeleteAllResponseDelaysHandler(w http.ResponseWriter, req *ht
10261026
}
10271027

10281028
func (d *Hoverfly) UpdateResponseDelaysHandler(w http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
1029-
var rd models.ResponseDelayJson
1029+
var rd models.ResponseDelayPayload
10301030
var mr messageResponse
10311031

10321032
if req.Body == nil {

core/admin_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -943,7 +943,7 @@ func TestGetResponseDelays(t *testing.T) {
943943

944944
body, err := ioutil.ReadAll(rec.Body)
945945

946-
sr := models.ResponseDelayJson{}
946+
sr := models.ResponseDelayPayload{}
947947
err = json.Unmarshal(body, &sr)
948948

949949
// normal equality checking doesn't work on slices (!!)
@@ -992,7 +992,7 @@ func TestUpdateResponseDelays(t *testing.T) {
992992
Delay: 100,
993993
}
994994
delays := models.ResponseDelayList{delayOne, delayTwo}
995-
delayJson := models.ResponseDelayJson{Data: &delays}
995+
delayJson := models.ResponseDelayPayload{Data: &delays}
996996
delayJsonBytes, err := json.Marshal(&delayJson)
997997
Expect(err).To(BeNil())
998998

core/hoverfly.go

+33-71
Original file line numberDiff line numberDiff line change
@@ -195,15 +195,22 @@ func hoverflyError(req *http.Request, err error, msg string, statusCode int) *ht
195195

196196
// processRequest - processes incoming requests and based on proxy state (record/playback)
197197
// returns HTTP response.
198-
func (hf *Hoverfly) processRequest(req *http.Request) (*http.Request, *http.Response) {
198+
func (hf *Hoverfly) processRequest(req *http.Request) *http.Response {
199+
var response *http.Response
199200

200201
mode := hf.Cfg.GetMode()
201202

203+
requestDetails, err := models.NewRequestDetailsFromHttpRequest(req)
204+
if err != nil {
205+
return hoverflyError(req, err, "Could not interpret HTTP request", http.StatusServiceUnavailable)
206+
}
207+
202208
if mode == CaptureMode {
203-
newResponse, err := hf.captureRequest(req)
209+
var err error
210+
response, err = hf.captureRequest(req)
204211

205212
if err != nil {
206-
return req, hoverflyError(req, err, "Could not capture request", http.StatusServiceUnavailable)
213+
return hoverflyError(req, err, "Could not capture request", http.StatusServiceUnavailable)
207214
}
208215
log.WithFields(log.Fields{
209216
"mode": mode,
@@ -214,13 +221,14 @@ func (hf *Hoverfly) processRequest(req *http.Request) (*http.Request, *http.Resp
214221
"destination": req.Host,
215222
}).Info("request and response captured")
216223

217-
return req, newResponse
224+
return response
218225

219226
} else if mode == SynthesizeMode {
220-
response, err := SynthesizeResponse(req, hf.Cfg.Middleware)
227+
var err error
228+
response, err = SynthesizeResponse(req, requestDetails, hf.Cfg.Middleware)
221229

222230
if err != nil {
223-
return req, hoverflyError(req, err, "Could not create synthetic response!", http.StatusServiceUnavailable)
231+
return hoverflyError(req, err, "Could not create synthetic response!", http.StatusServiceUnavailable)
224232
}
225233

226234
log.WithFields(log.Fields{
@@ -232,41 +240,32 @@ func (hf *Hoverfly) processRequest(req *http.Request) (*http.Request, *http.Resp
232240
"destination": req.Host,
233241
}).Info("synthetic response created successfuly")
234242

235-
respDelay := hf.ResponseDelays.GetDelay(req.URL.String(), req.Method)
236-
if respDelay != nil {
237-
respDelay.Execute()
238-
}
239-
240-
return req, response
241-
242243
} else if mode == ModifyMode {
243-
244-
response, err := hf.modifyRequestResponse(req, hf.Cfg.Middleware)
244+
var err error
245+
response, err = hf.modifyRequestResponse(req, requestDetails, hf.Cfg.Middleware)
245246

246247
if err != nil {
247248
log.WithFields(log.Fields{
248249
"error": err.Error(),
249250
"middleware": hf.Cfg.Middleware,
250251
}).Error("Got error when performing request modification")
251-
return req, hoverflyError(
252-
req,
253-
err,
254-
fmt.Sprintf("Middleware (%s) failed or something else happened!", hf.Cfg.Middleware),
255-
http.StatusServiceUnavailable)
252+
return hoverflyError(req, err, fmt.Sprintf("Middleware (%s) failed or something else happened!", hf.Cfg.Middleware), http.StatusServiceUnavailable)
256253
}
257254

258-
respDelay := hf.ResponseDelays.GetDelay(req.URL.String(), req.Method)
259-
if respDelay != nil {
260-
respDelay.Execute()
255+
} else {
256+
var err *matching.MatchingError
257+
response, err = hf.getResponse(req, requestDetails)
258+
if err != nil {
259+
return hoverflyError(req, err, err.Error(), err.StatusCode)
261260
}
262-
263-
// returning modified response
264-
return req, response
265261
}
266262

267-
newResponse := hf.getResponse(req)
263+
respDelay := hf.ResponseDelays.GetDelay(requestDetails)
264+
if respDelay != nil {
265+
respDelay.Execute()
266+
}
268267

269-
return req, newResponse
268+
return response
270269

271270
}
272271

@@ -344,7 +343,7 @@ func (hf *Hoverfly) doRequest(request *http.Request) (*http.Request, *http.Respo
344343
// middleware is provided, modifying request
345344
var requestResponsePair models.RequestResponsePair
346345

347-
rd, err := getRequestDetails(request)
346+
rd, err := models.NewRequestDetailsFromHttpRequest(request)
348347
if err != nil {
349348
return nil, nil, err
350349
}
@@ -404,33 +403,11 @@ func (hf *Hoverfly) doRequest(request *http.Request) (*http.Request, *http.Respo
404403
}
405404

406405
// getResponse returns stored response from cache
407-
func (hf *Hoverfly) getResponse(req *http.Request) *http.Response {
408-
409-
if req.Body == nil {
410-
req.Body = ioutil.NopCloser(bytes.NewBuffer([]byte("")))
411-
}
412-
413-
reqBody, err := ioutil.ReadAll(req.Body)
414-
415-
if err != nil {
416-
log.WithFields(log.Fields{
417-
"error": err.Error(),
418-
}).Error("Got error when reading request body")
419-
}
420-
421-
requestDetails := models.RequestDetails{
422-
Path: req.URL.Path,
423-
Method: req.Method,
424-
Destination: req.Host,
425-
Scheme: req.URL.Scheme,
426-
Query: req.URL.RawQuery,
427-
Body: string(reqBody),
428-
Headers: req.Header,
429-
}
406+
func (hf *Hoverfly) getResponse(req *http.Request, requestDetails models.RequestDetails) (*http.Response, *matching.MatchingError) {
430407

431408
responseDetails, matchErr := hf.RequestMatcher.GetResponse(&requestDetails)
432409
if matchErr != nil {
433-
return hoverflyError(req, matchErr, matchErr.Error(), matchErr.StatusCode)
410+
return nil, matchErr
434411
}
435412

436413
pair := &models.RequestResponsePair{
@@ -443,27 +420,12 @@ func (hf *Hoverfly) getResponse(req *http.Request) *http.Response {
443420
_ = c.ApplyMiddleware(hf.Cfg.Middleware)
444421
}
445422

446-
respDelay := hf.ResponseDelays.GetDelay(req.URL.String(), req.Method)
447-
if respDelay != nil {
448-
respDelay.Execute()
449-
}
450-
451-
return c.ReconstructResponse()
423+
return c.ReconstructResponse(), nil
452424
}
453425

454426
// modifyRequestResponse modifies outgoing request and then modifies incoming response, neither request nor response
455427
// is saved to cache.
456-
func (hf *Hoverfly) modifyRequestResponse(req *http.Request, middleware string) (*http.Response, error) {
457-
458-
// getting request details
459-
rd, err := getRequestDetails(req)
460-
if err != nil {
461-
log.WithFields(log.Fields{
462-
"error": err.Error(),
463-
"middleware": middleware,
464-
}).Error("Failed to get request details")
465-
return nil, err
466-
}
428+
func (hf *Hoverfly) modifyRequestResponse(req *http.Request, requestDetails models.RequestDetails, middleware string) (*http.Response, error) {
467429

468430
// modifying request
469431
req, resp, err := hf.doRequest(req)
@@ -489,7 +451,7 @@ func (hf *Hoverfly) modifyRequestResponse(req *http.Request, middleware string)
489451
Headers: resp.Header,
490452
}
491453

492-
requestResponsePair := models.RequestResponsePair{Response: r, Request: rd}
454+
requestResponsePair := models.RequestResponsePair{Response: r, Request: requestDetails}
493455

494456
c := NewConstructor(req, requestResponsePair)
495457
// applying middleware to modify response

core/hoverfly_test.go

+14-19
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,8 @@ func TestProcessCaptureRequest(t *testing.T) {
6363

6464
dbClient.Cfg.SetMode("capture")
6565

66-
req, resp := dbClient.processRequest(r)
66+
resp := dbClient.processRequest(r)
6767

68-
Expect(req).ToNot(BeNil())
6968
Expect(resp).ToNot(BeNil())
7069
Expect(resp.StatusCode).To(Equal(http.StatusCreated))
7170
}
@@ -82,17 +81,15 @@ func TestProcessSimulateRequest(t *testing.T) {
8281

8382
// capturing
8483
dbClient.Cfg.SetMode("capture")
85-
req, resp := dbClient.processRequest(r)
84+
resp := dbClient.processRequest(r)
8685

87-
Expect(req).ToNot(BeNil())
8886
Expect(resp).ToNot(BeNil())
8987
Expect(resp.StatusCode).To(Equal(http.StatusCreated))
9088

9189
// virtualizing
9290
dbClient.Cfg.SetMode(SimulateMode)
93-
newReq, newResp := dbClient.processRequest(r)
91+
newResp := dbClient.processRequest(r)
9492

95-
Expect(newReq).ToNot(BeNil())
9693
Expect(newResp).ToNot(BeNil())
9794
Expect(newResp.StatusCode).To(Equal(http.StatusCreated))
9895
}
@@ -113,9 +110,8 @@ func TestProcessSynthesizeRequest(t *testing.T) {
113110
Expect(err).To(BeNil())
114111

115112
dbClient.Cfg.SetMode(SynthesizeMode)
116-
newReq, newResp := dbClient.processRequest(r)
113+
newResp := dbClient.processRequest(r)
117114

118-
Expect(newReq).ToNot(BeNil())
119115
Expect(newResp).ToNot(BeNil())
120116
Expect(newResp.StatusCode).To(Equal(http.StatusOK))
121117
b, err := ioutil.ReadAll(newResp.Body)
@@ -136,9 +132,8 @@ func TestProcessModifyRequest(t *testing.T) {
136132
Expect(err).To(BeNil())
137133

138134
dbClient.Cfg.SetMode(ModifyMode)
139-
newReq, newResp := dbClient.processRequest(r)
135+
newResp := dbClient.processRequest(r)
140136

141-
Expect(newReq).ToNot(BeNil())
142137
Expect(newResp).ToNot(BeNil())
143138

144139
Expect(newResp.StatusCode).To(Equal(http.StatusAccepted))
@@ -168,7 +163,7 @@ func (this *ResponseDelayListStub) Len() int {
168163
return this.Len()
169164
}
170165

171-
func (this *ResponseDelayListStub) GetDelay(urlPattern, httpMethod string) *models.ResponseDelay {
166+
func (this *ResponseDelayListStub) GetDelay(request models.RequestDetails) *models.ResponseDelay {
172167
this.gotDelays++
173168
return nil
174169
}
@@ -185,7 +180,7 @@ func TestDelayAppliedToSuccessfulSimulateRequest(t *testing.T) {
185180

186181
// capturing
187182
dbClient.Cfg.SetMode("capture")
188-
_, resp := dbClient.processRequest(r)
183+
resp := dbClient.processRequest(r)
189184

190185
Expect(resp.StatusCode).To(Equal(http.StatusCreated))
191186

@@ -195,7 +190,7 @@ func TestDelayAppliedToSuccessfulSimulateRequest(t *testing.T) {
195190
stub := ResponseDelayListStub{}
196191
dbClient.ResponseDelays = &stub
197192

198-
_, newResp := dbClient.processRequest(r)
193+
newResp := dbClient.processRequest(r)
199194

200195
Expect(newResp.StatusCode).To(Equal(http.StatusCreated))
201196

@@ -217,7 +212,7 @@ func TestDelayNotAppliedToFailedSimulateRequest(t *testing.T) {
217212
stub := ResponseDelayListStub{}
218213
dbClient.ResponseDelays = &stub
219214

220-
_, newResp := dbClient.processRequest(r)
215+
newResp := dbClient.processRequest(r)
221216

222217
Expect(newResp.StatusCode).To(Equal(http.StatusPreconditionFailed))
223218

@@ -239,7 +234,7 @@ func TestDelayNotAppliedToCaptureRequest(t *testing.T) {
239234
stub := ResponseDelayListStub{}
240235
dbClient.ResponseDelays = &stub
241236

242-
_, resp := dbClient.processRequest(r)
237+
resp := dbClient.processRequest(r)
243238

244239
Expect(resp.StatusCode).To(Equal(http.StatusCreated))
245240

@@ -265,7 +260,7 @@ func TestDelayAppliedToSynthesizeRequest(t *testing.T) {
265260

266261
stub := ResponseDelayListStub{}
267262
dbClient.ResponseDelays = &stub
268-
_, newResp := dbClient.processRequest(r)
263+
newResp := dbClient.processRequest(r)
269264

270265
Expect(newResp.StatusCode).To(Equal(http.StatusOK))
271266

@@ -291,7 +286,7 @@ func TestDelayNotAppliedToFailedSynthesizeRequest(t *testing.T) {
291286

292287
stub := ResponseDelayListStub{}
293288
dbClient.ResponseDelays = &stub
294-
_, newResp := dbClient.processRequest(r)
289+
newResp := dbClient.processRequest(r)
295290

296291
Expect(newResp.StatusCode).To(Equal(http.StatusServiceUnavailable))
297292

@@ -314,7 +309,7 @@ func TestDelayAppliedToModifyRequest(t *testing.T) {
314309

315310
stub := ResponseDelayListStub{}
316311
dbClient.ResponseDelays = &stub
317-
_, newResp := dbClient.processRequest(r)
312+
newResp := dbClient.processRequest(r)
318313

319314
Expect(newResp.StatusCode).To(Equal(http.StatusAccepted))
320315

@@ -337,7 +332,7 @@ func TestDelayNotAppliedToFailedModifyRequest(t *testing.T) {
337332

338333
stub := ResponseDelayListStub{}
339334
dbClient.ResponseDelays = &stub
340-
_, newResp := dbClient.processRequest(r)
335+
newResp := dbClient.processRequest(r)
341336

342337
Expect(newResp.StatusCode).To(Equal(503))
343338

core/import.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import (
1313
log "github.com/Sirupsen/logrus"
1414
"github.com/SpectoLabs/hoverfly/core/matching"
1515
"github.com/SpectoLabs/hoverfly/core/models"
16-
"github.com/SpectoLabs/hoverfly/core/views"
1716
. "github.com/SpectoLabs/hoverfly/core/util"
17+
"github.com/SpectoLabs/hoverfly/core/views"
1818
"net/http"
1919
)
2020

@@ -138,18 +138,18 @@ func (hf *Hoverfly) ImportRequestResponsePairViews(pairViews []views.RequestResp
138138
responseDetails := models.NewResponseDetailsFromResponseDetailsView(pairView.Response)
139139

140140
requestTemplate := matching.RequestTemplate{
141-
Path: pairView.Request.Path,
142-
Method: pairView.Request.Method,
141+
Path: pairView.Request.Path,
142+
Method: pairView.Request.Method,
143143
Destination: pairView.Request.Destination,
144-
Scheme: pairView.Request.Scheme,
145-
Query: pairView.Request.Query,
146-
Body: pairView.Request.Body,
147-
Headers: pairView.Request.Headers,
144+
Scheme: pairView.Request.Scheme,
145+
Query: pairView.Request.Query,
146+
Body: pairView.Request.Body,
147+
Headers: pairView.Request.Headers,
148148
}
149149

150150
requestTemplateResponsePair := matching.RequestTemplateResponsePair{
151151
RequestTemplate: requestTemplate,
152-
Response: responseDetails,
152+
Response: responseDetails,
153153
}
154154

155155
hf.RequestMatcher.TemplateStore = append(hf.RequestMatcher.TemplateStore, requestTemplateResponsePair)

0 commit comments

Comments
 (0)