func (c *httpClient) Files(urls []string, files *[]File) error {
	l := len(urls)
	fs := make([]File, l)
	ch := make(chan error, l)
	var wg sync.WaitGroup
	wg.Add(l)
	for i, url := range urls {
		go func(i int) {
			defer wg.Done()
			resp, err := c.Get(url)
			if err != nil {
				ch <- err
				return
			}
			defer resp.Body.Close()
			if resp.StatusCode != 200 {
				var err error
				err = c.err(resp, "")
				ch <- err
				return
			}
			fs[i].Data, err = ioutil.ReadAll(resp.Body)
			if err != nil {
				ch <- c.err(resp, err.Error())
				return
			}
			ch <- nil
		}(i)
	}
	wg.Wait()
	for _ = range fs {
		if err := <-ch; err != nil {
			return err
		}
	}
	*files = fs
	return nil
}
Files downloads multiple files concurrency.
package httpclient
import (
	"encoding/json"
	"encoding/xml"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"sync"
)
type Error struct {
	Message    string
	StatusCode int
	URL        string
}
func (e *Error) Error() string {
	return e.Message
}
type File struct {
	Name string
	Data []byte
}
type httpClient struct {
	client *http.Client
}
func New() *httpClient {
	return &httpClient{client: &http.Client{}}
}
func (c *httpClient) err(resp *http.Response, message string) error {
	if message == "" {
		message = fmt.Sprintf("Get %s -> %d", resp.Request.URL.String(), resp.StatusCode)
	}
	return &Error{
		Message:    message,
		StatusCode: resp.StatusCode,
		URL:        resp.Request.URL.String(),
	}
}
func (c *httpClient) Get(url string) (*http.Response, error) {
	return c.client.Get(url)
}
func (c *httpClient) Bytes(url string) ([]byte, error) {
	resp, err := c.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return nil, c.err(resp, "")
	}
	p, err := ioutil.ReadAll(resp.Body)
	return p, err
}
func (c *httpClient) String(url string) (string, error) {
	bytes, err := c.Bytes(url)
	if err != nil {
		return "", err
	}
	return string(bytes), nil
}
func (c *httpClient) Reader(url string) (io.ReadCloser, error) {
	resp, err := c.Get(url)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != 200 {
		err = c.err(resp, "")
		resp.Body.Close()
		return nil, err
	}
	return resp.Body, nil
}
func (c *httpClient) JSON(url string, v interface{}) error {
	resp, err := c.Get(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return c.err(resp, "")
	}
	err = json.NewDecoder(resp.Body).Decode(v)
	if _, ok := err.(*json.SyntaxError); ok {
		err = c.err(resp, "JSON syntax error at "+url)
	}
	return err
}
func (c *httpClient) XML(url string, v interface{}) error {
	resp, err := c.Get(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return c.err(resp, "")
	}
	err = xml.NewDecoder(resp.Body).Decode(v)
	return err
}