2006/04/21(金)multipart/form-data
日記への画像添付に向けて、multipart/form-data の解析ルーチンでも作ろうかと思って調べ始めてみると……
- とりあえずネットで仕様書を検索。RFC1876, RFC2388だということは分かるが……見ても分かりにくいぞ、これは。
- 仕方ないので perl で書かれたサンプル(アップローダ)でも探してみると、CGI.pm を使用したものばかり見つかる。
- しょうがないので、ENCTYPE="multipart/form-data" なフォームで POST してデータを全部ファイルにはき出してみる。実に分かりやすい。
- 結局 boundary を認識しつつ読み出す必要があるので、perl 的にデリミタを書き換えてと思ったものの、例えば 100MB とか大きなファイルを受け取るとき、それだけメモリを食うこととなる。 → 常識的にはNG
- なんかいい方法ないかなぁーと再びネット内のcgiスクリプトを検索。…………見るんじゃなかった(笑)
どうしてネットに転がってる cgi (with perl) スクリプトってのは、有名どころ含め、汚いのばかりかなぁ(苦笑)*1
multipart/form-dataの例
というわけで例をアップしておきます。参考にどうぞ。アップロードしたファイルは、C++のソースです。
$ENV{CONTENT_TYPE} == "multipart/form-data; boundary=XX-15688238854994"
--XX-15688238854994 Content-Disposition: form-data; name="upload"; filename="form.cpp" Content-Type: application/octet-stream #include <stdio.h> #include <stdlib.h> #include <string.h> : :(中略) : #endif --XX-15688238854994 Content-Disposition: form-data; name="action" diary_edit --XX-15688238854994 Content-Disposition: form-data; name="edit_pkey_int" 6 --XX-15688238854994 : :(中略) : --XX-15688238854994 Content-Disposition: form-data; name="char2" auto --XX-15688238854994--
ちなみに、改行コードは \r\n (CR/FL) と決まっています。明示的に書くと次のような感じです。
<input type="hidden" name="action" value="diary_edit"> --XX-15688238854994\r\n Content-Disposition: form-data; name="action"\r\n \r\n diary_edit\r\n --XX-15688238854994\r\n