web-dev-qa-db-ja.com

リクエスト投稿から受信したmultipart / form-dataを解析します

リクエストライブラリを使用して、Webサービスクライアントを作成しています。ファイルとtext-jsonを含むmultipart/form-dataのデータを取得しています。どうやって解析するのかわからない。 pythonのmultipart/form-data形式を解析するための適切なライブラリはありますか?それとも自分でパーサーを作成する必要がありますか?

私のコード:

data = {
  "prototypeModel" :('prototypeModel', open(prototypeModel, 'rb'), 'application/octet-stream', {'Expires': '0'}),
  "mfcc_1" : ('mfcc', open(mfcc_1, 'rb'), 'application/octet-stream', {'Expires': '0'}),
  "mfcc_2" : ('mfcc', open(mfcc_2, 'rb'), 'application/octet-stream', {'Expires': '0'}),
  "mfcc_3" : ('mfcc', open(mfcc_3, 'rb'), 'application/octet-stream', {'Expires': '0'}),
}

print( '---------------------- start enroll ----------------------')
testEnrollResponse = requests.post(server+sessionID, files = data, json = declaredParameters)

b '\ r\n--c00750d1-8ce4-4d29-8390-b50bf02a92cc\r\nContent-Disposition:form-data; name = "playbackHash"\r\nContent-Type:application/octet-stream\r\n\r\n\x16\x00\x00\x00\x00\x00\x00\x00serialization :: archive\n\x00\x04\x08\x04 .... x00\x00R\x94\x9bp\x8c\x00\r\n--c00750d1-8ce4-4d29-8390-b50bf02a92cc\r\nContent-Disposition:form-data; name = "usersMFCC"\r\nContent-Type:application/octet-stream\r\n\r\n\x16\x00\x00\x00\x00\x00\x00\x00serialization :: archive\n\x00\x04\x08\x04\x08\x01\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x16\x00\x00\x00\x00\x00\x00u\xbd\xb4/\ xda1\xea\xbf\x0f\xed\xa2 <\ xc9\xf8\xe7\xbf?\ xd5\xf06u\xe7\xf0\xbf\xd4\x8d\xd4\xa1F\xbe\x03 @\x85X!\ x19\xd8A\x06 @\x8co\xf7\r...。
x80\xd9\x95Yxn\xd0?\ r\n--c00750d1-8ce4-4d29-8390-b50bf02a92cc\r\nContent-Disposition:form-data; name = "scoreAndStatus"\r\nContent-Type:application/json; charset = utf-8\r\n\r\n {"lexLikelihood":1.544479046897232、 "overallScore":-nan、 "playbackLikelihood":-inf、 "status":{"errorCode":0、 "errorMessage": " "}}\r\n--c00750d1-8ce4-4d29-8390-b50bf02a92cc-\r\n '

より多くのバイナリデータを「.....」に置き換えました

10
user3131037

multipart/form-data応答を受信して​​いる場合は、次のようにrequests-toolbeltライブラリを使用して解析できます。

$ pip install requests-toolbelt

インストール後

from requests_toolbelt.multipart import decoder

testEnrollResponse = requests.post(...)
multipart_data = decoder.MultipartDecoder.from_response(testEnrollResponse)

for part in multipart_data.parts:
    print(part.content)  # Alternatively, part.text if you want unicode
    print(part.headers)

Flaskのコードサンプル、使用 https://github.com/defnull/multipart

import multipart as mp
from multipart import tob

try:
    from io import BytesIO
except ImportError:
    from StringIO import StringIO as BytesIO

@app.route('/', methods=["GET","POST"])
def index():
        ...
        Elif flask.request.method == "POST":
                data = flask.request.data
                s = data.split("\r")[0][2:]
                p = mp.MultipartParser(BytesIO(tob(data)),s)
                blob = p.parts()[0].value
                f = open("file.bin","wb")
                f.write(blob.encode("latin-1"))
                f.close()
4

マルチパートデータを解析する 実例 は次のとおりです。インタラクティブなpythonプロンプトで試すことができます。

import email

msg = email.message_from_string('''\
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="    XXXX"

--    XXXX
Content-Type: text/plain


--    XXXX
Content-Type: text/plain

--    XXXX--
''')

msg.is_multipart()

システムでの動作がわかったら、POSTデータから独自の電子メールメッセージを作成し、同じ方法で解析できます。生の場合 投稿本文 =文字列として、残りの必要な情報はリクエストヘッダーにあります。わかりやすくするためにここにインデントを追加しました。ブロック文字列に無関係なインデントを含めないでください。

    epost_data = '''\
MIME-Version: 1.0
Content-Type: %s

%s''' % (self.headers['content-type'], post_data)

    msg = email.message_from_string(post_data)

    if msg.is_multipart():
        for part in msg.get_payload():
            name = part.get_param('name', header='content-disposition')
            filename = part.get_param('filename', header='content-disposition')
            # print 'name %s' % name # "always" there
            # print 'filename %s' % filename # only there for files...
            payload = part.get_payload(decode=True)
            print payload[:100] # output first 100 characters

最初の%sはコンテンツタイプに置き換えられ、2番目はpost_dataに置き換えられます。その後、ペイロードをファイルなどに書き込むことができます。

ファイルを保存することによるセキュリティへの影響を考慮するように注意してください。投稿されたファイル名を信頼できない可能性があります。たとえば、一部のWebサーバーでは../../filename.shで始まる可能性があるため、/my-folder/../../filename.shを書き込もうとすると、攻撃者は悪意のあるファイルを外部に配置する可能性があります。ファイルを保存しようとしている場所。ファイル自体を信頼する前に、許可されたタイプであるファイルを強力に検証することもお勧めします。攻撃者にシステム上のファイルを上書きさせたくありません。

2
user2905353