(以前疑問に思ったところで再び同じ疑問を感じて解決していないので記録しておく)
RFC 2388はmultipart/form-data形式を定義している。
フォームを使うとき特に指定をしないと、multipart/form-data形式ではなくapplication/x-www-form-urlencoded形式によって内容が送信される。例えば次のようなフォームを考える。
<form method="post" action="server_action.cgi"> <p><textarea name="xxxx"> 11111 22222</textarea></p> <p><input type="checkbox" name="yyyy" checked></p> <p> <input type="submit"> </p> </form>
このときリクエストのボディ部分は次のようになる。
xxxx=11111%0D%0A22222&yyyy=on
同じフォームでmultipart/form-data形式を指定したとする。
<form method="post" action="server_action.cgi" enctype="multipart/form-data">
するとリクエストボディは次のようなものになる(区切りを示す文字列は色々変わる)。
-----------------------------174406726119144318502035190680 Content-Disposition: form-data; name="xxxx" 11111 22222 -----------------------------174406726119144318502035190680 Content-Disposition: form-data; name="yyyy" on -----------------------------174406726119144318502035190680--
multipart/form-data形式はファイルを送信するためにも使われる。
<p><input type="file" name="zzzz"></p>
-----------------------------8062466261463433673562940811 Content-Disposition: form-data; name="xxxx" 11111 22222 -----------------------------8062466261463433673562940811 Content-Disposition: form-data; name="yyyy" on -----------------------------8062466261463433673562940811 Content-Disposition: form-data; name="zzzz"; filename="sample.txt" Content-Type: text/plain A text file. -----------------------------8062466261463433673562940811--
それでよく判らないのは「name="xxxx"」や「filename="sample.txt"」の右辺の引用符は必須なのかどうか、ということ。
RFC 2388に出てくる二つの例はいずれも引用符を使っている。
RFC 2388
3節:"multipart/form-data" contains a series of parts. Each part is expected to contain a content-disposition header [RFC 2183] where the disposition type is "form-data", and where the disposition contains an (additional) parameter of "name", where the value of that parameter is the original field name in the form. For example, a part might contain a header: Content-Disposition: form-data; name="user" with the value corresponding to the entry of the "user" field. Field names originally in non-ASCII character sets may be encoded within the value of the "name" parameter using the standard method described in RFC 2047.4.5節:
For example, a form with a text field in which a user typed 'Joe owes <eu>100' where <eu> is the Euro symbol might have form data returned as: --AaB03x content-disposition: form-data; name="field1" content-type: text/plain;charset=windows-1250 content-transfer-encoding: quoted-printable Joe owes =80100. --AaB03x
しかし本文を読んでみても(例では引用符を使っているけれど)引用符が必須であるとは書いてないように思える。
content-disposition headerの形式を定義しているRFC 2183にはファイル名を引用符でくくっていない例が出てくる。
RFC 2183
3節:Content-Type: image/jpeg Content-Disposition: attachment; filename=genome.jpeg; modification-date="Wed, 12 Feb 1997 16:29:51 -0500"; Content-Description: a complete map of the human genome <jpeg data>
それでは引用符は必須ではないといっていいのかというと自信がなくなる。
例えばPerlのCGIモジュールやRubyのCGIライブラリとwebrick/cgiライブラリはnameやfilenameの右辺に引用符が付いていないmultipart/form-dataを処理してくれない。ネット上で実際に送信して試してみても、引用符なしの形式だとうまく処理できていないようだった。そうすると、RFC 2388は引用符を付けるように言っていると読み取るべきなのか。
PythonとGaucheは引用符なしでも処理してくれるのでこちらの動作が正しいようにも思えるのだけど、別の困ったことがある。
Pythonにはmultipart/form-data形式のデータを作るための標準ライブラリがないみたいだからいいのだけど、Gaucheのrfc.httpモジュールのhttp-compose-form-dataは特殊文字などが入っていないかぎり引用符なしでmultipart/form-dataを構築する。そのためGaucheで作ったmultipart/form-data形式のデータをPerlやRubyに食わせても処理してくれない。
結局のところ、RFC 2388やRFC 2183を読み返してみてもどう解釈するのが正しいのか判らないまま。