У меня довольно неприятная проблема при попытке отправить файл через HTTP в Twisted.Я довольно новичок в Python (потому что это моя первая настоящая попытка сделать что-то кроме Hello World и т. Д.).
Теперь я совершенно уверен, что проблема возникает, когда FileSender отправляет двоичные данные,не совместим с UTF-8.Это кажется довольно обычной вещью при перемещении файлов, таких как изображения, видео, исполняемые файлы по сети.
Мне кажется, что при инициализации Twisted буфер инициализируется до ""
, что(Может быть, я очень ошибаюсь) это строка символов UTF-8 (или какова кодировка символов вашего Python по умолчанию)? ... Затем, когда новые данные добавляются в буфер, старый буфер (UTF-8) объединяетсяс новым буфером (э ... какая-нибудь другая двоичная кодировка?), которая приводит к:
Unhandled Error
Traceback (most recent call last):
Failure: exceptions.RuntimeError: Producer was not unregistered for /vfs/videos/thevid.avi
Unhandled Error
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/twisted/python/log.py", line 84, in callWithLogger
return callWithContext({"system": lp}, func, *args, **kw)
File "/usr/lib/python2.7/dist-packages/twisted/python/log.py", line 69, in callWithContext
return context.call({ILogContext: newCtx}, func, *args, **kw)
File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 118, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 81, in callWithContext
return func(*args,**kw)
--- <exception caught here> ---
File "/usr/lib/python2.7/dist-packages/twisted/internet/selectreactor.py", line 146, in _doReadOrWrite
why = getattr(selectable, method)()
File "/usr/lib/python2.7/dist-packages/twisted/internet/tcp.py", line 428, in doWrite
result = abstract.FileDescriptor.doWrite(self)
File "/usr/lib/python2.7/dist-packages/twisted/internet/abstract.py", line 199, in doWrite
self.dataBuffer = buffer(self.dataBuffer, self.offset) + "".join(self._tempDataBuffer)
File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
exceptions.UnicodeDecodeError: 'utf8' codec can't decode byte 0xd3 in position 6: invalid continuation byte
Unhandled Error
Traceback (most recent call last):
Failure: exceptions.RuntimeError: Producer was not unregistered for /vfs/videos/thevid.avi
Конечно, должен быть способ надежно установить буфер для передачи двоичных данных?Мой код для функции отправки файлов ниже.Я использую TxJSONRPC для создания и управления сервером (кроме метода render
, который переопределяется для обработки не только RPC).Если требуется дополнительная информация (например, об объекте запроса или Reactor, я могу покопаться).
Примечание: я хорошо знаю, что у меня нет обработчика ошибок, но на данный момент это не имеет большого значениямне.Обработка ошибок будет добавлена, как только я получу надежную передачу файлов!
def writeFile(self, request, location):
# Setup headers (mime type, filename)
request.setHeader('Content-Type', mimetypes.guess_type("file://" + location))
request.setHeader('Content-Disposition', "attachment; filename=" + path.basename(location))
# Open file
handle = open(location, "rb")
# Setup transfer (then cleanup etc)
d = FileSender().beginFileTransfer(handle, request)
def fileFinished(ignored):
handle.close()
request.finish()
d.addCallback(fileFinished).addErrback(fileFinished)