Итерация по множественным возвращениям в Голанге
Я пытаюсь получить входные данные из текстового файла, содержащего домены (неизвестное количество), чтобы затем использовать каждый в качестве аргумента и получить их тип сервера. Как и ожидалось, это возвращает только последний домен. Как мне повторить несколько возвращаемых значений? Ниже приведен код. // Тестовый пакет main
import (
"bufio"
"time"
"os"
"fmt"
"net/http"
//"github.com/gocolly/colly"
)
var Domain string
var Target string
func main() {
Domain := DomainGrab()
Target := BannerGrab(Domain)
//CheckDB if not listed then add else skip
//RiskDB
//Email
fmt.Println(Domain)
fmt.Println(Target)
}
func BannerGrab(s string) string {
client := &http.Client{}
req, err := http.NewRequest("GET", s, nil)
if err != nil {
log.Fatalln(err)
}
req.Header.Set("User-Agent", "Authac/0.1")
resp, _ := client.Do(req)
serverEntry := resp.Header.Get("Server")
return serverEntry
}
func DomainGrab() string {
//c := colly.NewCollector()
// Open the file.
f, _ := os.Open("domains.txt")
defer f.Close()
// Create a new Scanner for the file.
scanner := bufio.NewScanner(f)
// Loop over all lines in the file and print them.
for scanner.Scan() {
line := scanner.Text()
time.Sleep(2 * time.Second)
//fmt.Println(line)
return line
}
return Domain
}
3 ответа
Если я понимаю ваш вопрос, вы хотите прочитать файл, как-то обнаружить, что этот файл был изменен, и найти метод, который будет генерировать эти изменения в клиентском коде.
Это не так, как файлы работают.
у вас есть два варианта:
Прослушайте изменения файлов, используя некоторые специфичные для ОС API - https://www.linuxjournal.com/content/linux-filesystem-events-inotify
Читать файл, используя бесконечный цикл. Прочитайте файл один раз. Сохраните копию в памяти. Снова и снова читайте один и тот же файл в цикле, пока новый файл не будет отличен от копии и вычислит дельту.
Проверьте, возможно ли это использовать push
вместо pull
для получения новых доменов. Возможно ли, чтобы система, управляющая доменными именами в файле, передавала данные вам напрямую?
Если loop
является единственно возможным вариантом, установить некоторое время паузы между чтениями файлов, чтобы уменьшить нагрузку на систему.
Используйте каналы, как предложено @dave, когда вам удалось получить новые домены и вам нужно обрабатывать их одновременно.
Если вы хотите сделать это "одновременно", вы вернете канал, по которому вы отправите несколько вещей, которые вы хотите вернуть:
https://play.golang.org/p/iYBGPwfYLYR
func DomainGrab() <-chan string {
ch := make(chan string, 1)
f, _ := os.Open("domains.txt")
defer f.Close()
scanner := bufio.NewScanner(f)
go func() {
// Loop over all lines in the file and print them.
for scanner.Scan() {
line := scanner.Text()
time.Sleep(2 * time.Second)
ch <- line
}
close(ch)
}()
return ch
}
Вероятно, не лучшее решение. Но я решил избавиться от отдельной функции, все вместе, просто покрыть больше земли. Я опубликую ниже код того, что я ожидаю. Теперь мне нужно проанализировать домены, чтобы корневые URL и субдомены сканировались только один раз.
// Main
package main
import (
"log"
"fmt"
"time"
"net/http"
"github.com/gocolly/colly"
)
//var Domain string
var Target string
func main() {
c := colly.NewCollector()
c.OnError(func(r *colly.Response, err error) {
fmt.Println("Request URL:", r.Request.URL, "\n Failed with response:", r.StatusCode)
})
// Find and visit all links
c.OnHTML("a", func(e *colly.HTMLElement) {
e.Request.Visit(e.Attr("href"))
})
c.OnRequest(func(r *colly.Request) {
Domain := r.URL.String()
Target := BannerGrab(Domain)
fmt.Println(Domain)
fmt.Println(Target)
fmt.Println("Dropping By.. ", r.URL)
time.Sleep(1000 * time.Millisecond)
})
c.Visit("http://www.milliondollarhomepage.com/")
}
//CheckDB if not listed else add
//RiskDB
//Email
func BannerGrab(s string) string {
client := &http.Client{}
req, err := http.NewRequest("GET", s, nil)
if err != nil {
log.Fatalln(err)
}
req.Header.Set("User-Agent", "Authac/0.1")
resp, _ := client.Do(req)
serverEntry := resp.Header.Get("Server")
return serverEntry
}