Я использую jlaffaye / ftp , чтобы написать абстракцию файловой системы FTP для Afero . Ниже представлена моя реализация функции Stat
:
func (fs FtpFs) Stat(name string) (os.FileInfo, error) {
fname, err := parseFilePath(name)
if err != nil {
return nil, err
}
entry := ftp.Entry{Name: fname}
size, err := fs.c.FileSize(fname)
if err != nil { // This would be the case for invalid path or for directories
_, e := fs.c.List(fname)
if e != nil { // This should be the case for invalid path
if strings.Contains(strings.ToLower(err.Error()), ErrTimeout.Error()) ||
strings.Contains(strings.ToLower(e.Error()), ErrTimeout.Error()) {
return nil, ErrTimeout
}
return nil, &os.PathError{
Op: "stat",
Path: name,
Err: syscall.ENOENT,
}
}
entry.Size = 0
entry.Type = ftp.EntryTypeFolder
} else {
entry.Size = uint64(size)
entry.Type = ftp.EntryTypeFile
}
return FileInfo{&entry}, nil
}
func parseFilePath(path string) (string, error) {
if strings.HasPrefix(path, "ftp:/") {
// afero.Walk() uses filepath.Join() to walk over a directory,
// which converts the "ftp://" prefix to "ftp:/". This is to
// restore the path to the correct format, so that it could be
// properly parsed by url.Parse().
if !strings.HasPrefix(path, "ftp://") {
path = path[:5] + "/" + path[5:]
}
pathUrl, err := url.Parse(path)
if err != nil {
return "", err
}
if pathUrl.RawPath != "" {
return pathUrl.RawPath, nil
}
return pathUrl.RequestURI(), nil
}
return path, nil
}
Для большинства FTP-серверов (Windows Server, Python s pyftpdlib
et c.) Это работает нормально. Однако, когда я вызываю эту функцию с недопустимым путем на моем сервере Vsftpd (работающем в Ubuntu 18.04), я не получаю никаких ошибок. Это связано с тем, что вызов List
, который для этого варианта использования возвращает ошибку на других серверах, просто возвращает пустой список.
Есть ли способ обойти это поведение, или есть ли что-то, что мне не хватает здесь?