-
Notifications
You must be signed in to change notification settings - Fork 0
/
collector.go
119 lines (111 loc) · 2.83 KB
/
collector.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
package schemedetector
import (
"os"
"regexp"
"sort"
"strings"
"github.com/asaskevich/govalidator"
log "github.com/sirupsen/logrus"
)
func FromEnv() []*Scheme {
envs := map[string]string{}
for _, envStr := range os.Environ() {
splitted := strings.SplitN(envStr, "=", 2)
log.Debugf("env: %+v", splitted)
envs[splitted[0]] = splitted[1]
}
return FromMap(envs)
}
// skipcq: GO-R1005
func FromMap(input map[string]string) []*Scheme {
var result []*Scheme
var procceed []string
keys := mapToKeys(filterMap(input))
for _, k := range keys {
log.Debugf("parse: key='%s' value='%v'", k.name, k.value)
if stringInArray(k.name, procceed) {
continue
}
item := newScheme()
// collect all simillar keys
group := k.findSimilars(keys)
log.Debugf("parse: group='%v'", group)
// search for URI in keys
for _, k := range group {
parsed := k.uri
if parsed == nil {
log.Debugf("parse: k='%v' is not URL", k)
continue
}
log.Debugf("parse: k='%v' is URL %v", k, parsed.Hostname())
item.setEngine(parsed.Scheme)
item.setHost(parsed.Hostname())
item.setPort(parsed.Port())
item.setPath(parsed.Path)
item.setUsername(parsed.User.Username())
item.setArguments(parsed.RawQuery)
if p, hasPass := parsed.User.Password(); hasPass {
item.setPassword(p)
}
log.Debugf("procceed+='%s'", k.name)
procceed = append(procceed, k.name)
}
// search parameters in other keys
for _, k := range group {
log.Debugf("parse:2 '%s'", k.name)
if stringInArray(k.name, procceed) {
log.Debugf("parse:2 '%s' already proceed", k.name)
continue
}
if k.hints.host && govalidator.IsDNSName(k.value) || govalidator.IsIP(k.value) {
item.setHost(k.value)
} else if k.hints.port && govalidator.IsPort(k.value) {
item.setPort(k.value)
} else if k.hints.user {
item.setUsername(k.value)
} else if k.hints.pass {
item.setPassword(k.value)
} else if k.hints.path {
item.setPath(k.value)
}
}
item.guessMissed()
if item.isFull() {
for _, k := range group {
log.Debugf("procceed+='%s'", k.name)
procceed = append(procceed, k.name)
}
log.Debugf("parse: Succeed group %v", group)
log.Debugf("parse: RESULT '%s'", item)
result = append(result, item)
}
}
return result
}
func mapToKeys(input map[string]string) []*key {
var keys []string
for k := range input {
keys = append(keys, k)
}
sort.Strings(keys)
var result []*key
for _, k := range keys {
v := input[k]
result = append(result, newKey(k, v))
}
return result
}
func filterMap(input map[string]string) map[string]string {
excludeRegexp := os.Getenv("SCHEME_DETECTOR_EXCLUDE")
if excludeRegexp == "" {
return input
}
filter := regexp.MustCompile(excludeRegexp)
filtered := map[string]string{}
for k, v := range input {
if !filter.Match([]byte(k)) {
filtered[k] = v
}
}
return filtered
}