5

在 Camping 中,如何最好地提供静态文件,例如 css?


现在我有

class Style < R '/cards.css'
    def get
         @headers["Content-Type"] = "text/css"
         File.read('cards.css')
    end
end 

有没有涉及 Rack 的更聪明的方法?

4

2 回答 2

9

Camping 对静态文件的当前(记得从 RubyGems 安装最新版本!)立场是服务器应该负责提供静态文件。

如果您使用camping-command,则public/应该自动为您提供 -directory。只需cards.css进入public/cards.csslocalhost:3301/cards.css 即可返回该文件。

在生产中,您应该配置 Apache/Nginx/whatever 以直接从public/-directory 提供文件。


如果您无法配置 Apache/Nginx(例如在 Heroku 中),您可以像这样编写自定义 config.ru:

# Your Camping app:
app = MyApp
# Static files:
files = Rack::File.new('public')

# First try the static files, then "fallback" to the app 
run Rack::Cascade.new([files, app], [405, 404, 403])

(这就是 Camping::Server 在内部所做的:https ://github.com/camping/camping/blob/5201b49b753fe29dc3d2e96405d724bcaa7ad7d4/lib/camping/server.rb#L151 )


对于小文件,您可以将它们存储在 app.rb 的数据块中:https ://github.com/camping/camping/blob/5201b49b753fe29dc3d2e96405d724bcaa7ad7d4/test/app_file.rb#L37

如果您想将所有内容保存在一个文件中,这也很有用。

Camping.goes :Foo

__END__

@@ /cards.css
...

Camping 将使用文件扩展名来设置正确的 Content-Type。


此外,最新版本的 Camping 有一个serve-method 可以为您处理 Content-Type。您可以将控制器简化为:

class Style < R '/style.css'
  def get
    serve "cards.css", File.read("cards.css")
  end
end

我必须为糟糕的文档道歉。现在你

于 2012-10-21T11:44:11.720 回答
2

这是whytheluckystiff最初的建议:

class Static < R '/static/(.+)'
  MIME_TYPES = {
    '.html' => 'text/html',
    '.css'  => 'text/css',
    '.js'   => 'text/javascript',
    '.jpg'  => 'image/jpeg',
    '.gif'  => 'image/gif'
  }
  PATH = File.expand_path(File.dirname(@__FILE__@))
  def get(path)
    @headers['Content-Type'] = MIME_TYPES[path[/\.\w+$/, 0]] || "text/plain" 
    unless path.include? ".." # prevent directory traversal attacks
      @headers['X-Sendfile'] = "#{PATH}/static/#{path}" 
    else
      @status = "403" 
      "403 - Invalid path" 
    end
  end
end

PS - 实际上,您可以在这里找到其他一些很棒的想法,例如文件上传、会话等。

于 2012-10-20T23:11:16.810 回答