1

我一直在努力制作一个 sftp 服务器,并且无法从我的 ISFTPServer.openDirectory 函数返回任何信息。

前任

class MySFTPAdapter:
    implements(filetransfer.ISFTPServer)
    def openDirectory(self, path):
        return ('test', 'drwxrwxrwx    1 ab       cd              0 Apr 23 15:41 test', {'size': 0, 'uid': 1000, 'gid': 1000, 'mtime': 1366746069L, 'atime': 1366746069L, 'permissions': 511})

失败

    Traceback (most recent call last):
  File "sftpserver.py", line 435, in dataReceived
    f(data)
  File "/usr/lib/python2.6/dist-packages/twisted/conch/ssh/filetransfer.py", line 265, in packet_OPENDIR
    d.addCallback(self._cbOpenDirectory, requestId)
  File "/usr/lib/python2.6/dist-packages/twisted/internet/defer.py", line 260, in addCallback
    callbackKeywords=kw)
  File "/usr/lib/python2.6/dist-packages/twisted/internet/defer.py", line 249, in addCallbacks
    self._runCallbacks()
--- <exception caught here> ---
  File "/usr/lib/python2.6/dist-packages/twisted/internet/defer.py", line 441, in _runCallbacks
    self.result = callback(self.result, *args, **kw)
  File "/usr/lib/python2.6/dist-packages/twisted/conch/ssh/filetransfer.py", line 269, in _cbOpenDirectory
    handle = str(hash(dirObj))
exceptions.TypeError: unhashable type: 'dict'

异常帧局部变量是;

{'val': ('test', 'drwxrwxrwx    1 ab       cd              0 Apr 23 15:41 test', {'size': 0, 'uid': 1000, 'gid': 1000, 'mtime': 1366746069L, 'atime': 1366746069L, 'permissions': 511})}

任何人都知道发生了什么或我做错了什么?

4

1 回答 1

3

您的实施openDirectory

def openDirectory(self, path):
    return ('test',
            'drwxrwxrwx    1 ab       cd              0 Apr 23 15:41 test',
            {'size': 0, 'uid': 1000, 'gid': 1000, 'mtime': 1366746069L,
             'atime': 1366746069L, 'permissions': 511})

返回三个元素的元组。从接口文档:

    This method returns an iterable object that has a close() method,                                                                      
    or a Deferred that is called back with same.                                                                                           

    The close() method is called when the client is finished reading                                                                       
    from the directory.  At this point, the iterable will no longer                                                                        
    be used.                                                                                                                               

    The iterable should return triples of the form (filename,                                                                              
    longname, attrs) or Deferreds that return the same.  The                                                                               
    sequence must support __getitem__, but otherwise may be any                                                                            
    'sequence-like' object.                                                      

您返回的元组听起来像是这里讨论的迭代器的一个元素,而不是整个返回值。

尝试类似:

def openDirectory(self, path):
    yield ('test',
           'drwxrwxrwx    1 ab       cd              0 Apr 23 15:41 test',
           {'size': 0, 'uid': 1000, 'gid': 1000, 'mtime': 1366746069L,
            'atime': 1366746069L, 'permissions': 511})

现在你有了一个生成器——它是一个带有 close 方法的迭代器——它的元素是文档中描述的三元组。

于 2013-04-30T18:58:54.067 回答