106 lines
1.7 KiB
Go
106 lines
1.7 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"flag"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"io/ioutil"
|
||
|
"log"
|
||
|
"net/http"
|
||
|
"runtime"
|
||
|
"sort"
|
||
|
"sync"
|
||
|
)
|
||
|
|
||
|
const max = 1000
|
||
|
|
||
|
type pair struct {
|
||
|
u string
|
||
|
s int64
|
||
|
}
|
||
|
|
||
|
type pairs []pair
|
||
|
|
||
|
func (p pairs) Len() int { return len(p) }
|
||
|
func (p pairs) Swap(a, b int) { p[a], p[b] = p[b], p[a] }
|
||
|
func (p pairs) Less(a, b int) bool { return p[a].s < p[b].s }
|
||
|
|
||
|
var workers = flag.Int("workers", runtime.NumCPU()*4, "number of downloaders")
|
||
|
|
||
|
func main() {
|
||
|
flag.Parse()
|
||
|
for r := range srt(attack(urls(max), *workers)) {
|
||
|
fmt.Printf("%v\t%v\n", r.s, r.u)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func urls(max int) chan string {
|
||
|
r := make(chan string)
|
||
|
|
||
|
go func() {
|
||
|
for i := 0; i < max; i++ {
|
||
|
r <- fmt.Sprintf("https://hmm.clstr.co/size/%03d", i)
|
||
|
}
|
||
|
close(r)
|
||
|
}()
|
||
|
|
||
|
return r
|
||
|
}
|
||
|
|
||
|
func attack(urls chan string, workers int) chan pair {
|
||
|
r := make(chan pair)
|
||
|
go func() {
|
||
|
c := http.Client{}
|
||
|
s := make(chan bool, workers)
|
||
|
wg := sync.WaitGroup{}
|
||
|
for u := range urls {
|
||
|
wg.Add(1)
|
||
|
s <- true
|
||
|
go func(url string) {
|
||
|
resp, err := c.Get(url)
|
||
|
if err != nil {
|
||
|
log.Printf("probalo: %v", err)
|
||
|
return
|
||
|
}
|
||
|
r <- pair{url, resp.ContentLength}
|
||
|
|
||
|
if n, err := io.Copy(ioutil.Discard, resp.Body); err != nil {
|
||
|
log.Printf("after %v bytes: %v", n, err)
|
||
|
}
|
||
|
if err := resp.Body.Close(); err != nil {
|
||
|
log.Printf("close body: %v", err)
|
||
|
}
|
||
|
<-s
|
||
|
wg.Done()
|
||
|
}(u)
|
||
|
}
|
||
|
wg.Wait()
|
||
|
close(r)
|
||
|
}()
|
||
|
return r
|
||
|
}
|
||
|
|
||
|
func srt(in chan pair) chan pair {
|
||
|
r := make(chan pair)
|
||
|
go func() {
|
||
|
ps := pairs{}
|
||
|
for r := range in {
|
||
|
ps = append(ps, r)
|
||
|
}
|
||
|
|
||
|
sort.Sort(ps)
|
||
|
|
||
|
for _, p := range ps {
|
||
|
r <- p
|
||
|
}
|
||
|
close(r)
|
||
|
}()
|
||
|
return r
|
||
|
}
|
||
|
|
||
|
func print() {
|
||
|
for i := 0; i < 1000; i++ {
|
||
|
fmt.Sprintf("hmm.clstr.co/size/%03d", i)
|
||
|
}
|
||
|
}
|