From 86bdb2edc65cf628b4887c06b3dab254a67bfe45 Mon Sep 17 00:00:00 2001 From: Kenta Sato Date: Tue, 6 Nov 2012 06:05:28 +0900 Subject: [PATCH] enable to handle multibyte filenames I got tons of "Write failed: Wide character in syswrite at \ /usr/lib/perl/5.12/IO/Handle.pm line 207." errors when I tried to handle multi-byte filenames through 'render_file' method. Filenames encoded in UTF-8 can suppress these errors. --- lib/Mojolicious/Plugin/RenderFile.pm | 6 ++- t/multibyte_filename.t | 69 ++++++++++++++++++++++++++++ "t/\346\274\242\345\255\227.txt" | 1 + 3 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 t/multibyte_filename.t create mode 100644 "t/\346\274\242\345\255\227.txt" diff --git a/lib/Mojolicious/Plugin/RenderFile.pm b/lib/Mojolicious/Plugin/RenderFile.pm index a00727d..48fb707 100644 --- a/lib/Mojolicious/Plugin/RenderFile.pm +++ b/lib/Mojolicious/Plugin/RenderFile.pm @@ -4,6 +4,7 @@ use Mojo::Base 'Mojolicious::Plugin'; use strict; use warnings; use File::Basename; +use Encode qw( encode decode_utf8 ); use Mojo::Util 'quote'; our $VERSION = '0.05'; @@ -15,7 +16,7 @@ sub register { my $c = shift; my %args = @_; - my $filename = $args{filename}; + my $filename = decode_utf8($args{filename}); my $status = $args{status} || 200; my $content_disposition = $args{content_disposition} || 'attachment'; @@ -26,7 +27,7 @@ sub register { # Create asset my $asset; - if ( my $filepath = $args{filepath} ) { + if ( my $filepath = decode_utf8($args{filepath}) ) { unless ( -f $filepath && -r $filepath ) { $c->app->log->error("Cannot read file [$filepath]. error [$!]"); return; @@ -45,6 +46,7 @@ sub register { # Create response headers $filename = quote($filename); # quote the filename, per RFC 5987 + $filename = encode("UTF-8", $filename); my $headers = Mojo::Headers->new(); $headers->add( 'Content-Type', $content_type . ';name=' . $filename ); diff --git a/t/multibyte_filename.t b/t/multibyte_filename.t new file mode 100644 index 0000000..16ee9de --- /dev/null +++ b/t/multibyte_filename.t @@ -0,0 +1,69 @@ +use Mojo::Base -strict; + +use Test::More; +use Encode; + +use Mojolicious::Lite; +use Test::Mojo; + +use lib '../lib'; +use utf8; + +use File::Basename qw/dirname/; +use File::Spec::Functions qw/rel2abs/; + +my $FILE = rel2abs( dirname(__FILE__) . '/' . '漢字.txt' ); + +plugin 'RenderFile'; + +get "/default" => sub { + my $self = shift; + $self->render_file( + filepath => $FILE + ); +}; + +get "/filename" => sub { + my $self = shift; + $self->render_file( + filepath => $FILE, + filename => '別名.txt', + ); +}; + +get "/encoded" => sub { + my $self = shift; + $self->render_file( + filepath => encode_utf8 $FILE, + ); +}; + +get "/encoded_filename" => sub { + my $self = shift; + $self->render_file( + filepath => encode_utf8 $FILE, + filename => encode_utf8 '別名.txt', + ); +}; + + +my $t = Test::Mojo->new; + +$t->get_ok("/default") + ->status_is(200) + ->content_is( encode_utf8 '漢字(かんじ)は、古代中国に発祥を持つ文字。' ) + ->header_is( 'Content-Disposition' => encode_utf8 'attachment;filename="漢字.txt"' ); + +$t->get_ok("/filename") + ->status_is(200) + ->header_is( 'Content-Disposition' => encode_utf8 'attachment;filename="別名.txt"' ); + +$t->get_ok("/encoded") + ->status_is(200) + ->header_is( 'Content-Disposition' => encode_utf8 'attachment;filename="漢字.txt"' ); + +$t->get_ok("/encoded_filename") + ->status_is(200) + ->header_is( 'Content-Disposition' => encode_utf8 'attachment;filename="別名.txt"' ); + +done_testing(); diff --git "a/t/\346\274\242\345\255\227.txt" "b/t/\346\274\242\345\255\227.txt" new file mode 100644 index 0000000..5624167 --- /dev/null +++ "b/t/\346\274\242\345\255\227.txt" @@ -0,0 +1 @@ +漢字(かんじ)は、古代中国に発祥を持つ文字。 \ No newline at end of file