Twisted无缘无故抛出“只能在Python 2上传递字节”错误
我正在用 twisted 作为我的网页服务器,利用这个设置来提供普通的文本网站和二进制文件下载。
我在六台机器上使用完全相同的设置,唯一的区别是三台运行 Debian,另外三台运行 Ubuntu。
在我的三台 Ubuntu 机器中,有两台出现了这个错误:
Unhandled Error
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/twisted/protocols/basic.py", line 571, in dataReceived
why = self.lineReceived(line)
File "/usr/lib/python2.7/dist-packages/twisted/web/http.py", line 1655, in lineReceived
self.allContentReceived()
File "/usr/lib/python2.7/dist-packages/twisted/web/http.py", line 1730, in allContentReceived
req.requestReceived(command, path, version)
File "/usr/lib/python2.7/dist-packages/twisted/web/http.py", line 826, in requestReceived
self.process()
--- <exception caught here> ---
File "/usr/lib/python2.7/dist-packages/twisted/web/server.py", line 189, in process
self.render(resrc)
File "/usr/lib/python2.7/dist-packages/twisted/web/server.py", line 238, in render
body = resrc.render(self)
File "/usr/lib/python2.7/dist-packages/twisted/web/resource.py", line 250, in render
return m(request)
File "/usr/lib/python2.7/dist-packages/twisted/web/static.py", line 631, in render_GET
producer.start()
File "/usr/lib/python2.7/dist-packages/twisted/web/static.py", line 710, in start
self.request.registerProducer(self, False)
File "/usr/lib/python2.7/dist-packages/twisted/web/http.py", line 872, in registerProducer
self.transport.registerProducer(producer, streaming)
File "/usr/lib/python2.7/dist-packages/twisted/internet/_newtls.py", line 233, in registerProducer
FileDescriptor.registerProducer(self, producer, streaming)
File "/usr/lib/python2.7/dist-packages/twisted/internet/abstract.py", line 112, in registerProducer
producer.resumeProducing()
File "/usr/lib/python2.7/dist-packages/twisted/web/static.py", line 720, in resumeProducing
self.request.write(data)
File "/usr/lib/python2.7/dist-packages/twisted/web/server.py", line 217, in write
http.Request.write(self, data)
File "/usr/lib/python2.7/dist-packages/twisted/web/http.py", line 1001, in write
value = networkString('%s' % (value,))
File "/usr/lib/python2.7/dist-packages/twisted/python/compat.py", line 364, in networkString
raise TypeError("Can only pass-through bytes on Python 2")
exceptions.TypeError: Can only pass-through bytes on Python 2
Unhandled Error
Traceback (most recent call last):
Failure: exceptions.RuntimeError: Producer was not unregistered for /file/10983801
而另一台则运行得很好。
所有三台 Ubuntu 服务器上的 Python 版本都是:ii python2.7 2.7.6-8 amd64
我最近没有更新 Python,也没有对我的代码做任何更改。我还尝试重启机器,但没有成功。
我非常希望能得到一些提示。 在谷歌搜索时只找到了这个链接: 在 Windows 上运行 Portia (scrapy) 但由于我使用的是 2.7.6 和 Linux,这个情况应该不适用。
编辑:附上实际的代码:
class PyQueueFile(Resource):
def __init__(self):
Resource.__init__(self)
self.ipcTalker = talker.Talker()
def getChild(self, convert_id, request):
"""
:param request: The http Request
:type request: twisted.web.http.Request
"""
try:
db = database.Database()
video = db.getVideo(convert_id)
request.setHeader("Content-Disposition",
"attachment; filename=\"" + os.path.basename(video['title'] + "." + video['format']) + "\"")
request.setHeader("Content-type", "application/force-download")
fileResponse = File(video['path'])
except TypeError:
return Page404()
return fileResponse
def fireup():
try:
myconfig = config.Config()
root = Resource()
root.putChild("file", PyQueueFile())
factory = Site(root)
reactor.listenTCP(myconfig.webPort, factory, 100, myconfig.webIp)
reactor.run()
except (KeyboardInterrupt, SystemExit):
reactor.stopListening()
编辑 2: 我也尝试通过 pip 安装 twisted,结果还是同样的问题。 :/
2 个回答
1
在邮件列表的帮助下,我解决了这个问题。
问题是由一个unicode字符串引起的。
把这一行:
"attachment; filename=\"" + os.path.basename(video['title'] + "." + video['format']) + "\"")
改成这样:
"attachment; filename=\"" + str(os.path.basename(video['title']) + "." + video['format']) + "\"")
就解决了这个问题。不过我还是不明白为什么在所有平台上都没有出现这个问题?
3
查看一下在https://docs.python.org/2/howto/unicode.html中关于“unicode文件名”的章节,这里有解释:
>>> import os
>>> os.path.basename(u'/a/b/c')
u'c'
>>> os.path.basename('/a/b/c')
'c'
不过,你的修复方法在文件名中遇到非ASCII字符时会失败,应该使用URL编码(urllib.urlencode)。