Clojure 重定向缺少的尾部斜杠URL的环形解决方案

Clojure 重定向缺少的尾部斜杠URL的环形解决方案,clojure,ring,Clojure,Ring,我尝试使用环形路由实现的行为大致如中所述 基本上,我有一些以斜杠结尾的URL,我正在尝试创建一个中间件,它将从例如example.com/foo重定向到example.com/foo/,当且仅当/foo/是有效URL而/foo不是 我目前正在使用这个中间件 (defn good-response? [resp] (and resp (not= (:status resp) 404))) (defn wrap-slash [handler] (fn [{:keys [uri] :as r

我尝试使用环形路由实现的行为大致如中所述

基本上,我有一些以斜杠结尾的URL,我正在尝试创建一个中间件,它将从例如
example.com/foo
重定向到
example.com/foo/
,当且仅当
/foo/
是有效URL而
/foo
不是

我目前正在使用这个中间件

(defn good-response? [resp]
  (and resp (not= (:status resp) 404)))

(defn wrap-slash [handler]
  (fn [{:keys [uri] :as req}]
    (let [resp (handler req)]
      (if (or (good-response? resp) (.endsWith "/" uri))
        resp
        (let [added-slash (str uri "/")]
          (if (good-response? (handler (assoc req :uri added-slash)))
            (redirect added-slash)
            resp))))))
它几乎完成了它应该做的一切:它从
/foo
重定向到
/foo/
iff
/foo/
存在,而
/foo
不存在

我担心的是,此解决方案将调用
(handler req)
至少两次,一次是在请求
/foo
时调用,另一次是在客户端请求重定向的URL时调用。现在这已经不是问题了,但我可以想象,对于一些带有数百个DB查询或诸如此类的慢页面,将响应时间增加一倍是一件痛苦的事情


有没有一种方法可以简单地检查给定URL是否存在处理程序,而不调用该处理程序?我们可以通过使
(:body request)
懒惰来完全避免这个问题吗?

环中没有通用的方法来检查“这是一个有效的uri吗?”而不使用该uri调用整个堆栈处理程序,因为没有uri的中心列表,但即使如此,处理程序也可以出于任何原因拒绝处理请求,不仅仅是基于它的uri

我可能会走另一条路;对于所有实际需要此行为的处理程序,让它们也捕获“未刷新”版本,然后在需要/有用时重定向

或者,如果给定一些规则,url应该始终以斜杠结尾,则使用单独的处理程序/中间件,如果不匹配,则让重定向失败。无论哪种方式最终用户都会得到404,那么谁在乎呢,真的

但最具体的处理者通常处于做出决定的最佳位置

哦,你可能不只是把帖子转发给其他URI

我修复了你的代码

(defn good-response? [resp]
  (and resp (not= (:status resp) 404)))

(defn wrap-slash [handler]
  (fn [{:keys [uri] :as req}]
    (let [resp (handler req)]
      (if (or (good-response? resp) (.endsWith uri "/"))
        resp
        (let [added-slash (str uri "/")]          
          (if (good-response? (handler (-> req
                                           (assoc :uri added-slash)
                                           (assoc :path-info added-slash))))
            (redirect added-slash)
            resp))))))
您需要更改:路径信息