From e3b2780655c3f8a38649e0c5f3fc8f6c50fe12ad Mon Sep 17 00:00:00 2001 From: Nicola Murino Date: Sat, 24 Jan 2026 10:20:19 +0100 Subject: [PATCH] webdav: ignore port for unix domain sockets Fixes #2151 Signed-off-by: Nicola Murino --- internal/webdavd/internal_test.go | 68 ++++++++++++++++++++++++++++++- internal/webdavd/webdavd.go | 16 ++++++-- 2 files changed, 80 insertions(+), 4 deletions(-) diff --git a/internal/webdavd/internal_test.go b/internal/webdavd/internal_test.go index 4b676c69..35f71035 100644 --- a/internal/webdavd/internal_test.go +++ b/internal/webdavd/internal_test.go @@ -270,6 +270,7 @@ Ap157PUHTriSnxyMF2Sb3EhX/rQkmbnbCqqygHC14iBy8MrKzLG00X6BelZV5n0D RKjnkiEZeG4+G91Xu7+HmcBLwV86k5I+tXK9O1Okomr6Zry8oqVcxU5TB6VRS+rA ubwF00Drdvk2+kDZfxIM137nBiy7wgCJi2Ksm5ihN3dUF6Q0oNPl -----END RSA PRIVATE KEY-----` + osWindows = "windows" ) // MockOsFs mockable OsFs @@ -523,7 +524,7 @@ func TestResolvePathErrors(t *testing.T) { assert.EqualError(t, err, common.ErrGenericFailure.Error()) } - if runtime.GOOS != "windows" { + if runtime.GOOS != osWindows { user.HomeDir = filepath.Clean(os.TempDir()) connection.User = user fs := vfs.NewOsFs("connID", connection.User.HomeDir, "", nil) @@ -1740,3 +1741,68 @@ func TestGetCacheExpirationTime(t *testing.T) { c.ExpirationTime = 1 assert.False(t, c.getExpirationTime().IsZero()) } + +func TestBindingGetAddress(t *testing.T) { + tests := []struct { + name string + binding Binding + want string + }{ + { + name: "IP address with port", + binding: Binding{Address: "127.0.0.1", Port: 8080}, + want: "127.0.0.1:8080", + }, + { + name: "Unix socket path (no port)", + binding: Binding{Address: "/tmp/app.sock", Port: 0}, + want: "/tmp/app.sock", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.binding.GetAddress(); got != tt.want { + t.Errorf("GetAddress() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestBindingIsValid(t *testing.T) { + tests := []struct { + name string + binding Binding + want bool + }{ + { + name: "Valid: Positive port", + binding: Binding{Address: "127.0.0.1", Port: 10080}, + want: true, + }, + { + name: "Valid: Absolute path on Unix (non-Windows)", + binding: Binding{Address: "/var/run/app.sock", Port: 0}, + // This test outcome is dynamic based on the OS + want: runtime.GOOS != osWindows, + }, + { + name: "Invalid: Port 0 and relative path", + binding: Binding{Address: "relative/path", Port: 0}, + want: false, + }, + { + name: "Invalid: Empty address and port 0", + binding: Binding{Address: "", Port: 0}, + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.binding.IsValid(); got != tt.want { + t.Errorf("IsValid() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/internal/webdavd/webdavd.go b/internal/webdavd/webdavd.go index bd59f759..36b3b33c 100644 --- a/internal/webdavd/webdavd.go +++ b/internal/webdavd/webdavd.go @@ -21,6 +21,7 @@ import ( "net/http" "os" "path/filepath" + "runtime" "time" "github.com/go-chi/chi/v5/middleware" @@ -176,12 +177,21 @@ func (b *Binding) isMutualTLSEnabled() bool { // GetAddress returns the binding address func (b *Binding) GetAddress() string { - return fmt.Sprintf("%s:%d", b.Address, b.Port) + if b.Port > 0 { + return fmt.Sprintf("%s:%d", b.Address, b.Port) + } + return b.Address } -// IsValid returns true if the binding port is > 0 +// IsValid returns true if the binding is valid func (b *Binding) IsValid() bool { - return b.Port > 0 + if b.Port > 0 { + return true + } + if filepath.IsAbs(b.Address) && runtime.GOOS != "windows" { + return true + } + return false } func (b *Binding) listenerWrapper() func(net.Listener) (net.Listener, error) {