Skip to content

Commit feb7bd2

Browse files
author
Karolis Rusenas
committed
Merge pull request #53 from SpectoLabs/develop
Develop
2 parents 2ea4306 + 5460a5e commit feb7bd2

File tree

7 files changed

+117
-63
lines changed

7 files changed

+117
-63
lines changed

admin.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ func (d *DBClient) startAdminInterface() {
3939

4040
// admin interface starting message
4141
log.WithFields(log.Fields{
42-
"AdminPort": AppConfig.adminInterface,
42+
"AdminPort": d.cfg.adminInterface,
4343
}).Info("Admin interface is starting...")
4444

45-
n.Run(AppConfig.adminInterface)
45+
n.Run(d.cfg.adminInterface)
4646
}
4747

4848
// getBoneRouter returns mux for admin interface
@@ -197,8 +197,8 @@ func (d *DBClient) DeleteAllRecordsHandler(w http.ResponseWriter, req *http.Requ
197197
// CurrentStateHandler returns current state
198198
func (d *DBClient) CurrentStateHandler(w http.ResponseWriter, req *http.Request) {
199199
var resp StateRequest
200-
resp.Mode = AppConfig.mode
201-
resp.Destination = AppConfig.destination
200+
resp.Mode = d.cfg.GetMode()
201+
resp.Destination = d.cfg.destination
202202

203203
b, _ := json.Marshal(resp)
204204
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
@@ -228,17 +228,33 @@ func (d *DBClient) stateHandler(w http.ResponseWriter, r *http.Request) {
228228
w.WriteHeader(422) // can't process this entity
229229
return
230230
}
231+
232+
availableModes := map[string]bool{
233+
"virtualize": true,
234+
"capture": true,
235+
"modify": true,
236+
"synthesize": true,
237+
}
238+
239+
if !availableModes[stateRequest.Mode] {
240+
log.WithFields(log.Fields{
241+
"suppliedMode": stateRequest.Mode,
242+
}).Error("Wrong mode found, can't change state")
243+
http.Error(w, "Bad mode supplied, available modes: virtualize, capture, modify, synthesize.", 400)
244+
return
245+
}
246+
231247
log.WithFields(log.Fields{
232248
"newState": stateRequest.Mode,
233249
"body": string(body),
234250
}).Info("Handling state change request!")
235251

236252
// setting new state
237-
AppConfig.mode = stateRequest.Mode
253+
d.cfg.SetMode(stateRequest.Mode)
238254

239255
var resp StateRequest
240-
resp.Mode = stateRequest.Mode
241-
resp.Destination = AppConfig.destination
256+
resp.Mode = d.cfg.GetMode()
257+
resp.Destination = d.cfg.destination
242258
b, _ := json.Marshal(resp)
243259
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
244260
w.Write(b)

cache.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// redis cache backend implementation for persistent storage
2-
31
package main
42

53
import (
@@ -20,7 +18,6 @@ type Cache struct {
2018
func getDB(name string) *bolt.DB {
2119
log.WithFields(log.Fields{
2220
"databaseName": name,
23-
"Mode": AppConfig.mode,
2421
}).Info("Initiating database")
2522
db, err := bolt.Open(name, 0600, nil)
2623
if err != nil {

hoverfly.go

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,12 @@ import (
66

77
"bufio"
88
"flag"
9-
"fmt"
109
"net"
1110
"net/http"
1211
"os"
1312
"regexp"
1413
)
1514

16-
const DefaultPort = ":8500"
17-
1815
// modes
1916
const VirtualizeMode = "virtualize"
2017
const SynthesizeMode = "synthesize"
@@ -46,16 +43,17 @@ func main() {
4643
middleware := flag.String("middleware", "", "should proxy use middleware")
4744
flag.Parse()
4845

46+
// getting settings
47+
cfg := InitSettings()
48+
4949
if *verbose {
5050
// Only log the warning severity or above.
5151
log.SetLevel(log.DebugLevel)
5252
}
53-
54-
// getting settings
55-
initSettings()
53+
cfg.verbose = *verbose
5654

5755
// overriding default middleware setting
58-
AppConfig.middleware = *middleware
56+
cfg.middleware = *middleware
5957

6058
// setting default mode
6159
mode := VirtualizeMode
@@ -69,7 +67,7 @@ func main() {
6967
} else if *synthesize {
7068
mode = SynthesizeMode
7169

72-
if AppConfig.middleware == "" {
70+
if cfg.middleware == "" {
7371
log.Fatal("Synthesize mode chosen although middleware not supplied")
7472
}
7573

@@ -79,7 +77,7 @@ func main() {
7977
} else if *modify {
8078
mode = ModifyMode
8179

82-
if AppConfig.middleware == "" {
80+
if cfg.middleware == "" {
8381
log.Fatal("Modify mode chosen although middleware not supplied")
8482
}
8583

@@ -89,22 +87,22 @@ func main() {
8987
}
9088

9189
// overriding default settings
92-
AppConfig.mode = mode
90+
cfg.mode = mode
9391

9492
// overriding destination
95-
AppConfig.destination = *destination
93+
cfg.destination = *destination
9694

97-
// getting default database
98-
port := os.Getenv("ProxyPort")
99-
if port == "" {
100-
port = DefaultPort
101-
} else {
102-
port = fmt.Sprintf(":%s", port)
103-
}
95+
proxy, dbClient := getNewHoverfly(cfg)
96+
defer dbClient.cache.db.Close()
97+
98+
log.Warn(http.ListenAndServe(cfg.proxyPort, proxy))
99+
}
100+
101+
// getNewHoverfly returns a configured ProxyHttpServer and DBClient, also starts admin interface on configured port
102+
func getNewHoverfly(cfg *Configuration) (*goproxy.ProxyHttpServer, DBClient) {
104103

105104
// getting boltDB
106-
db := getDB(AppConfig.databaseName)
107-
defer db.Close()
105+
db := getDB(cfg.databaseName)
108106

109107
cache := Cache{
110108
db: db,
@@ -115,16 +113,17 @@ func main() {
115113
d := DBClient{
116114
cache: cache,
117115
http: &http.Client{},
116+
cfg: cfg,
118117
}
119118

120119
// creating proxy
121120
proxy := goproxy.NewProxyHttpServer()
122121

123-
proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile("^.*$"))).
122+
proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile(d.cfg.destination))).
124123
HandleConnect(goproxy.AlwaysMitm)
125124

126125
// enable curl -p for all hosts on port 80
127-
proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile(*destination))).
126+
proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile(d.cfg.destination))).
128127
HijackConnect(func(req *http.Request, client net.Conn, ctx *goproxy.ProxyCtx) {
129128
defer func() {
130129
if e := recover(); e != nil {
@@ -151,29 +150,30 @@ func main() {
151150
})
152151

153152
// processing connections
154-
proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile(*destination))).DoFunc(
153+
proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile(cfg.destination))).DoFunc(
155154
func(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
156155
return d.processRequest(r)
157156
})
158157

159158
go d.startAdminInterface()
160159

161-
proxy.Verbose = *verbose
160+
proxy.Verbose = d.cfg.verbose
162161
// proxy starting message
163162
log.WithFields(log.Fields{
164-
"Destination": *destination,
165-
"ProxyPort": port,
166-
"Mode": AppConfig.mode,
167-
}).Info("Proxy is starting...")
163+
"Destination": d.cfg.destination,
164+
"ProxyPort": d.cfg.proxyPort,
165+
"Mode": d.cfg.GetMode(),
166+
}).Info("Proxy prepared...")
168167

169-
log.Warn(http.ListenAndServe(port, proxy))
168+
return proxy, d
170169
}
171170

172171
// processRequest - processes incoming requests and based on proxy state (record/playback)
173172
// returns HTTP response.
174173
func (d *DBClient) processRequest(req *http.Request) (*http.Request, *http.Response) {
175174

176-
if AppConfig.mode == CaptureMode {
175+
mode := d.cfg.GetMode()
176+
if mode == CaptureMode {
177177
log.Info("*** Capture ***")
178178
newResponse, err := d.captureRequest(req)
179179
if err != nil {
@@ -184,19 +184,19 @@ func (d *DBClient) processRequest(req *http.Request) (*http.Request, *http.Respo
184184
return req, newResponse
185185
}
186186

187-
} else if AppConfig.mode == SynthesizeMode {
187+
} else if mode == SynthesizeMode {
188188
log.Info("*** Sinthesize ***")
189-
response := synthesizeResponse(req, AppConfig.middleware)
189+
response := synthesizeResponse(req, d.cfg.middleware)
190190
return req, response
191191

192-
} else if AppConfig.mode == ModifyMode {
192+
} else if mode == ModifyMode {
193193
log.Info("*** Modify ***")
194-
response, err := d.modifyRequestResponse(req, AppConfig.middleware)
194+
response, err := d.modifyRequestResponse(req, d.cfg.middleware)
195195

196196
if err != nil {
197197
log.WithFields(log.Fields{
198198
"error": err.Error(),
199-
"middleware": AppConfig.middleware,
199+
"middleware": d.cfg.middleware,
200200
}).Error("Got error when performing request modification")
201201
return req, nil
202202
}

manipulation.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ func (c *Constructor) ApplyMiddleware(middleware string) error {
2525
if err != nil {
2626
log.WithFields(log.Fields{
2727
"error": err.Error(),
28-
"middleware": AppConfig.middleware,
28+
"middleware": middleware,
2929
}).Error("Error during middleware transformation, not modifying payload!")
3030

3131
return err
3232
} else {
3333

3434
log.WithFields(log.Fields{
35-
"middleware": AppConfig.middleware,
35+
"middleware": middleware,
3636
}).Info("Middleware transformation complete!")
3737
// override payload with transformed new payload
3838
c.payload = newPayload

models.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ import (
1313
"io/ioutil"
1414
)
1515

16+
// DBClient provides access to cache, http client and configuration
1617
type DBClient struct {
1718
cache Cache
1819
http *http.Client
20+
cfg *Configuration
1921
}
2022

2123
// request holds structure for request
@@ -73,7 +75,6 @@ func (d *DBClient) captureRequest(req *http.Request) (*http.Response, error) {
7375
if err != nil {
7476
log.WithFields(log.Fields{
7577
"error": err.Error(),
76-
"mode": AppConfig.mode,
7778
}).Error("Got error when reading request body")
7879
}
7980
log.WithFields(log.Fields{
@@ -139,11 +140,11 @@ func (d *DBClient) doRequest(request *http.Request) (*http.Response, error) {
139140
// We can't have this set. And it only contains "/pkg/net/http/" anyway
140141
request.RequestURI = ""
141142

142-
if AppConfig.middleware != "" {
143+
if d.cfg.middleware != "" {
143144
var payload Payload
144145

145146
c := NewConstructor(request, payload)
146-
c.ApplyMiddleware(AppConfig.middleware)
147+
c.ApplyMiddleware(d.cfg.middleware)
147148

148149
request = c.reconstructRequest()
149150

@@ -250,8 +251,8 @@ func (d *DBClient) getResponse(req *http.Request) *http.Response {
250251

251252
c := NewConstructor(req, payload)
252253

253-
if AppConfig.middleware != "" {
254-
_ = c.ApplyMiddleware(AppConfig.middleware)
254+
if d.cfg.middleware != "" {
255+
_ = c.ApplyMiddleware(d.cfg.middleware)
255256
}
256257

257258
response := c.reconstructResponse()
@@ -260,15 +261,13 @@ func (d *DBClient) getResponse(req *http.Request) *http.Response {
260261
"key": key,
261262
"status": payload.Response.Status,
262263
"bodyLength": response.ContentLength,
263-
"mode": AppConfig.mode,
264264
}).Info("Response found, returning")
265265

266266
return response
267267

268268
} else {
269269
log.WithFields(log.Fields{
270270
"error": err.Error(),
271-
"mode": AppConfig.mode,
272271
"query": req.URL.RawQuery,
273272
"path": req.URL.RawPath,
274273
"destination": req.Host,
@@ -324,7 +323,6 @@ func (d *DBClient) modifyRequestResponse(req *http.Request, middleware string) (
324323
log.WithFields(log.Fields{
325324
"status": newResponse.StatusCode,
326325
"middleware": middleware,
327-
"mode": AppConfig.mode,
328326
}).Info("Response modified, returning")
329327

330328
return newResponse, nil

0 commit comments

Comments
 (0)