![](/img/trans.png)
[英]python cgi.FieldStorage is empty on chunked transport of type multipart/form-data
[英]Python server cgi.FieldStorage parsing multipart/form-data
所以我一直在用Python編寫一個簡單的Web服務器,現在我正在嘗試處理多部分/表單數據POST請求。 我已經可以處理application / x-www-form-urlencoded POST請求,但是相同的代碼不適用於多部分。 如果看起來我有什么誤會,即使有什么小事,也請叫我出來。 另外,如果你們對改善我的代碼有任何建議,請也告訴我:)謝謝!
當請求進入時,我首先對其進行解析,然后將其拆分為標題的字典和用於請求正文的字符串。 我使用它們來構造一個FieldStorage表單,然后可以將其視為字典來提取數據:
requestInfo = ''
while requestInfo[-4:] != '\r\n\r\n':
requestInfo += conn.recv(1)
requestSplit = requestInfo.split('\r\n')[0].split(' ')
requestType = requestSplit[0]
url = urlparse.urlparse(requestSplit[1])
path = url[2] # Grab Path
if requestType == "POST":
headers, body = parse_post(conn, requestInfo)
print "!!!Request!!! " + requestInfo
print "!!!Body!!! " + body
form = cgi.FieldStorage(headers = headers, fp = StringIO(body), environ = {'REQUEST_METHOD':'POST'}, keep_blank_values=1)
這是我的parse_post方法:
def parse_post(conn, headers_string):
headers = {}
headers_list = headers_string.split('\r\n')
for i in range(1,len(headers_list)-2):
header = headers_list[i].split(': ', 1)
headers[header[0]] = header[1]
content_length = int(headers['Content-Length'])
content = conn.recv(content_length)
# Parse Content differently if it's a multipart request??
return headers, content
因此,對於x-www-form-urlencoded POST請求,我可以將FieldStorage形式像字典一樣對待,如果調用,例如:
firstname = args['firstname'].value
print firstname
它會工作。 但是,如果我改為發送多部分POST請求,則最終不打印任何內容。
這是x-www-form-urlencoded請求的正文:firstname = TEST&lastname = rwar
這是多部分請求的主體:--070f6a3146974d399d97c85dcf93ed44 Content-Disposition:form-data; NAME = “姓氏”; 文件名=“姓氏”
rwar --070f6a3146974d399d97c85dcf93ed44 Content-Disposition:表格數據; NAME = “姓名”; 文件名=“姓名”
測試--070f6a3146974d399d97c85dcf93ed44--
所以這是一個問題,如果是多部分請求,是否應該在parse_post中手動解析正文以獲取數據?
還是有我需要/可以用來解析多部分主體的方法?
還是我完全錯了?
再次感謝,我知道這本書讀得很長,但是我想確保我的問題很全面
因此,我解決了我的問題,但是完全是笨拙的。
最終手動解析了請求的主體,這是我編寫的代碼:
if("multipart/form-data" in headers["Content-Type"]):
data_list = []
content_list = content.split("\r\n\r\n")
for i in range(len(content_list) - 1):
data_list.append("")
data_list[0] += content_list[0].split("name=")[1].split(";")[0].replace('"','') + "="
for i,c in enumerate(content_list[1:-1]):
key = c.split("name=")[1].split(";")[0].replace('"','')
data_list[i+1] += key + "="
value = c.split("\r\n")
data_list[i] += value[0]
data_list[-1] += content_list[-1].split("\r\n")[0]
content = "&".join(data_list)
如果有人仍然可以解決我的問題而不必手動解析身體,請告訴我!
有一個streaming-form-data項目,該項目提供了一個Python解析器來解析由multipart/form-data
編碼multipart/form-data
。 它旨在允許以塊的形式解析數據,但是由於沒有強制執行塊大小,因此您可以一次傳遞整個輸入,它就可以完成工作。 它應該可以通過pip install streaming_form_data
。
這是源代碼-https://github.com/siddhantgoel/streaming-form-data
文檔-https: //streaming-form-data.readthedocs.io/en/latest/
免責聲明:我是作者。 當然,如果遇到錯誤,請創建一個問題。 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.