4

実行可能ファイルを「配布」する 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の組み込みWebサーバーを介して)、正しいファイル(サイズと内容)が得られます。しかし、共有ホスティング (Linux) で CGI モードで実行すると、正しいサイズで返されますが、ファイルの最初の 8 バイトは常に正しくありません (常に異なります)。ファイルの残りの部分は正しいです。

私のサブで、そこにあると思われるものを取得する$hex_data代わりに指定します。$bin_data

私は途方に暮れています。

4

1 に答える 1

5

render_partialはあなたが望むものではありません。

まず、実行可能ファイルを base64 形式で再エンコードし、テンプレートが base64 でエンコードされていることを指定します (これは、16 進数がアプリの要件ではないことを前提としています)。

@@ 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 としてダウンロードします。

于 2012-04-07T20:02:00.210 に答える