はじめに
MIME-TYPEの中でも複雑かつ、あまり普段は意識しないのが、multipart/form-data
。HTMLでformを作り、formタグの属性でenctype="multipart/form-data"
を指定することで送ることができる。プリミティブなHTTPクライアントを使って、自前でmultipart/form-data
を投げようとして、いくつかハマったので、改めてRFCの仕様を読んだのでメモ。
サンプル
リクエストヘッダ
Content-Type: multipart/form-data; boundary=--hogehoge
リクエストボディ
--hogehoge
Content-Disposition: form-data; name="user_name"
Content-Type: text/plain
test
--hogehoge
Content-Disposition: form-data; name="email"
sample@mail.com
--hogehoge
Content-Disposition: form-data; name="gender"
male
--hogehoge
Content-Disposition: form-data; name="user_profile" filename="image.jpeg"
Content-Type: image/jpeg
\xff\xd8\....
--hogehoge--
リクエストヘッダ部
Content-Type: multipart/form-data; boundary=hogehoge;
MIME-TYPEの指定と、そのパラメータとしてboundary
の指定が必須となる(MUST)。このboundary(と、先頭につけた--)によってリクエストボディの中身を区切ることができるようになる。
リクエストボディ部
Content-Disposition: form-data; name="user_name"
この各Partのヘッダ情報をMIMEヘッダフィールドと呼ぶ。この**MIMEヘッダフィールドの文字コードはUS-ASCIIしか許容されない。**フォームの各部分には必ずContent-Disposition
と、そのパラメータであるname
をつけなければならない(MUST)。**また、改行コードは必ずCRLFを使用すること。**また、そのpartがファイルを表す場合、filenameパラメータをつけることが推奨される(SHOULD)。
Content-Type: text/plain
partごとに、mime-typeを設定することができる。デフォルトはtext/plainになっており、設定は任意(MAY)。ファイルを表すpartの場合、デフォルトはapplication/octet-streamとなるので、つけることが推奨される(SHOULD)。
バイナリを送信する際
あとがき
末尾のboundaryは、行の最後に--をつけることや、CRLFでないとならないことや、送信先のサーバがMUST以外のMIMEヘッダフィールドを必須にしてないか確認したりと色々ハマりポイントはあった。難しいですね。