Add method to parse IPs by version (IPv4/IPv6) with validation and limit support
This commit is contained in:
@@ -63,3 +63,50 @@ func (p *jsonLinesParser) Parse(body io.Reader, validator IPValidator, limit uin
|
|||||||
|
|
||||||
return ips, nil
|
return ips, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseIPsByVersion parses the JSON Lines data from the given reader
|
||||||
|
// and returns a slice of IP addresses for each IP version.
|
||||||
|
// It also returns any errors that occurred during the process.
|
||||||
|
func (p *jsonLinesParser) ParseIPsByVersion(body io.Reader, validator IPValidator, limit uint) (ipV4 IPs, ipV6 IPs, err error) {
|
||||||
|
decoder := json.NewDecoder(body)
|
||||||
|
ipV4 = make(IPs, 0)
|
||||||
|
ipV6 = make(IPs, 0)
|
||||||
|
for {
|
||||||
|
var item json.RawMessage
|
||||||
|
if err := decoder.Decode(&item); err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return nil, nil, fmt.Errorf("decode json item: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if item == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ip, err := p.extract(item)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("extract ip: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ip = strings.TrimSpace(ip)
|
||||||
|
isValid, ipVersion := validator.IsValidAndReturnVersion(ip)
|
||||||
|
if !isValid {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if ipVersion == IPVersion4 {
|
||||||
|
ipV4 = append(ipV4, ip)
|
||||||
|
} else if ipVersion == IPVersion6 {
|
||||||
|
ipV6 = append(ipV6, ip)
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if limit > 0 && uint(len(ipV4))+uint(len(ipV6)) >= limit {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ipV4, ipV6, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -66,3 +66,53 @@ func (p *rssParser) Parse(body io.Reader, validator IPValidator, limit uint) (IP
|
|||||||
|
|
||||||
return ips, nil
|
return ips, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseIPsByVersion parses the RSS data from the given reader
|
||||||
|
// and returns a slice of IP addresses for each IP version.
|
||||||
|
// It also returns any errors that occurred during the process.
|
||||||
|
func (p *rssParser) ParseIPsByVersion(body io.Reader, validator IPValidator, limit uint) (ipV4 IPs, ipV6 IPs, err error) {
|
||||||
|
decoder := xml.NewDecoder(body)
|
||||||
|
ipV4 = make(IPs, 0)
|
||||||
|
ipV6 = make(IPs, 0)
|
||||||
|
|
||||||
|
for {
|
||||||
|
token, err := decoder.Token()
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil, fmt.Errorf("parse rss: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
start, ok := token.(xml.StartElement)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ip, err := p.extract(decoder, start)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("extract rss ip: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ip = strings.TrimSpace(ip)
|
||||||
|
isValid, ipVersion := validator.IsValidAndReturnVersion(ip)
|
||||||
|
if !isValid {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if ipVersion == IPVersion4 {
|
||||||
|
ipV4 = append(ipV4, ip)
|
||||||
|
} else if ipVersion == IPVersion6 {
|
||||||
|
ipV6 = append(ipV6, ip)
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if limit > 0 && uint(len(ipV4))+uint(len(ipV6)) >= limit {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ipV4, ipV6, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -158,3 +158,49 @@ func (p *textParser) Parse(body io.Reader, validator IPValidator, limit uint) (I
|
|||||||
|
|
||||||
return ips, nil
|
return ips, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *textParser) ParseIPsByVersion(body io.Reader, validator IPValidator, limit uint) (ipV4 IPs, ipV6 IPs, err error) {
|
||||||
|
ipV4 = make(IPs, 0)
|
||||||
|
ipV6 = make(IPs, 0)
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(body)
|
||||||
|
|
||||||
|
buf := make([]byte, 0, 64*1024)
|
||||||
|
scanner.Buffer(buf, 1024*1024)
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := strings.TrimSpace(scanner.Text())
|
||||||
|
if line == "" || strings.HasPrefix(line, ";") || strings.HasPrefix(line, "#") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ip, isFound := p.textExtract.Extract(line)
|
||||||
|
if !isFound {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ip = strings.TrimSpace(ip)
|
||||||
|
isValid, ipVersion := validator.IsValidAndReturnVersion(ip)
|
||||||
|
if !isValid {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if ipVersion == IPVersion4 {
|
||||||
|
ipV4 = append(ipV4, ip)
|
||||||
|
} else if ipVersion == IPVersion6 {
|
||||||
|
ipV6 = append(ipV6, ip)
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if limit > 0 && uint(len(ipV4))+uint(len(ipV6)) >= limit {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("read response: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ipV4, ipV6, nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user