2011-05-22 65 views
4

我正在構建一個簡單的Web服務,要求對所有請求進行簽名。使用包括請求主體的請求數據來生成簽名散列。我的願望是擁有一個驗證請求籤名的中間件組件,如果簽名是無效的,則會返回錯誤。問題是中間件需要使用env ['wsgi.input']。read()讀取請求主體。這會將請求正文字符串的指針推進到結尾,這使得執行鏈中其他組件無法訪問數據。Python WSGI:多次讀取env ['wsgi.input']

有什麼辦法讓env ['wsgi.input']可以被讀取兩次嗎?

例:

from myapp.lib.helpers import sign_request 
from urlparse import parse_qs 
import json 

class ValidateSignedRequestMiddleware(object): 
    def __init__(self, app, secret): 
     self._app = app 
     self._secret = secret 

    def __call__(self, environ, start_response): 
     auth_params = environ['HTTP_AUTHORIZATION'].split(',', 1) 
     timestamp = auth_params[0].split('=', 1)[1] 
     signature = auth_params[1].split('=', 1)[1] 

     expected_signature = sign_request(
      environ['REQUEST_METHOD'], 
      environ['HTTP_HOST'], 
      environ['PATH_INFO'], 
      parse_qs(environ['QUERY_STRING']), 
      environ['wsgi.input'].read(), 
      timestamp, 
      self._secret 
     ) 
     if signature != expected_signature: 
      start_response('400 Bad Request', [('Content-Type', 'application/json')]) 
      return [json.dumps({'error': ('Invalid request signature',)})] 

     return self._app(environ, start_response) 
+0

可能重複[如何複製wsgi.input如果我想多次處理POST數據?](http://stackoverflow.com/questions/1783383/how-do-i-copy-wsgi-input-if-i-want-to-process-post-data - 不止一次) – 2011-05-22 19:59:28

回答

3

你可以嘗試尋求回到起點,但你會發現,你將有一個StringIO來取代它包含你剛纔讀了什麼。

+0

尋求似乎沒有在environ ['wsgi.input']上工作,用StringIO取代,感覺有點骯髒,但謝謝。 – 2011-05-22 20:17:59