在WSGI中,通過讀取文件類對象environ['wsgi.input']
來消費發佈數據。如果堆棧中的第二個元素也想讀取發佈數據,它可能會通過讀取什麼時候沒有更多需要讀取來掛起程序。如果我想多次處理POST數據,如何複製wsgi.input?
我應該如何複製POST數據以便可以多次處理?
在WSGI中,通過讀取文件類對象environ['wsgi.input']
來消費發佈數據。如果堆棧中的第二個元素也想讀取發佈數據,它可能會通過讀取什麼時候沒有更多需要讀取來掛起程序。如果我想多次處理POST數據,如何複製wsgi.input?
我應該如何複製POST數據以便可以多次處理?
如果你要一舉讀它,你總是可以讀取它,創建你讀過的東西,一個CStringIO類似文件的對象,然後分配給它回來,像這樣:
import cStringIO
import copy
lines = []
for line in environ['wsgi.input']:
lines.append(line)
newlines = copy.copy(lines)
environ['wsgi.input'] = cStringIO.StringIO(''.join(newlines))
有最有可能做到這一點更有效的方式,但我一般找WSGI的帖子東西很脆,如果你想做的任何事情不平凡的(如讀取後的數據muptiple次)......
你可以嘗試將流的文件複製品放回環境中:
from cStringIO import StringIO
length = int(environ.get('CONTENT_LENGTH', '0'))
body = StringIO(environ['wsgi.input'].read(length))
environ['wsgi.input'] = body
雖然需要做到這一點有點味道。理想情況下,只有一段代碼應該解析查詢字符串和後主體,並將結果傳遞給其他組件。
您不應該依賴於能夠將內容長度默認爲-1。 WSGI規範中沒有什麼說實現應該接受-1作爲參數read()來表示讀取所有輸入。在這種情況下,實施可能會決定提出例外。實際上,該規範甚至可能會說,如果CONTENT_LENGTH不存在或爲空,則必須將其解釋爲「0」,或者不可輸入。 – 2009-11-23 22:07:11
啊葉......不太清楚爲什麼我這麼說,我自己的實際代碼使用0 :-)你打算在WSGI中改變這種行爲,對吧? – bobince 2009-11-23 23:40:52
我有點懷疑WSGI現在會看到任何變化。 – 2009-11-24 00:44:37
而且,bobince _is_是更有效的方法:) – 2009-11-23 14:33:57
在wsgi.input中使用for/in循環,就像內存/時間效率非常低。這是因爲如果在最壞的情況下,你有一個大文件,其中所有數據都由空行組成,那麼你最終會創建一個非常大的列表,其中每個條目都是單個字符。也不知道爲什麼你打擾copy.copy(),因爲無論如何你都可以立即將它連接在一起。 – 2009-11-23 22:11:40