How to install static files for Rack

I want to serve static files as well as dynamic content through Rack. I used to use WEBrick without using Rack , with code like this, and it worked:

@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 

In the above request, localhost:3000 will respond with dynamic content, and the localhost:3000/resource/path_to_file will respond with a static file located in /path_to_file on my computer.

Now I want to switch to a system using Rack with a Thin server. I wrote the following, but could not get the static files. How to change it to make it work?

  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) 

I know this is a similar question: How to serve static files via Rack? but I could not get it to work. I am not sure how to use Rack::Static , Rack::File or Rack::Directory . Please teach me.

+4
source share
2 answers

You need to use Rack::Builder to use the use SomeMiddleware syntax in a regular Ruby script (it is usually used in config.ru ). You will also need run for your application. Note that the urls key on Rack::Static accepts an array, not a single line:

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

Here Rack::Builder takes your application, ->env{[200, {}, [some_dyamically_generated_content]]} , adding Rack::Static middleware to it and creating a new combo application that is then passed to Thin for launch.

Rack::Static is a middleware component that can be added to existing rack applications. Rack::File and Rack::Directory are the rack applications themselves, not middleware ( Rack::Static uses Rack::File internally, just like Rack::Directory by default). You can achieve the same effect as above using the Rack::File and map command:

 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) 

A more common way to do this is to place the contents of the block passed to Rack::Bundler.new in the config.ru file:

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

Then you can start this with thin start , which should be found by config.ru if it starts from the same directory, or you can use the -R option to specify the file. The rackup command rackup also be used by rackup -s thin if you want to specify Thin as the server.

+6
source

If you do not require authentication / authorization before servicing files, you can add files to /public and serve them with the base server. So if your application layout is as follows

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

Once you start your application (using thin, webrick or apache or any other server), you can access the static files from http://localhost:4567/a_static_file.png

+1
source

Source: https://habr.com/ru/post/1390204/


All Articles