Как монтировать статические файлы для Rack - PullRequest
4 голосов
/ 10 января 2012

Я хочу обслуживать статические файлы и динамическое содержимое через 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

В приведенном выше запросе к localhost:3000 будет отвечать динамическое содержимое, ина запросы к localhost:3000/resource/path_to_file будет отвечать статический файл, расположенный на моем компьютере по адресу /path_to_file.

Теперь я хочу переключиться на систему, использующую Rack с тонким сервером.Я написал следующее, но не смог получить статические файлы.Как изменить его, чтобы он работал?

    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)

Я знаю, что есть похожий вопрос: Как обслуживать статические файлы через Rack? , но я не смог заставить его работать,Я не уверен, как использовать Rack::Static, Rack::File или Rack::Directory.Пожалуйста, научи меня.

Ответы [ 2 ]

6 голосов
/ 11 января 2012

Вам необходимо использовать Rack::Builder, чтобы использовать синтаксис use SomeMiddleware в обычном скрипте Ruby (обычно он используется в файле 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и создание нового комбинированного приложения, которое затем передается в Thin для запуска.

Rack::Static - это компонент промежуточного программного обеспечения, который вы можете добавить к существующим стоечным приложениям.Rack::File и Rack::Directory оба являются стоечными приложениями, а не промежуточным программным обеспечением (Rack::Static использует Rack::File внутри, как и Rack::Directory по умолчанию).Вы можете добиться того же эффекта, что и выше, используя Rack::File и команду map:

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]]}

Затем вы можете запустить его с помощью thin start, который должен найти config.ru при запуске из того же каталога, или вы можете использовать опцию -R, чтобы указатьфайл.Также можно использовать команду rackup, rackup -s thin, если вы хотите указать Thin в качестве сервера.

1 голос
/ 11 января 2012

Если вам не требуется аутентификация / авторизация перед обработкой файлов, вы сможете добавлять файлы в /public и обслуживать их базовым сервером.Поэтому, если макет вашего приложения выглядит следующим образом

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

После запуска приложения (с использованием thin, webrick или apache или любого другого сервера) вы можете получить доступ к статическим файлам с http://localhost:4567/a_static_file.png

...