如何使用Compojure生成修改后的http标头?

时间:2011-05-25 04:16:49

标签: http clojure http-headers compojure

我正在尝试提高从我的Compojure网络服务器获取页面的客户端的性能。我们使用(compojure.route/resources "/")提供了一堆静态文件(JS,CSS),它在文件系统上查找文件,将它们转换为URL,然后将它们作为流提供给Ring。通过转换为流,它似乎丢失了所有文件元数据,例如mod时间。

我可以包装静态资源处理程序并添加ExpiresCache-Control: max-age标头,但这会阻止客户端发送任何请求。很有用,但这些文件有时会发生变化(当我们推出一个版本时)。

理想情况下,我希望客户端信任自己的缓存版本,例如一小时,并在该小时后通过If-Modified-Since标头发出请求。然后我们可以返回304 Not Modified,客户端可以避免下载几百公斤的JavaScript。

看起来我可以在提供响应时设置Last-Modified标头,这会导致客户端使用If-Modified-Since标头限定后续请求。很好,除了我必须重写compojure.route/resources中的大部分代码以添加Last-Modified - 不困难但又乏味 - 并且发明了更多代码来识别和响应{{1}标头这不是一项重大任务,也不是一项简单的任务。

这已经存在吗?我找不到它,但它似乎是一个足够普通的,足够大的任务,有人会为它编写一个库。

2 个答案:

答案 0 :(得分:4)

FWIW,我通过使用Ring的wrap-file-info中间件来实现这一点;我很尴尬,我在Compojure而不是Ring中寻找这个。但是,compojure.route的{​​{1}}和files处理程序都提供了流而不是文件或网址,当然Ring无法从中找出元数据。

我必须写一份基本上resources的副本,而不是resources;当包裹在符合我需要的File时。仍然不介意一个稍微好一点的解决方案,不涉及从Compojure复制大量代码。

答案 1 :(得分:1)

您是否考虑过使用ring-etag-middleware?它使用文件的上次修改日期来生成实体标记。然后,它将匹配304键入请求中的if-none-match标头。