2012-01-10 25 views
4

我想通過機架服務靜態文件以及動態內容。以前,我用的WEBrick 不使用機架,像這樣的代碼,它的工作:如何爲機架安裝靜態文件

@s = WEBrick::HTTPServer.new(
     Port: 3000, 
     BindAddress: "localhost", 
     Logger: WEBrick::Log.new(File::NULL), 
     AccessLog: [nil, nil] 
    ) 
    %w[INT TERM].each{|signal| trap(signal){@s.shutdown}} 
    @s.mount("/", self) 
    @s.mount("/resource/", WEBrick::HTTPServlet::FileHandler, "/") 
    @s.start 

在上面,請求對localhost:3000將動態內容進行響應,並要求localhost:3000/resource/path_to_file將由來回應靜態文件位於我電腦上的/path_to_file

現在,我想切換到使用Rack with Thin服務器的系統。我寫了以下內容,但無法獲取所提供的靜態文件。應該如何改變它以使其工作?

Rack::Handler::Thin.run(->env{ 
     h = Rack::Utils.parse_nested_query(env["QUERY_STRING"]) 
     # I tried the following three lines one at a time, but neither worked. 
     use(Rack::Static, urls: "/resource/", root: "/") # First try 
     Rack::File.new("/resource").call(env) # Second try 
     Rack::Directory.new("/resource").call(env) # Third try 
     [200, {}, [some_dyamically_generated_content]] 
    }, Port: 3000) 

我知道療法是一個類似的問題:How to serve static files via Rack?,但我不能使它工作。我不知道如何使用Rack::Static,Rack::FileRack::Directory。請教我。

回答

6

訪問靜態文件,你需要使用Rack::Builder,以便在普通的Ruby腳本中使用use SomeMiddleware語法(通常在config.ru文件中使用它)。您的應用程序還需要run。需要注意的是urls關鍵Rack::Static需要一個數組,而不是一個字符串:

require 'rack' 
Rack::Handler::Thin.run(Rack::Builder.new { 
    use(Rack::Static, urls: ["/resource/"], root: "/") 
    run ->env{[200, {}, [some_dyamically_generated_content]]} 
}, Port: 3000) 

這裏Rack::Builder正在您的應用程序,->env{[200, {}, [some_dyamically_generated_content]]},加入Rack::Static中間件,並創建一個新的組合應用,然後將其傳遞到細跑步。

Rack::Static是您可以添加到現有機架應用程序的中間件組件。 Rack::FileRack::Directory都是機架應用程序,而不是中間件(Rack::Static內部使用Rack::File,默認情況下使用Rack::Directory)。

require 'rack' 
Rack::Handler::Thin.run(Rack::Builder.new { 
    map "/resource/" do 
     run Rack::File.new "/" 
    end 
    map "/" do 
     run ->env{[200, {}, [some_dyamically_generated_content]]} 
    end 
}, Port: 3000) 

比較常見的方法,這樣做將是把傳遞給Rack::Bundler.new塊的內容在config.ru文件:

use(Rack::Static, urls: ["/resource/"], root: "/") 
run ->env{[200, {}, [some_dyamically_generated_content]]} 
如上使用 Rack::Filemap命令你可以達到同樣的效果

然後,您可以運行thin start,如果從同一目錄運行,應該找到config.ru,或者您可以使用-R選項指定文件。如果要將Thin指定爲服務器,也可以使用rackup命令,rackup -s thin

+0

感謝您的重寫和細節。有效。 – sawa 2012-01-10 21:11:06

1

如果您在提供文件前不需要認證/授權,您應該能夠將文件添加到/public並讓它們由底層服務器提供服務。 所以,如果你的應用程序佈局看起來像這樣

my_app/ 
    - app.rb 
    - config.ru 
    - public/ 
    - a_static_file.png 
    - another_static_file.png 

一旦你開始你的應用程序(使用薄,使用WEBrick,或Apache或任何底層服務器),你可以從http://localhost:4567/a_static_file.png

+0

我可能會考慮這一點,但現在,我需要訪問某些位置而不必將它們全部移至'/ public'。謝謝您的幫助。 – sawa 2012-01-10 21:12:02