// Scrape scrapes a tracker request func Scrape(tracker torrentTracker, query url.Values) []byte { // List of files to be scraped scrapeFiles := make([]data.FileRecord, 0) // Iterate all info_hash values in query for _, infoHash := range query["info_hash"] { // Make a copy of query, set the info hash as current in loop localQuery := query localQuery.Set("info_hash", infoHash) // Store scrape information in struct scrape := new(data.ScrapeLog).FromValues(localQuery) if scrape == (data.ScrapeLog{}) { return tracker.Error("Malformed scrape") } // Request to store scrape go scrape.Save() log.Printf("scrape: [%s %s] %s", tracker.Protocol(), scrape.IP, scrape.InfoHash) // Check for a matching file via info_hash file := new(data.FileRecord).Load(scrape.InfoHash, "info_hash") if file == (data.FileRecord{}) { // Torrent is not currently registered return tracker.Error("Unregistered torrent") } // Ensure file is verified, meaning we will permit scraping of it if !file.Verified { return tracker.Error("Unverified torrent") } // Launch peer reaper to remove old peers from this file go file.PeerReaper() // File is valid, add it to list to be scraped scrapeFiles = append(scrapeFiles[:], file) } // Create scrape return tracker.Scrape(scrapeFiles) }
// Scrape generates and triggers a tracker scrape request func Scrape(tracker TorrentTracker, query url.Values) []byte { // List of files to be scraped scrapeFiles := make([]data.FileRecord, 0) // Iterate all info_hash values in query for _, infoHash := range query["info_hash"] { // Make a copy of query, set the info hash as current in loop localQuery := query localQuery.Set("info_hash", infoHash) // Store scrape information in struct scrape := new(data.ScrapeLog) err := scrape.FromValues(localQuery) if err != nil { return tracker.Error("Malformed scrape") } // Request to store scrape go func(scrape *data.ScrapeLog) { if err := scrape.Save(); err != nil { log.Println(err.Error()) } }(scrape) log.Printf("scrape: [%s %s] %s", tracker.Protocol(), scrape.IP, scrape.InfoHash) // Check for a matching file via info_hash file, err := new(data.FileRecord).Load(scrape.InfoHash, "info_hash") if err != nil { log.Println(err.Error()) return tracker.Error(ErrScrapeFailure.Error()) } // Torrent is not currently registered if file == (data.FileRecord{}) { return tracker.Error("Unregistered torrent") } // Ensure file is verified, meaning we will permit scraping of it if !file.Verified { return tracker.Error("Unverified torrent") } // Launch peer reaper asynchronously to remove old peers from this file go func(file data.FileRecord) { // Start peer reaper count, err := file.PeerReaper() if err != nil { log.Println(err.Error()) } // Report peers reaped if count > 0 { log.Println("peerReaper: reaped %d peers on file ID: %d", count, file.ID) } }(file) // File is valid, add it to list to be scraped scrapeFiles = append(scrapeFiles[:], file) } // Create scrape return tracker.Scrape(scrapeFiles) }