-
Notifications
You must be signed in to change notification settings - Fork 222
Expand file tree
/
Copy pathlocal_middleware.go
More file actions
115 lines (100 loc) · 3.23 KB
/
local_middleware.go
File metadata and controls
115 lines (100 loc) · 3.23 KB
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
package middleware
import (
"bytes"
"encoding/json"
"os/exec"
"github.com/SpectoLabs/hoverfly/core/models"
log "github.com/sirupsen/logrus"
)
// ExecuteMiddleware - takes command (middleware string) and payload, which is passed to middleware
func (this Middleware) executeMiddlewareLocally(pair models.RequestResponsePair) (models.RequestResponsePair, error) {
var middlewareCommand *exec.Cmd
if this.Script == nil {
middlewareCommand = exec.Command(this.Binary)
} else {
middlewareCommand = exec.Command(this.Binary, this.Script.Name())
}
pairViewBytes, err := json.Marshal(pair.ConvertToRequestResponsePairView())
if err != nil {
return pair, &MiddlewareError{
OriginalError: err,
Message: "Failed to marshal request to JSON",
}
}
log.WithFields(log.Fields{
"command": this.toString(),
"stdin": string(pairViewBytes),
}).Info("Preparing to execute local middleware")
var stdout bytes.Buffer
var stderr bytes.Buffer
// Redirect standard streams
middlewareCommand.Stdin = bytes.NewReader(pairViewBytes)
middlewareCommand.Stdout = &stdout
middlewareCommand.Stderr = &stderr
if err := middlewareCommand.Start(); err != nil {
log.WithFields(log.Fields{
"sdtdout": string(stdout.Bytes()),
"sdtderr": string(stderr.Bytes()),
"error": err.Error(),
}).Error("Middleware failed to start")
return pair, &MiddlewareError{
OriginalError: err,
Message: "Middleware failed to start",
Command: this.toString(),
Stdin: string(pairViewBytes),
Stdout: string(stdout.Bytes()),
Stderr: string(stderr.Bytes()),
}
}
if err := middlewareCommand.Wait(); err != nil {
log.WithFields(log.Fields{
"command": this.toString(),
"stdin": string(pairViewBytes),
"sdtdout": string(stdout.Bytes()),
"sdtderr": string(stderr.Bytes()),
"error": err.Error(),
}).Error("Middleware failed")
return pair, &MiddlewareError{
OriginalError: err,
Message: "Middleware failed",
Command: this.toString(),
Stdin: string(pairViewBytes),
Stdout: string(stdout.Bytes()),
Stderr: string(stderr.Bytes()),
}
}
// log stderr, middleware executed successfully
if len(stderr.Bytes()) > 0 {
log.WithFields(log.Fields{
"sdtderr": string(stderr.Bytes()),
}).Info("Information from middleware")
}
if len(stdout.Bytes()) > 0 {
var newPairView RequestResponsePairView
err = json.Unmarshal(stdout.Bytes(), &newPairView)
if err != nil {
return pair, &MiddlewareError{
OriginalError: err,
Message: "Failed to unmarshal JSON from middleware",
Command: this.toString(),
Stdin: string(pairViewBytes),
Stdout: string(stdout.Bytes()),
Stderr: string(stderr.Bytes()),
}
} else {
if log.GetLevel() == log.DebugLevel {
log.WithFields(log.Fields{
"middleware": this.toString(),
"payload": string(stdout.Bytes()),
}).Debug("payload after modifications")
}
// payload unmarshalled into RequestResponsePair struct, returning it
return models.NewRequestResponsePairFromRequestResponsePairView(newPairView), nil
}
} else {
log.WithFields(log.Fields{
"stdout": string(stdout.Bytes()),
}).Warn("No response from middleware.")
}
return pair, nil
}