Search code examples
rubyrackmiddleman

Rack::Builder and Rack::TryStatic doesn't work


I have a Middleman app which I am serving using Rack::TryStatic.

Here is the config.ru.

use Rack::TryStatic,
  root: 'build',
  urls: %w[/],
  try: ['.html', 'index.html', '/index.html']

run lambda{ |env|
  four_oh_four_page = File.expand_path("../build/404.html", __FILE__)
  [ 404, { 'Content-Type'  => 'text/html'}, [ File.read(four_oh_four_page) ]]
}

My understanding is that when you use a config.ru with run, map or use methods, they are converted to a Rack::Builder object.

I've tried wrapping this config in a Rack::Builder object like this:

app = Rack::Builder.new do

  use Rack::TryStatic,
    root: 'build',
    urls: %w[/],
    try: ['.html', 'index.html', '/index.html']

  run lambda{ |env|
    four_oh_four_page = File.expand_path("../build/404.html", __FILE__)
    [ 404, { 'Content-Type'  => 'text/html'}, [ File.read(four_oh_four_page) ]]
  }
end

run app

When I do this, I get the 404 page for all requests.

Why doesn't this work?


Solution

  • It looks like there is a bug in the current released version of TryStatic that has been fixed in master, where the try array is being lost when used in way that causes the middleware to be reinitialized.

    You can avoid this by making sure the app only get s initialized once by using to_app:

    run app.to_app
    

    or equivalently use app instead of new:

    app = Rack::Builder.app do
      # ...