2011-10-22 64 views
1

我們在亞馬遜S3上存儲大量文件,我們希望網站訪問者能夠通過AJAX訪問,但我們不希望向訪問者透露實際的文件位置。簡單的Perl代理

爲了達到這個目的,我希望做的是向一個非常簡單的perl腳本發出一個AJAX請求,該腳本只是作爲代理並將文件返回給瀏覽器。我已經有腳本設置來驗證用戶是否登錄並執行數據庫查詢以找出正確的URL來訪問S3上的文件,但我不確定將文件返回到Vistor瀏覽器的最佳方式最有效的方式。

任何建議,最好的方式來完成這將不勝感激。謝謝!

+0

如果您想阻止他們看到該位置,您必須從腳本中打開文件並將其回顯給用戶的瀏覽器。您可以使用標題使它看起來像他們正在下載原始文件。 –

+0

@SamDufel - 謝謝。我應該使用任何示例代碼或建議模塊來最大限度地減少最終用戶的加載時間? –

+0

對不起,我主要使用php,而不是perl。我可以給你一個例子在PHP中,但我不知道這將是多麼有用...... –

回答

1

好的。有一個例子是如何使用Mojolicious框架來實現的。 我想你運行這個腳本作爲守護進程。腳本捕獲到/json_dir/.*的所有請求,將此請求發送到Stackoverflow API並返回響應。 您可以運行該腳本./example.pl daemon,然後嘗試http://127.0.0.1:3000/json_dir/perl

對此你應該能夠找到你的標題爲「簡單的Perl代理」自己的問題。 這段代碼可以作爲監聽特定端口和CGI腳本的獨立守護進程使用(首選)。

#!/usr/bin/env perl 
use Mojolicious::Lite; 

get '/json_dir/(.filename)' => sub { 
    my $self = shift; 

    my $filename = $self->stash('filename'); 
    my $url = "http://api.stackoverflow.com/1.1/questions?tagged=" . $filename; 

    $self->ua->get(
     $url => sub { 
      my ($client, $tx) = @_; 
      json_response($self, $tx); 
     } 
    ); 

    $self->render_later; 
}; 

sub json_response { 
    my ($self, $tx) = @_; 
    if (my $res = $tx->success) { 
     $self->tx->res($res); 
    } 
    else { 
     $self->render_not_found; 
    } 
    $self->rendered; 
} 

app->start; 

__DATA__ 

@@ not_found.html.ep 
<!doctype html><html> 
    <head><title>Not Found</title></head> 
    <body>File not found</body> 
</html> 
2

最好的方法是使用sendfile system call。如果您打開並手動從磁盤讀取文件,然後再將它按塊方式寫入Web框架的「接收器」端,那麼您非常浪費,因爲數據必須通過RAM傳送,可能包括緩衝。

你在你的問題中描述的是一種非常常見的模式,因此許多解決方案已經存在圍繞設置special HTTP header的想法,然後讓應用程序下面的Web堆棧有效地處理它。

採用XSendfile中間件在普拉克設置合適的報頭。下面的最小程序將DTRT並在可能的情況下利用系統調用。

use IO::File::WithPath qw(); 
use Plack::Builder qw(builder enable); 
builder { 
    enable 'Plack::Middleware::XSendfile'; 
    sub { 
     return [200, [], IO::File::WithPath->new('/usr/src/linux/COPYING')]; 
    } 
};