From 6279216c2e8c9fe505c1d1b28ddb4f9c34edd697 Mon Sep 17 00:00:00 2001 From: Nicola Murino Date: Sun, 9 Apr 2023 20:17:37 +0200 Subject: [PATCH] webdav: fix GET as PROPFIND if a prefix is defined Signed-off-by: Nicola Murino --- internal/webdavd/internal_test.go | 26 ++++++++++++++++++++++++++ internal/webdavd/server.go | 4 ++++ 2 files changed, 30 insertions(+) diff --git a/internal/webdavd/internal_test.go b/internal/webdavd/internal_test.go index ffe936ce..3a812d90 100644 --- a/internal/webdavd/internal_test.go +++ b/internal/webdavd/internal_test.go @@ -34,6 +34,7 @@ import ( "github.com/eikenb/pipeat" "github.com/sftpgo/sdk" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/drakkan/sftpgo/v2/internal/common" "github.com/drakkan/sftpgo/v2/internal/dataprovider" @@ -638,6 +639,31 @@ func TestFileAccessErrors(t *testing.T) { } } +func TestCheckRequestMethodWithPrefix(t *testing.T) { + user := dataprovider.User{ + BaseUser: sdk.BaseUser{ + HomeDir: filepath.Clean(os.TempDir()), + Permissions: map[string][]string{ + "/": {dataprovider.PermAny}, + }, + }, + } + fs := vfs.NewOsFs("connID", user.HomeDir, "") + connection := &Connection{ + BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user), + } + server := webDavServer{ + binding: Binding{ + Prefix: "/dav", + }, + } + req, err := http.NewRequest(http.MethodGet, "/../dav", nil) + require.NoError(t, err) + server.checkRequestMethod(context.Background(), req, connection) + require.Equal(t, "PROPFIND", req.Method) + require.Equal(t, "1", req.Header.Get("Depth")) +} + func TestContentType(t *testing.T) { user := dataprovider.User{ BaseUser: sdk.BaseUser{ diff --git a/internal/webdavd/server.go b/internal/webdavd/server.go index 081cc2b5..43290d7b 100644 --- a/internal/webdavd/server.go +++ b/internal/webdavd/server.go @@ -26,6 +26,7 @@ import ( "path" "path/filepath" "runtime/debug" + "strings" "time" "github.com/drakkan/webdav" @@ -137,6 +138,9 @@ func (s *webDavServer) checkRequestMethod(ctx context.Context, r *http.Request, // see RFC4918, section 9.4 if r.Method == http.MethodGet || r.Method == http.MethodHead { p := path.Clean(r.URL.Path) + if s.binding.Prefix != "" { + p = strings.TrimPrefix(p, s.binding.Prefix) + } info, err := connection.Stat(ctx, p) if err == nil && info.IsDir() { if r.Method == http.MethodHead {