Ruby Sinatra-通过config.ru设置缓存控制头
我目前正在Heroku的Cedar stack上运行一个Octopress(基于Jekyll)站点。代码位于此处: 我想根据文件类型有选择地应用Ruby Sinatra-通过config.ru设置缓存控制头,ruby,heroku,sinatra,rack,jekyll,Ruby,Heroku,Sinatra,Rack,Jekyll,我目前正在Heroku的Cedar stack上运行一个Octopress(基于Jekyll)站点。代码位于此处: 我想根据文件类型有选择地应用缓存控制头: .html文件的值为public,最大年龄=3600 .css |.js |.png |.ico(etc)获取一个值public,max age=604800-或者,我想将此规则应用于/stylesheets'、'/javascripts'、'/imgs'目录中提供的任何内容 使用了set:static\u cache\u contro
缓存控制
头:
文件的值为.html
public,最大年龄=3600
(etc)获取一个值.css |.js |.png |.ico
-或者,我想将此规则应用于public,max age=604800
目录中提供的任何内容/stylesheets'、'/javascripts'、'/imgs'
cache\u control:public、:max\u age=>3600
语句,但没有运气
我已经成功地在文章本身上设置了public,max age=3600
(例如/2012/lazy sundays/
),但无法获得应用于CSS/JS的标题(例如/stylesheets/screen.CSS
)
我的config.ru
当前看起来是这样的(更新的):
需要“捆绑机/设置”
需要“sinatra/基地”
#项目根目录
$root=::File.dirname(_File__;)
类SinatraStaticServer7200
发送\u sinatra\u文件(request.path){404}
结束
你找不到吗
发送\u sinatra_文件('404.html'){“对不起,我找不到{request.path}”
缓存控制:无缓存,:max\u age=>0
结束
def send_sinatra_文件(路径和缺少文件块)
file\u path=file.join(file.dirname(\uuuu file\uuuuuu),“public”,path)
file\u path=file.join(file\u path,'index.html'),除非file\u path=~/\.[a-z]+$/i
文件是否存在?(文件路径)?发送\u文件(文件路径):缺少\u文件\u block.call
结束
结束
使用Rack::Deflater
运行静态服务器
我对西纳特拉不太熟悉,但我认为这样做可以奏效:
class SinatraStaticServer < Sinatra::Base
before '*.html' do
response.headers['Cache-Control'] = 'public, max-age=3600'
end
before %r{\.(css)|(js)|(png)|(ico)} do
response.headers['Cache-Control'] = 'public, max-age=604800'
end
# ...
end
我确认这在我的机器上有效。请注意,我在回答的第一部分中使用了response.headers['Cache-Control']
,而不是您尝试过的set:static\u Cache\u Control
,但我认为它只能在configure do
块中运行一次
还请注意,在当前设置中,与上述内容匹配的404(例如,
nonexistant.png
)将在缓存控制标头仍然存在的情况下提供404状态。我可以看到几种解决方法,但我认为您可以这样做,所以我只是指出了这一点,并认为您可以随意处理它。以下是如何为静态资产设置长到期头,以及为Heroku上的主要内容设置任意到期头:
档案:
gem 'rack-contrib'
config.ru:
require 'rack/contrib'
get '*.html' do |page|
# whatever code you need to serve up your main pages
# goes here... use Rack::File I guess.
page
end
# Set content headers for that content...
before do
expires 5001, :public, :must_revalidate
end
# Assets in /static/stylesheets (domain.com/stylesheets)
# are served by Rack StaticCache, with a default 2 year expiry.
use Rack::StaticCache, :urls => ["/stylesheets"], :root => Dir.pwd + '/static'
run Sinatra::Application
默认情况下,URL数组中列出的内容(静态/样式表、静态/图像等)将有2年的有效期
您必须从/public移动到/static,否则您将不必要地使用Heroku的nginx配置(应用这些设置的正确位置)
我知道你说你试图不使用Rack Contrib,但那没有意义。使用一个90行的小库来实现这一点没有什么害处
“正确”的方法是在可以配置nginx的环境中托管静态内容,第二种最好的方法是重命名静态文件路径,以便heroku忽略它,并使用rack static来提供具有所需标题的静态文件
--
同样要明确的是,只需将您的公用文件夹重命名为其他文件夹,您就可以通过路由执行此操作,并且正常的Sinatra expires功能将过期。但我会使用StaticCache,因为它不那么冗长。(我相信,真正的问题是Heroku不允许nginx与你的应用程序对话以请求公开/)谢谢-感觉已经完成了一半,但仍然没有通过标题(通过curl和askapache.com检查),我看到了,但试图避免使用rack contrib,因为它感觉这不是最好的(简短的)方式。我还深入研究并使用了
set:static\u cache\u控件,[:public,:max\u age=>3600]
在之前。。。do
块,但它仍然没有添加缓存控制头。PS:我已经在原始问题中添加了有关我的具体尝试的信息,如果这有助于您解决此问题的话。谢谢你迄今为止的回复,这帮助我缩小了我需要做的事情。@elithrar因为今天我太累了,不能做任何我自己的项目,所以我有时间消磨时间。我安装了Sinatra,并对其进行了研究,发现了为什么没有添加标题。请看我的最新答案。谢谢。不过,我正试图避免这种情况,因为这有点像黑客攻击(我还必须攻击Octopress才能让它正常工作)。看看Sinatra文档,public/文件夹不应该干扰这一点,set:static\u cache\u control语句用于处理public/@elithrar中的文件是的,如果您可以对所有静态文件使用相同的缓存控制,那就非常简单了。手动为静态文件提供服务,以便根据文件扩展名提供自定义头是一种黑客行为,但我认为这就是你的目的。我不认为有一个内置的简单方法可以做到这一点。我试图“避免”使用它,这样我就不必开始修补Octopress。它的默认rake任务使用SASS将CSS文件放入/public/stylesheets,并在/public中发布。修改rake脚本(请注意)并不是什么大不了的事,但它可能会使将来与新版本的合并更加令人头痛。但我离题了。您的解决方案看起来是最合适的—我已经有一半可以使用了(主页已经提供了正确的缓存头)—因此我只需要将引用从/public更改为/static,并从那里开始,以避免Heroku的默认行为。另外:我如何覆盖StaticCache
的2年期限?我想避免对CSS进行版本控制,因为每次更改CSS时都要重新生成整个站点,但我希望能够有一个
gem 'rack-contrib'
require 'rack/contrib'
get '*.html' do |page|
# whatever code you need to serve up your main pages
# goes here... use Rack::File I guess.
page
end
# Set content headers for that content...
before do
expires 5001, :public, :must_revalidate
end
# Assets in /static/stylesheets (domain.com/stylesheets)
# are served by Rack StaticCache, with a default 2 year expiry.
use Rack::StaticCache, :urls => ["/stylesheets"], :root => Dir.pwd + '/static'
run Sinatra::Application