diff --git a/http.go b/http.go index b281fc8..85defaa 100644 --- a/http.go +++ b/http.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "io" + "mime" "net/http" "net/url" "strconv" @@ -21,6 +22,7 @@ type RangeReadSeekCloser struct { buf []byte bufferOffset int64 closed bool + fileName string } func NewRangeReadSeekCloser(uri string) (*RangeReadSeekCloser, error) { @@ -200,6 +202,10 @@ func (r *RangeReadSeekCloser) Close() error { return nil } +func (r *RangeReadSeekCloser) GetFileName() string { + return r.fileName +} + func (r *RangeReadSeekCloser) getInformation() error { response, err := http.DefaultClient.Head(r.GetURI()) if err != nil { @@ -215,6 +221,60 @@ func (r *RangeReadSeekCloser) getInformation() error { if r.size, err = strconv.ParseInt(response.Header.Get("content-length"), 10, 0); err != nil { return errors.New("server response does not have a valid Content-Length") } + if response.Header.Get("content-disposition") != "" { + if _, params, err := mime.ParseMediaType(response.Header.Get("content-disposition")); err == nil { + if disposition, ok := params["filename"]; ok { + r.fileName = disposition + } + } + } + + if r.fileName == "" { + if response.Header.Get("content-type") != "" { + if mimeType, params, err := mime.ParseMediaType(response.Header.Get("content-type")); err == nil { + switch mimeType { + case "audio/flac": + r.fileName = "_.flac" + case "audio/ogg": + r.fileName = "_.ogg" + if codecs, ok := params["codecs"]; ok { + switch codecs { + case "vorbis": + r.fileName = "_.vorbis" + case "opus": + r.fileName = "_.opus" + case "flac": + r.fileName = "_.flac" + } + } + case "audio/mpeg": + r.fileName = "_.mp3" + if codecs, ok := params["codecs"]; ok { + switch codecs { + case "mp3": + r.fileName = "_.mp3" + } + } + case "audio/mp4": + r.fileName = "_.m4a" + if codecs, ok := params["codecs"]; ok { + switch codecs { + case "alac": + r.fileName = "_.alac" + } + } + case "audio/aac": + r.fileName = "_.aac" + case "audio/x-tta", "audio/tta": + r.fileName = "_.tta" + } + } + } + } + + if r.fileName == "" { + r.fileName = r.GetURI() + } return nil } diff --git a/queue.go b/queue.go index 8b17837..9f78ab9 100644 --- a/queue.go +++ b/queue.go @@ -19,6 +19,7 @@ import ( "log" "net/http" "os" + "path" "runtime" "strconv" "strings" @@ -85,11 +86,14 @@ func (e *QueueTrackEntry) Load() error { return nil } + fileName := path.Base(e.Path) + if len(e.Path) > 4 && e.Path[:4] == "http" { s, err := NewRangeReadSeekCloser(e.Path) if err != nil { return err } + fileName = s.GetFileName() runtime.SetFinalizer(s, (*RangeReadSeekCloser).Close) @@ -116,7 +120,7 @@ func (e *QueueTrackEntry) Load() error { return err } - decoders, err := guess.GetDecoders(e.reader, e.Path) + decoders, err := guess.GetDecoders(e.reader, fileName) if err != nil { return err }