如何为Rack安装静态文件

saw*_*awa 4 ruby rack file thin

我想通过Rack提供静态文件以及动态内容.以前,我使用WEBrick 而不使用Rack,代码是这样的,它起作用了:

    @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
Run Code Online (Sandbox Code Playgroud)

在上面,请求localhost:3000将由动态内容响应,请求localhost:3000/resource/path_to_file将由位于/path_to_file我的计算机上的静态文件响应.

现在,我想切换到使用Rack with Thin server的系统.我写了以下内容,但无法获取所提供的静态文件.应如何改变以使其有效?

    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)
Run Code Online (Sandbox Code Playgroud)

我知道这是一个类似的问题:如何通过Rack提供静态文件?,但我无法使它工作.我不知道如何使用Rack::Static,Rack::FileRack::Directory.请教我.

mat*_*att 6

您需要使用Rack::Builder以便use SomeMiddleware在普通的Ruby脚本中使用该语法(它通常在config.ru文件中使用).您还需要run申请.请注意,获取数组的urlsRack::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)
Run Code Online (Sandbox Code Playgroud)

这里Rack::Builder是您的应用程序,->env{[200, {}, [some_dyamically_generated_content]]}Rack::Static中间件添加到它并创建一个新的组合应用程序,然后传递给Thin运行.

Rack::Static是一个可以添加到现有机架应用程序的中间件组件.Rack::File并且Rack::Directory它们本身都是机架应用程序,而不是中间件(在内部Rack::Static使用Rack::File,Rack::Directory默认情况下也是如此).使用Rack::Filemap命令可以达到与上面相同的效果:

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)
Run Code Online (Sandbox Code Playgroud)

更常见的方法是将传递的块的内容Rack::Bundler.new放在一个config.ru文件中:

use(Rack::Static, urls: ["/resource/"], root: "/") 
run ->env{[200, {}, [some_dyamically_generated_content]]}
Run Code Online (Sandbox Code Playgroud)

然后thin start,您可以运行此命令,config.ru如果从同一目录运行,则应该查找该命令,或者您可以使用该-R选项指定该文件.如果要将Thin指定为服务器rackup,也可以使用该命令rackup -s thin.