From 8c038326b9c649f349fd2bd63a7491f4879c3362 Mon Sep 17 00:00:00 2001 From: Dan Walters Date: Sat, 14 Sep 2019 16:16:07 -0500 Subject: [PATCH] dlna: correct output for ContentDirectoryService#Browse with BrowseMetadata We were marshalling the "cds object" instead of the "upnp object". Fixes #3253 (I think) --- cmd/serve/dlna/cds.go | 10 +++++++++- cmd/serve/dlna/dlna_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/cmd/serve/dlna/cds.go b/cmd/serve/dlna/cds.go index 39fa09c37..2e77162a3 100644 --- a/cmd/serve/dlna/cds.go +++ b/cmd/serve/dlna/cds.go @@ -245,7 +245,15 @@ func (cds *contentDirectoryService) Handle(action string, argsXML []byte, r *htt "UpdateID": cds.updateIDString(), }, nil case "BrowseMetadata": - result, err := xml.Marshal(obj) + node, err := cds.vfs.Stat(obj.Path) + if err != nil { + return nil, err + } + upnpObject, err := cds.cdsObjectToUpnpavObject(obj, node, host) + if err != nil { + return nil, err + } + result, err := xml.Marshal(upnpObject) if err != nil { return nil, err } diff --git a/cmd/serve/dlna/dlna_test.go b/cmd/serve/dlna/dlna_test.go index 157f8c19e..7fb5ce395 100644 --- a/cmd/serve/dlna/dlna_test.go +++ b/cmd/serve/dlna/dlna_test.go @@ -7,6 +7,7 @@ import ( "net/http" "net/url" "os" + "strings" "testing" "github.com/rclone/rclone/vfs" @@ -91,3 +92,32 @@ func TestServeContent(t *testing.T) { require.Equal(t, goldenContents, actualContents) } + +// Check that ContentDirectory#Browse returns appropriate metadata on the root container. +func TestContentDirectoryBrowseMetadata(t *testing.T) { + // Sample from: https://github.com/rclone/rclone/issues/3253#issuecomment-524317469 + req, err := http.NewRequest("POST", testURL+"ctl", strings.NewReader(` + + + + + 0 + BrowseMetadata + * + 0 + 0 + + + +`)) + require.NoError(t, err) + req.Header.Set("SOAPACTION", `"urn:schemas-upnp-org:service:ContentDirectory:1#Browse"`) + resp, err := http.DefaultClient.Do(req) + require.NoError(t, err) + assert.Equal(t, http.StatusOK, resp.StatusCode) + body, err := ioutil.ReadAll(resp.Body) + require.NoError(t, err) + require.Contains(t, string(body), "<container ") + require.NotContains(t, string(body), "<item ") +}