我正在尝试用Django构建一个RESTful api来共享mp3 - 就在前面:它是一个玩具应用程序,从不投入生产,所以它不需要扩展或担心(我希望)有关版权恶魔。 我现在的问题是我有一个Django视图,我想成为HTTP PUT请求的端点。 PUT的标题将包含元数据,而正文将仅包含二进制文件。
这是我(尝试)击中的实际视图。请注意,日志记录表明控制流永远不会进入put()方法,我认为这是正确的,如果不是特别健壮:
class UserSong(RESTView):
logging.debug('entering UserSong.put')
def put(self, request, username=''):
if request.META['Content-Type'] != 'octet/stream':
raise Http400()
title = request.META['X-BD-TITLE'] if 'X-BD-TITLE' in request.META else 'title unknown'
artist = request.META['X-BD-ARTIST'] if 'X-BD-ARTIST' in request.META else 'artist unknown'
album = request.META['X-BD-ALBUM'] if 'X-BD-ALBUM' in request.META else 'album unknown'
song_data = b6decode(request.raw_post_data)
song = Song(title=title, artist=artist, playcount=playcount, is_sample=is_sample, song_data=song_data, album=album)
song.save()
return HttpResponse('OK', 'text/plain' , 201)
def __call__(self, request, *args, **kwargs):
logging.basicConfig(filename=LOGFILE,level=logging.DEBUG)
try:
if request.method == 'DELETE':
return self.delete(request, *args, **kwargs)
elif request.method == 'GET':
return self.get(request, *args, **kwargs)
elif request.method == 'POST':
return self.post(request, *args, **kwargs)
elif request.method == 'PUT':
return self.put(request, *args, **kwargs)
except:
raise Http404()
在测试中,我能够使用Django的单元测试框架进行单元测试,但我不相信它是准确地模仿真实生活。所以,我破解了打开httplib,并构建了一个自己的PUT。这是我以交互方式执行的代码:
>>>method = 'PUT'
>>>url = 'accounts/test/songs/'
>>>f = open('/Users/bendean/Documents/BEARBOT.mp3')
>>>data = f.read()
>>>body = data
>>>headers = {'X-BD-ARTIST' : 'BEARBOT' , 'X-BD-ALBUM':'','X-BD-TITLE':'LightningSPRKS'}
>>>headers['CONTENT-TYPE'] = 'octet/stream'
>>>import httplib
>>>c = httplib.HTTPConnection('localhost:8000')
>>>c.request(method, url, body, headers)
我得到的反应不是很好
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/httplib.py", line 880, in request
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/httplib.py", line 914, in _send_request
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/httplib.py", line 719, in send
File "<string>", line 1, in sendall
error: [Errno 54] Connection reset by peer
虽然有时我得到
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/httplib.py", line 880, in request
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/httplib.py", line 914, in _send_request
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/httplib.py", line 719, in send
File "<string>", line 1, in sendall
error: [Errno 32] Broken pipe
我相信我的网址正常工作(GET处理程序做得很好,谢谢)。日志记录表明请求实际上并不是处理程序代码。
谷歌搜索引导我发出跟踪器,建议问题在于httplib在上传大文件时处理错误(这个是3.7 MB)。所以,我并不羞于承认我不在这里 - 我怎样才能确定导致错误的原因?我是否正确格式化了我的请求(p.s.我也试过b64encoding the body,结果相同)?从更广泛的意义上说,我正在做什么(测试,而不是在生活中)是合理的?它与开发服务器上的可配置设置有什么关系吗?如果我尝试将这个问题放在Apache上,这些问题会消失吗?非常感谢您的帮助。
答案 0 :(得分:0)
看起来问题出在开发服务器处理大型请求中。在使用mod_wsgi部署到apache之后,这个问题就消失了。关于RESTful文件上传,我仍有很多未解决的问题......