簡體   English   中英

Python服務器cgi.FieldStorage解析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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM