Add forceListHidden dial option to force the use of 'LIST -a' command (#271)

This is useful for servers that do not offer up
hidden folders/files by default when using LIST/MLSD
commands.
Setting forceListHidden to true will force the use of
the 'LIST -a' command even when MLST support has
been detected.
This commit is contained in:
Øyvind Heddeland Instefjord 2022-09-04 20:43:06 +02:00 committed by GitHub
parent b85cf1edcc
commit 99be0634ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 14 deletions

View File

@ -295,6 +295,20 @@ func TestListCurrentDir(t *testing.T) {
mock.Wait()
}
func TestListCurrentDirWithForceListHidden(t *testing.T) {
mock, c := openConnExt(t, "127.0.0.1", "no-time", DialWithDisabledMLSD(true), DialWithForceListHidden(true))
assert.True(t, c.options.forceListHidden)
_, err := c.List("")
assert.NoError(t, err)
assert.Equal(t, "LIST -a", mock.lastFull, "LIST -a must not have a trailing whitespace")
err = c.Quit()
assert.NoError(t, err)
mock.Wait()
}
func TestTimeUnsupported(t *testing.T) {
mock, c := openConnExt(t, "127.0.0.1", "no-time")

40
ftp.go
View File

@ -72,18 +72,19 @@ type DialOption struct {
// dialOptions contains all the options set by DialOption.setup
type dialOptions struct {
context context.Context
dialer net.Dialer
tlsConfig *tls.Config
explicitTLS bool
disableEPSV bool
disableUTF8 bool
disableMLSD bool
writingMDTM bool
location *time.Location
debugOutput io.Writer
dialFunc func(network, address string) (net.Conn, error)
shutTimeout time.Duration // time to wait for data connection closing status
context context.Context
dialer net.Dialer
tlsConfig *tls.Config
explicitTLS bool
disableEPSV bool
disableUTF8 bool
disableMLSD bool
writingMDTM bool
forceListHidden bool
location *time.Location
debugOutput io.Writer
dialFunc func(network, address string) (net.Conn, error)
shutTimeout time.Duration // time to wait for data connection closing status
}
// Entry describes a file and is returned by List().
@ -247,6 +248,16 @@ func DialWithWritingMDTM(enabled bool) DialOption {
}}
}
// DialWithForceListHidden returns a DialOption making ServerConn use LIST -a to include hidden files and folders in directory listings
//
// This is useful for servers that do not do this by default, but it forces the use of the LIST command
// even if the server supports MLST.
func DialWithForceListHidden(enabled bool) DialOption {
return DialOption{func(do *dialOptions) {
do.forceListHidden = enabled
}}
}
// DialWithLocation returns a DialOption that configures the ServerConn with specified time.Location
// The location is used to parse the dates sent by the server which are in server's timezone
func DialWithLocation(location *time.Location) DialOption {
@ -650,11 +661,14 @@ func (c *ServerConn) List(path string) (entries []*Entry, err error) {
var cmd string
var parser parseFunc
if c.mlstSupported {
if c.mlstSupported && !c.options.forceListHidden {
cmd = "MLSD"
parser = parseRFC3659ListLine
} else {
cmd = "LIST"
if c.options.forceListHidden {
cmd += " -a"
}
parser = parseListLine
}

View File

@ -4,7 +4,7 @@ import (
"path"
)
//Walker traverses the directory tree of a remote FTP server
// Walker traverses the directory tree of a remote FTP server
type Walker struct {
serverConn *ServerConn
root string