1

我试图使用环路由实现的行为在这个问题中被大致描述。

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

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

(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 时。现在这不是问题,但我可以想象对于具有数百个数据库查询或类似事情的一些慢速页面的响应时间加倍是痛苦的。

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

4

2 回答 2

2

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

我可能会反过来;对于实际需要此行为的所有处理程序,使它们也捕获“未斜线”版本,然后在需要/有用时重定向。

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

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

哦,您可能不只是将 POST 转发到其他 URI。

于 2013-01-24T17:58:09.193 回答
0

我修复了你的代码。

(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))))))

您需要更改:路径信息。

于 2015-06-19T04:19:09.163 回答