はじめに
このエントリを公開後,Plackの中の人でもあるmiyagawaさんより,同エントリの内容が現在のバージョンのものにおいて正しくない,という旨のご指摘をいただきました.ありがとうございます.(実際には,0.90*系と0.99_*系との違い,ということで無問題?)
ということで,現時点で最新(ですよね?)の「0.99_5(DEVELOPER RELEASE)」を入れ,同バージョンにおけるPlack::Request,Plack::Request::Uploadのドキュメントを確認し,修正したものを以下に掲載します.
アップロードフォーム
前エントリと同様のものです.
<form action="" method="post" enctype="multipart/form-data"> ファイル 1-1 <input type="file" name="file1" value="" /> ファイル 1-2 <input type="file" name="file1" value="" /> ファイル 2 <input type="file" name="file2" value="" /> <input type="submit" name="submit" value="アップロード!" /> </form>
Plack::Request::Uploadオブジェクトを取得する
アップロードオブジェクトの集合はHash::MultiValueオブジェクトとして
Plack::Requestオブジェクトのuploadsメソッドを呼ぶところは,前と変わりありませんが,得られるものがHash::MultiValueオブジェクトとなりました.
use Data::Dumper; # $req is Plack::Request object my $uploads = $req->uploads; print ref $uploads;
Hash::MultiValue
データ構成
今回もスペースの都合上,$VAR1 =な部分は削ってます.
use Data::Dumper; print Dumper $uploads;
bless( {
'file2' => bless( {
'headers' => bless( {
'content-disposition' => 'form-data; name="file2"; filename="9a8ba767.jpg"',
'content-type' => 'image/jpeg'
}, 'HTTP::Headers' ),
'filename' => '9a8ba767.jpg',
'tempname' => '/tmp/f2cY6WMe0_',
'size' => 102723
}, 'Plack::Request::Upload' ),
'file1' => bless( {
'headers' => bless( {
'content-disposition' => 'form-data; name="file1"; filename="7a98edb3.jpg"',
'content-type' => 'image/jpeg'
}, 'HTTP::Headers' ),
'filename' => '7a98edb3.jpg',
'tempname' => '/tmp/6hLGbxAmym',
'size' => 301283
}, 'Plack::Request::Upload' )
}, 'Hash::MultiValue' );キーにフォームのフィールド名,値にPlack::Request::Uploadオブジェクトが1ファイルにつき1つ,という構成になっているのがわかr...おっと,Data::Dumperでの出力では,キーが重複した分については表示されないんでした.このあたりは次節で確認してみます.
特定のフィールドの要素を取得する
print Dumper $uploads->{file1}; print Dumper $uploads->{file2};
$VAR1 = bless( {
'headers' => bless( {
'content-disposition' => 'form-data; name="file1"; filename="7a98edb3.jpg"',
'content-type' => 'image/jpeg'
}, 'HTTP::Headers' ),
'filename' => '7a98edb3.jpg',
'tempname' => '/tmp/j4gQY8Am6V',
'size' => 301283
}, 'Plack::Request::Upload' );
$VAR1 = bless( {
'headers' => bless( {
'content-disposition' => 'form-data; name="file2"; filename="9a8ba767.jpg"',
'content-type' => 'image/jpeg'
}, 'HTTP::Headers' ),
'filename' => '9a8ba767.jpg',
'tempname' => '/tmp/GbG3P_7Fhp',
'size' => 102723
}, 'Plack::Request::Upload' );print Dumper $uploads->get_all('file1'); print Dumper $uploads->get_all('file2');
$VAR1 = bless( {
'headers' => bless( {
'content-disposition' => 'form-data; name="file1"; filename="6ac3d070.jpg"',
'content-type' => 'image/jpeg'
}, 'HTTP::Headers' ),
'filename' => '6ac3d070.jpg',
'tempname' => '/tmp/E63LJB8y1s',
'size' => 59307
}, 'Plack::Request::Upload' );
$VAR2 = bless( {
'headers' => bless( {
'content-disposition' => 'form-data; name="file1"; filename="7a98edb3.jpg"',
'content-type' => 'image/jpeg'
}, 'HTTP::Headers' ),
'filename' => '7a98edb3.jpg',
'tempname' => '/tmp/38aWzTxmFv',
'size' => 301283
}, 'Plack::Request::Upload' );
$VAR1 = bless( {
'headers' => bless( {
'content-disposition' => 'form-data; name="file2"; filename="9a8ba767.jpg"',
'content-type' => 'image/jpeg'
}, 'HTTP::Headers' ),
'filename' => '9a8ba767.jpg',
'tempname' => '/tmp/jFgvreL2Ol',
'size' => 102723
}, 'Plack::Request::Upload' );Data::Dumperでは確認できなかった分についてもしっかり取得できていますね.
Plack::Request::Uploadオブジェクトのメソッド
こちらにも変更がありますね.
size
アップロードされたファイルのサイズが得られます.
my ($up) = $uploads->get_all('file1'); print Dumper $up->size;
$VAR1 = 59307;
path
ファイルは自動的に一時ファイルとして保存されるわけですが,このメソッドは,その保存先のパスを取得できます.
print Dumper $up->path;
$VAR1 = '/tmp/FmOgLKzAZQ';
content_type
アップロードされたファイルのContent-Typeが得られます.
print Dumper $up->content_type;
$VAR1 = 'image/jpeg';
filename,basename
それぞれ,「original filename in the client」「basename for “filename”」ということですが,まだよくわかっていません><
print Dumper $up->filename; print Dumper $up->basename;
$VAR1 = '6ac3d070.jpg'; $VAR1 = '6ac3d070.jpg';
参考
おわりに
以上,Plackにおけるファイルアップロード処理のための準備(というか,もうファイル自体はアップロードされてしまっていますがw)に関するメモの修正版でした.
All parameter-related methods such as parameters, body_parameters, query_parameters and uploads now contains Hash::MultiValue objects, rather than scalar or an array reference depending on the user input which is insecure. See Hash::MultiValue for more about this change.
INCOMPATIBILITIES – Plack::Request – search.cpan.org
ということなので,Hash::MultiValueオブジェクトの扱いに慣れておいて損はないかと思います.



