diff --git a/client/mpd/djrandom.go b/client/mpd/djrandom.go
index b5ef82db2c7ded3d1077312e4f492404f2e099a7..1fb6e49cbab7d47f4c4d4aa9f7954144e40d2aa5 100644
--- a/client/mpd/djrandom.go
+++ b/client/mpd/djrandom.go
@@ -7,6 +7,7 @@ import (
 	"fmt"
 	"io"
 	"log"
+	"net/http"
 	"net/url"
 	"strings"
 	"sync"
@@ -96,15 +97,55 @@ func (s *DJRandomSong) Open() (io.ReadCloser, error) {
 		return nil, errors.New("no audio file")
 	}
 
-	resp, err := s.client.GetRaw("/dl/" + s.audiofile.MD5)
-	if err != nil {
-		return nil, err
+	return &songReader{
+		client: s.client,
+		url:    "/dl/" + s.audiofile.MD5,
+		size:   s.audiofile.Size,
+	}, nil
+}
+
+// A streaming HTTP reader that can resume the download on error.
+type songReader struct {
+	client    *util.HttpClient
+	url       string
+	pos, size int64
+	resp      *http.Response
+}
+
+func (r *songReader) Read(buf []byte) (int, error) {
+	var err error
+	for i := 0; i < 2; i++ {
+		if r.pos >= r.size {
+			return 0, io.EOF
+		}
+		if r.resp == nil {
+			r.resp, err = r.client.GetRawRange(r.url, r.pos, r.size)
+			if err != nil {
+				return 0, err
+			}
+			if r.resp.StatusCode > 300 {
+				return 0, fmt.Errorf("HTTP error %d", r.resp.StatusCode)
+			}
+		}
+
+		var n int
+		n, err = r.resp.Body.Read(buf)
+		if n > 0 {
+			r.pos += int64(n)
+			return n, err
+		}
+		log.Printf("HTTP read error: %v", err)
+		r.resp.Body.Close()
+		r.resp = nil
 	}
-	if resp.StatusCode != 200 {
-		resp.Body.Close()
-		return nil, fmt.Errorf("HTTP error %d", resp.StatusCode)
+	return 0, err
+}
+
+func (r *songReader) Close() error {
+	if r.resp != nil {
+		r.resp.Body.Close()
 	}
-	return resp.Body, nil
+	return nil
 }
 
 type DJRandomDatabase struct {
diff --git a/util/http_client.go b/util/http_client.go
index 2b9e4243ecb779fdd943fe62afb30f1f486e9c67..5e1d571b1beb53ccf46b3af6880910084900cee0 100644
--- a/util/http_client.go
+++ b/util/http_client.go
@@ -116,6 +116,19 @@ func (h *HttpClient) GetRaw(url string) (*http.Response, error) {
 	return h.bulkClient.Do(req)
 }
 
+func (h *HttpClient) GetRawRange(url string, beg, end int64) (*http.Response, error) {
+	req, err := h.NewRequest("GET", url, nil)
+	if err != nil {
+		log.Printf("GetRaw(%s): NewRequest error: %s", url, err)
+		return nil, err
+	}
+	req.Header.Add("Range", fmt.Sprintf("bytes=%d-%d", beg, end-1))
+
+	SignHttpRequest(h.authKey, req)
+
+	return h.bulkClient.Do(req)
+}
+
 func (h *HttpClient) NewRequest(method, relUrl string, data io.Reader) (*http.Request, error) {
 	fullUrl := fmt.Sprintf("%s%s", h.baseUrl, relUrl)
 	return http.NewRequest(method, fullUrl, data)