まだ重たいCMSをお使いですか?
毎秒1000リクエスト を捌く超高速CMS「adiary

2006/04/21(金)multipart/form-data

日記への画像添付に向けて、multipart/form-data の解析ルーチンでも作ろうかと思って調べ始めてみると……

  1. とりあえずネットで仕様書を検索。RFC1876, RFC2388だということは分かるが……見ても分かりにくいぞ、これは。
  2. 仕方ないので perl で書かれたサンプル(アップローダ)でも探してみると、CGI.pm を使用したものばかり見つかる。
  3. しょうがないので、ENCTYPE="multipart/form-data" なフォームで POST してデータを全部ファイルにはき出してみる。実に分かりやすい。
  4. 結局 boundary を認識しつつ読み出す必要があるので、perl 的にデリミタを書き換えてと思ったものの、例えば 100MB とか大きなファイルを受け取るとき、それだけメモリを食うこととなる。 → 常識的にはNG
  5. なんかいい方法ないかなぁーと再びネット内のcgiスクリプトを検索。…………見るんじゃなかった(笑)

どうしてネットに転がってる cgi (with perl) スクリプトってのは、有名どころ含め、汚いのばかりかなぁ(苦笑)*1

*1 : もっとも2年ぐらい前までヒトのこと言えないソースばかりですが(汗)

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