//go:build !solution package main import ( "fmt" "io" "net/http" "os" "time" ) type HTTPGetResult struct { Success bool Body string Elapsed time.Duration Size int URL string Error error } func (result HTTPGetResult) String() string { if result.Success { return fmt.Sprintf("%v\t%v\t%v", result.Elapsed, result.Size, result.URL) } else { return result.Error.Error() } } func GetHTTPBody(url string, ch chan HTTPGetResult) { startTime := time.Now() resp, err := http.Get(url) if err != nil { ch <- HTTPGetResult{Success: false, Error: err} return } defer resp.Body.Close() data, err := io.ReadAll(resp.Body) if err != nil { ch <- HTTPGetResult{Success: false, Error: err} return } ch <- HTTPGetResult{ Success: true, Body: string(data), Elapsed: time.Since(startTime), Size: len(data), URL: url, } } func main() { startTime := time.Now() urls, ch := os.Args[1:], make(chan HTTPGetResult) for _, url := range urls { go GetHTTPBody(url, ch) } for i := 0; i < len(urls); i++ { fmt.Println(<-ch) } fmt.Println(time.Since(startTime), "elapsed") }