package Sledge::Plugin::Download; # $Id: Download.pm,v 1.3 2003/02/14 07:36:51 miyagawa Exp $ # # Tatsuhiko Miyagawa # Livin' On The EDGE, Limited. # use strict; use vars qw($VERSION); $VERSION = 0.02; use vars qw(@ISA @EXPORT); require Exporter; @ISA = qw(Exporter); @EXPORT = qw(download); sub download { my($self, $filename, $content) = @_; my $type = _dispatch_type($self, $filename); $self->r->header_out('Content-Disposition' => $type->{disposition}); $self->r->content_type($type->{type}); if (defined $content) { $self->r->header_out('Content-Length' => length $content); $self->r->send_http_header; $self->r->print($content); } else { $self->r->send_http_header; } $self->finished(1); # may be early, but no problem } sub _dispatch_type { my($self, $filename) = @_; my $ua = $self->r->header_in('User-Agent'); my $name = _convert($filename); if ($ua !~ /Mac/ && $ua =~ /MSIE/) { my($ver) = $ua =~ /MSIE ([\d\.]+)/; if ($ver < 5) { return { disposition => "inline; filename=$name", type => "application/download; name=$name", }; } else { return { disposition => "attachment; filename=$name", type => "application/download; name=$name", }; } } else { return { disposition => "attachment; filename=$name", type => "application/octet-stream; name=$name", }; } } sub _convert { my $name = shift; return $name if $name =~ /^[\x00-\x7f]+$/; # ascii require Jcode; return Jcode->new($name)->sjis; } 1; __END__ =head1 NAME Sledge::Plugin::Download - HTTP file download enhancemnet =head1 SYNOPSIS package Your::Pages; use Sledge::Plugin::Download; sub dispatch_foo { my $self = shift; $self->download('foo.csv'); while (my $line = <$fh>) { $self->r->print($line); } } # or, if your filesize is small sub dispatch_foo { my $self = shift; my $output = $self->read_content; $self->download("ほげほげ.txt", $output); } =head1 DESCRIPTIO Sledge::Plugin::Download は、ファイルダウンロードダイアログを出す際の、 ブラウザによるバグに対応するためのプラグインです。 =head1 METHODS このプラグインをuseすると、Pagesクラスに C メソッドが追加さ れます。このメソッドは、ファイル名を引数にとり、HTTPダウンロードを開始 するヘッダを出力します。 ファイルの中身が小さく、メモリ展開しても問題ない場合には、先に中身をス カラ変数に読みこんでおいて C の第2引数に渡せば、 Content-Length: の出力、中身のアウトプットを順番に実行します。 ファイル名にマルチバイト文字を使用した場合 Shift_JIS でエンコーディン グされ、UNIXクライアントでは文字化けが発生する可能性があります。 =head1 AUTHOR Tatsuhiko Miyagawa with Sledge development team. =head1 SEE ALSO L =cut