我有一个Mojolicious Lite脚本,“发出”一个可执行文件(用户可以从脚本的URL下载该文件)。我将编码数据保存在DATA部分的内联模板中,然后对其进行编码和render_data。
get '/download' => sub {
my $self = shift;
my $hex_data = $self->render_partial( 'TestEXE' );
my $bin_data;
while( $hex_data =~ /([^\n]+)\n?/g ) {
$bin_data .= pack "H".(length $1), $1;
}
my $headers = Mojo::Headers->new;
$headers->add( 'Content-Type', 'application/x-download;name=Test.exe' );
$headers->add( 'Content-Disposition', 'attachment;filename=Test.exe' );
$headers->add( 'Content-Description', 'File Transfer');
$self->res->content->headers($headers);
$self->render_data( $bin_data );
};
__DATA__
@@ TestEXE.html.ep
4d5a90000300000004000000ffff0000b8000000000000004000000000000000
00000000000000000000000000000000000000000000000000000000b0000000
0e1fba0e00b409cd21b8014ccd21546836362070726f6772616d2063616e6e6f
....
当我在本地运行时(通过http://127.0.0.1:3000/上的内置网络服务器,Win7),我得到了正确的文件(大小和内容)。但是当我在共享主机(Linux)上以CGI模式运行它时,它返回正确的大小,但文件的前8个字节总是不正确(并且总是不同)。文件的其余部分是正确的。
如果在我的sub中我指定$hex_data
而不是$bin_data
,我会得到假设的那样。
我迷路了。
答案 0 :(得分:5)
render_partial 不是您想要的。
首先,re-encode the executable in base64 format,并指定模板是base64编码的(假设hex不是您的应用程序的要求):
@@ template-name (base64)
此外,您根本不需要控制器方法。 Mojolicious将为您处理这个过程 - 您只需要为模板命名即可。
use Mojolicious::Lite;
app->start;
__DATA__
@@ Test.exe (base64)
...
然后http://127.0.0.1:3000/Test.exe将下载该文件。
-
如果您仍想使用控制器方法来解决特定于应用的问题,请专门获取数据模板:
use Mojolicious::Lite;
get '/download' => sub {
my $self = shift;
# http://mojolicio.us/perldoc/Mojolicious/Renderer.pm#get_data_template
my $data = $self->app->renderer->get_data_template({}, 'Test.exe');
# Replace content-disposition instead of adding it,
# to prevent duplication from elsewhere in the app
$self->res->headers->header(
'Content-Disposition', 'attachment;filename=name.exe');
$self->render_data($data);
};
app->start;
__DATA__
@@ Test.exe (base64)
...
http://127.0.0.1:3000/download将获取模板,设置标题,然后将其下载为name.exe。