フォームよるファイルアップロードの仕様

広告

HTMLのフォームを使ったファイルアップロードはRFC1867に従った動作をします。RFC1867は下記に記載があります。

http://www.ietf.org/rfc/rfc1867.txt

フォームを使ったファイルアップロードを行った際にサーバ側にどのようなデータが送られてくるのかについて、上記ページによると次のように書かれています。

下記のようなフォームからファイルをアップロードしたとします。この場合、テキストが1つとアップロードするファイルとなりますが、「file1.txt」と「file2.gif」の2つのファイルをアップロードしたとします。

<form action="http://server.dom/cgi/handle"
         enctype="multipart/form-data"
         method="post">
What is your name? <input type="text" name="submitter">
What files are you sending? <input type="file" name="pics">
</form>

するとサーバ側には下記のようなデータが送られてきます。

Content-type: multipart/form-data, boundary=AaB03x

    --AaB03x
    content-disposition: form-data; name="submitter"

    Joe Blow
    --AaB03x
    content-disposition: form-data; name="pics"
    Content-type: multipart/mixed, boundary=BbC04y

        --BbC04y
        Content-disposition: attachment; filename="file1.txt"
        Content-Type: text/plain

        ... contents of file1.txt ...
        --BbC04y
        Content-disposition: attachment; filename="file2.gif"
        Content-type: image/gif
        Content-Transfer-Encoding: binary

        ...contents of file2.gif...
        --BbC04y--
    --AaB03x--

※各行の先頭のスペースは見やすいように適当に入れてあります。

複数のデータがまとめてサーバに送られてくる場合、それぞれのデータを区別するために境界線で分けられます。境界線は「boudary=」の後に書かれたランダムな文字によって作られます。上記の場合で言えば「AbB03」と「BbC04」が境界線を表すために決められたランダムな文字列となります。

その為、上記はまず大きな2つのブロックに分けられます。1つ目は次の部分です。

--AaB03x
content-disposition: form-data; name="submitter"

Joe Blow
--AaB03x

2つ目は次の部分です。

--AaB03x
content-disposition: form-data; name="pics"
Content-type: multipart/mixed, boundary=BbC04y

    --BbC04y
    Content-disposition: attachment; filename="file1.txt"
    Content-Type: text/plain

    ... contents of file1.txt ...
    --BbC04y
    Content-disposition: attachment; filename="file2.gif"
    Content-type: image/gif
    Content-Transfer-Encoding: binary

    ...contents of file2.gif...
    --BbC04y--
--AaB03x--

1つ目のブロックには、フォームの1番目のコントロールに入力された「名前」の値が入っています。この場合は「Joe Blow」です。2つ目のブロックにはアップロードされたファイルのデータが入っています。

今回はアップロードされたファイルが2つあったので、2つ目のブロックはさらに別の境界線によって2つのブロックに分けられています。1つ目は次の部分です。

--BbC04y
Content-disposition: attachment; filename="file1.txt"
Content-Type: text/plain

... contents of file1.txt ...
--BbC04y

2つ目は次の部分です。

--BbC04y
Content-disposition: attachment; filename="file2.gif"
Content-type: image/gif
Content-Transfer-Encoding: binary

...contents of file2.gif...
--BbC04y--

こちらのブロックでは、アップロードされた2つのファイルが境界線で区切られて格納されています。

このようにフォームから送られてきたデータは、境界線によって区切られ1つのまとまったデータとして送られてきます。よって送られ来たデータを処理するには境界線によって各ブロックからデータを取り出して処理すればいいわけです。

このデータをブロック毎に分割してくれる処理をしてくれるのがJakarta Commons FileUploadです。

( Written by Tatsuo Ikura )

関連記事 (一部広告含む)