2009-11-24 53 views
1

我試圖建立與Django的一個RESTful API來分享的MP3 - 右前面:這是一個玩具應用,從來沒有進入生產,所以它並不需要擴展或擔心(我希望)關於版權魔鬼。 我現在的問題是我有一個Django視圖,我想成爲HTTP PUT請求的端點。 PUT的頭文件將包含元數據,而主體將完全是二進制文件。問題把二進制數據的Django

下面是我(想)打的實際看法。請注意,記錄表明,控制流不會進入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處理程序做得很好,謝謝)。日誌記錄表明請求實際上沒有將其傳遞給處理程序代碼。

周圍的Googling使我的問題跟蹤表明問題是httplib的的處理錯誤的,同時上傳大文件(這個人是3.7 MB)。

所以,我並不羞於承認,我從我的深度這裏 - 我怎麼能確定是什麼原因造成的錯誤?我是否正確地格式化了我的請求(p.s.我也嘗試過對身體進行編碼,結果相同)?從更大的意義上說,我正在做的(測試,而不是生活中)是否合理?它與開發服務器上的可配置設置有什麼關係?如果我嘗試將它放在Apache上,這些問題是否會消失?非常感激你的幫助。

+2

你能後接受認沽Django的看法?一個猜測可能是,如果你使用django開發者服務器(manage.py runserver),它可能不會處理大文件請求嗎? – Purrell 2009-11-25 01:15:21

+0

這解決了嗎? – bentford 2010-01-04 14:03:37

回答

0

它出現的問題是開發服務器的處理大量的請求。使用mod_wsgi部署到apache後,此問題消失。不過許多關於REST的文件上傳懸而未決的問題對我來說...