@@ -9,6 +9,10 @@ import (
9
9
"strings"
10
10
)
11
11
12
+ const (
13
+ NoHostWithFixURL = "host field must included when fixUrl option set"
14
+ )
15
+
12
16
// HostResults /search/all api results
13
17
type HostResults struct {
14
18
Mode string `json:"mode"`
@@ -47,14 +51,24 @@ type SearchOptions struct {
47
51
}
48
52
49
53
// fixHostToUrl 替换host为url
50
- func fixHostToUrl (res [][]string , fields []string , hostIndex int , urlPrefix string ) [][]string {
54
+ func fixHostToUrl (res [][]string , fields []string , hostIndex int , urlPrefix string , protocolIndex int ) [][]string {
55
+
51
56
newRes := make ([][]string , 0 , len (res ))
52
57
for _ , row := range res {
53
58
newRow := make ([]string , 0 , len (fields ))
54
59
for j , r := range row {
55
60
if j == hostIndex {
56
61
if ! strings .Contains (r , "://" ) {
57
- r = urlPrefix + r
62
+ if urlPrefix != "" {
63
+ r = urlPrefix + r
64
+ } else if protocolIndex != - 1 &&
65
+ (row [protocolIndex ] == "socks5" || row [protocolIndex ] == "redis" ||
66
+ row [protocolIndex ] == "http" || row [protocolIndex ] == "https" ||
67
+ row [protocolIndex ] == "mongodb" || row [protocolIndex ] == "mysql" ) {
68
+ r = row [protocolIndex ] + "://" + r
69
+ } else {
70
+ r = "http://" + r
71
+ }
58
72
}
59
73
}
60
74
newRow = append (newRow , r )
@@ -64,6 +78,71 @@ func fixHostToUrl(res [][]string, fields []string, hostIndex int, urlPrefix stri
64
78
return newRes
65
79
}
66
80
81
+ // fixUrlCheck 检查参数,构建新的field和记录相关字段的偏移
82
+ // 返回hostIndex, protocolIndex, fields, rawFieldSize, err
83
+ func (c * Client ) fixUrlCheck (fields []string , options ... SearchOptions ) (int , int , []string , int , error ) {
84
+ noSetFields := false
85
+ if len (fields ) == 0 {
86
+ noSetFields = true
87
+ fields = []string {"host" , "ip" , "port" }
88
+ }
89
+ rawFieldSize := len (fields )
90
+
91
+ // 确保urlfix开启后带上了protocol字段
92
+ protocolIndex := - 1
93
+ hostIndex := - 1
94
+ if len (options ) > 0 && options [0 ].FixUrl {
95
+ if noSetFields {
96
+ fields = []string {"host" , "ip" , "port" , "protocol" }
97
+ rawFieldSize = len (fields )
98
+ hostIndex = 0
99
+ protocolIndex = 3
100
+ } else {
101
+ // 检查host字段存在
102
+ for index , f := range fields {
103
+ switch f {
104
+ case "host" :
105
+ hostIndex = index
106
+ break
107
+ }
108
+ }
109
+ if hostIndex == - 1 {
110
+ err := errors .New (NoHostWithFixURL )
111
+ return hostIndex , protocolIndex , fields , rawFieldSize , err
112
+ }
113
+ for index , f := range fields {
114
+ switch f {
115
+ case "protocol" :
116
+ protocolIndex = index
117
+ break
118
+ }
119
+ }
120
+ if protocolIndex == - 1 {
121
+ fields = append (fields , "protocol" )
122
+ protocolIndex = len (fields ) - 1
123
+ }
124
+ }
125
+ }
126
+ return hostIndex , protocolIndex , fields , rawFieldSize , nil
127
+ }
128
+
129
+ func (c * Client ) postProcess (res [][]string , fields []string ,
130
+ hostIndex int , protocolIndex int , rawFieldSize int , options ... SearchOptions ) [][]string {
131
+ if len (options ) > 0 && options [0 ].FixUrl {
132
+ res = fixHostToUrl (res , fields , hostIndex , options [0 ].UrlPrefix , protocolIndex )
133
+ }
134
+
135
+ // 返回用户指定的字段
136
+ if rawFieldSize != len (fields ) {
137
+ var newRes [][]string
138
+ for _ , r := range res {
139
+ newRes = append (newRes , r [0 :rawFieldSize ])
140
+ }
141
+ return newRes
142
+ }
143
+ return res
144
+ }
145
+
67
146
// HostSearch search fofa host data
68
147
// query fofa query string
69
148
// size data size: -1 means all,0 means just data total info, >0 means actual size
@@ -112,23 +191,22 @@ func (c *Client) HostSearch(query string, size int, fields []string, options ...
112
191
perPage = 1000
113
192
}
114
193
115
- if len (fields ) == 0 {
116
- fields = []string {"ip" , "port" }
194
+ hostIndex , protocolIndex , fields , rawFieldSize , err := c .fixUrlCheck (fields , options ... )
195
+ if err != nil {
196
+ return nil , err
117
197
}
118
198
199
+ uniqIPMap := make (map [string ]bool )
119
200
// 确认fields包含ip
120
201
ipIndex := - 1
121
- uniqIPMap := make (map [string ]bool )
122
202
if uniqByIP {
123
- ipExists := false
124
203
for index , f := range fields {
125
204
if f == "ip" {
126
205
ipIndex = index
127
- ipExists = true
128
206
break
129
207
}
130
208
}
131
- if ! ipExists {
209
+ if ipIndex == - 1 {
132
210
fields = append (fields , "ip" )
133
211
ipIndex = len (fields ) - 1
134
212
}
@@ -213,18 +291,7 @@ func (c *Client) HostSearch(query string, size int, fields []string, options ...
213
291
}
214
292
215
293
// 后处理
216
- if len (options ) > 0 && options [0 ].FixUrl {
217
- urlPrefix := options [0 ].UrlPrefix
218
- if urlPrefix == "" {
219
- urlPrefix = "http://"
220
- }
221
- for i , f := range fields {
222
- if f == "host" {
223
- res = fixHostToUrl (res , fields , i , urlPrefix )
224
- break
225
- }
226
- }
227
- }
294
+ res = c .postProcess (res , fields , hostIndex , protocolIndex , rawFieldSize , options ... )
228
295
229
296
return
230
297
}
@@ -272,8 +339,11 @@ func (c *Client) DumpSearch(query string, allSize int, batchSize int, fields []s
272
339
if perPage < 1 || perPage > 100000 {
273
340
return errors .New ("batchSize must between 1 and 100000" )
274
341
}
275
- if len (fields ) == 0 {
276
- fields = []string {"host" , "ip" , "port" }
342
+
343
+ // 确保urlfix开启后带上了protocol字段
344
+ hostIndex , protocolIndex , fields , rawFieldSize , err := c .fixUrlCheck (fields , options ... )
345
+ if err != nil {
346
+ return err
277
347
}
278
348
279
349
// 分页取数据
@@ -331,18 +401,7 @@ func (c *Client) DumpSearch(query string, allSize int, batchSize int, fields []s
331
401
}
332
402
333
403
// 后处理
334
- if len (options ) > 0 && options [0 ].FixUrl {
335
- urlPrefix := options [0 ].UrlPrefix
336
- if urlPrefix == "" {
337
- urlPrefix = "http://"
338
- }
339
- for i , f := range fields {
340
- if f == "host" {
341
- results = fixHostToUrl (results , fields , i , urlPrefix )
342
- break
343
- }
344
- }
345
- }
404
+ results = c .postProcess (results , fields , hostIndex , protocolIndex , rawFieldSize , options ... )
346
405
347
406
if c .onResults != nil {
348
407
c .onResults (results )
0 commit comments