package main import ( "bufio" "bytes" "fmt" "io" "log" "mime" "net/http" "net/url" "os" "path/filepath" "strconv" ) func main() { ReadAndDownload(".", os.Stdin) } func ReadAndDownload(root string, r io.Reader) { var n int var name string scanner := bufio.NewScanner(r) for scanner.Scan() { txt := scanner.Text() if name == "" || txt == "" { name = txt n = 0 continue } err := download(n, root, name, txt) if err != nil { log.Println(err) } n++ } } func download(n int, root, name, uri string) error { u, err := url.Parse(uri) if err != nil { return fmt.Errorf("parsing uri %s: %v", uri, err) } ext := filepath.Ext(u.Path) response, err := http.Get(uri) switch { case err != nil: return fmt.Errorf("downloading file %s: %v", uri, err) case response.StatusCode != http.StatusOK: return fmt.Errorf("downloading file %s: status code %d", uri, response.StatusCode) default: defer response.Body.Close() } var r io.Reader = response.Body if ext == "" { var err error ext, r, err = guessExt(response.Body) if err != nil { return err } } filename := filepath.Join(root, name+strconv.Itoa(n)+ext) f, err := os.Create(filename) if err != nil { return err } _, err = io.Copy(f, r) return err } func guessExt(r io.Reader) (string, io.Reader, error) { head, headCopy := make([]byte, 512), make([]byte, 512) n, readErr := io.ReadFull(r, head) head = head[:n] copy(headCopy, head) hr := bytes.NewReader(headCopy) t := http.DetectContentType(head) ext, err := mime.ExtensionsByType(t) if readErr == io.EOF || readErr == io.ErrUnexpectedEOF { return ext[0], hr, nil } if err != nil { return "", nil, err } return ext[0], io.MultiReader(hr, r), nil }