-
Notifications
You must be signed in to change notification settings - Fork 0
/
types.go
111 lines (96 loc) · 2.54 KB
/
types.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
package apidiff
import (
"bytes"
"fmt"
"hash/fnv"
"net/http"
"sort"
"time"
)
// Options holds shared CLI arguments from user
type Options struct {
Verbose bool
Name string
}
// RecordedSession represents stored API session
type RecordedSession struct {
Name string
Path string
Interactions []RecordedInteraction
Created time.Time
}
// RecordedInteraction represents recorded API interaction
type RecordedInteraction struct {
URL string
Method string
StatusCode int
Stats RequestStats
}
// RequestInteraction represents request info for API interaction
type RequestInteraction struct {
URL string `yaml:"url"`
Method string `yaml:"method"`
StatusCode int `yaml:"status_code"`
Headers http.Header `yaml:"headers"`
Payload string `yaml:"body"`
}
// Fingerprint returns unique signature of request that
// is used for later comparison
func (ri RequestInteraction) Fingerprint() string {
h := fnv.New32a()
var sortedHeaderKeys []string
for k := range ri.Headers {
sortedHeaderKeys = append(sortedHeaderKeys, k)
}
sort.Strings(sortedHeaderKeys)
var headers bytes.Buffer
for _, name := range sortedHeaderKeys {
for _, value := range ri.Headers[name] {
headers.WriteString(name)
headers.WriteString(value)
}
}
fingerprint := fmt.Sprintf(
"%s%s%d%s%s",
ri.URL,
ri.Method,
ri.StatusCode,
headers.String(),
ri.Payload,
)
_, err := h.Write([]byte(fingerprint))
if err != nil {
panic(err)
}
return fmt.Sprint(h.Sum32())
}
// RequestStats hold HTTP stats metrics
type RequestStats struct {
DNSLookup int `yaml:"dns_lookup"`
TCPConnection int `yaml:"tcp_connection"`
TLSHandshake int `yaml:"tls_andshake"`
ServerProcessing int `yaml:"server_processing"`
ContentTransfer int `yaml:"content_transfer"`
}
// Duration returns total time spend on request
func (rs RequestStats) Duration() int {
return rs.DNSLookup + rs.TCPConnection + rs.TLSHandshake + rs.ServerProcessing + rs.ContentTransfer
}
// MatchingRules contains filter to be applied to stored interactions
type MatchingRules struct {
Name string `yaml:"name"`
Value interface{} `yaml:"value"`
}
// RequestInfo contains shared API request details
type RequestInfo struct {
Payload string `yaml:"body"`
Headers http.Header `yaml:"headers"`
}
// Differences represents errors between two interactions
type Differences struct {
URL string
InteractionIndex int
Headers map[string]error
Body map[string]error
Changed bool
}