2013-01-24 3 views
1

반지 경로를 사용하여 구현하려는 동작은 대략 this question에 설명되어 있습니다.누락 된 후행 슬래시 URL을 리디렉션하는 링 솔루션

는 기본적으로 나는 후행 슬래시로 끝나는 일부 URL이, 내가하고 경우에만 /foo/가 유효한 URL과 /foo가없는 경우 example.com/foo/example.com/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하지 않는 /foo에서 /foo/에 IFF에 리디렉션합니다.

이 솔루션을 사용하면 에 대한 요청에서 두 번 이상 (handler req)을 요청하고 클라이언트가 리디렉션 된 URL을 요청한 경우 다시 한 번 호출 할 것입니다. 지금은 문제가 아니지만 수백 건의 DB 쿼리 또는 이와 같은 문제가있는 일부 느린 페이지의 응답 시간을 두 배로 늘리는 것은 힘든 일이라고 상상할 수 있습니다.

핸들러를 호출하지 않고 주어진 URL에 대한 핸들러가 존재하는지 단순히 확인하는 방법이 있습니까? (:body request)을 게으르게 만들면 완전히 문제를 피할 수 있을까요?

답변

2

"유효한 URI인가?"를 확인하는 일반적인 방법은 없습니다. 그 uri로 전체 스택 핸들러를 호출하지 않고 uris의 중앙 목록이 없기 때문에 핸들러조차도 uri를 기반으로하는 것이 아니라 어떤 이유로 든 요청을 처리 할 수 ​​없습니다.

나는 다른 방향으로 갈 것입니다. 실제로이 동작을 필요로하는 모든 핸들러는 "unslashed"버전을 잡아서 필요/유용 할 경우 리다이렉트하게 만듭니다.

URL이 일부 규칙에 따라 항상 슬래시로 끝나야하고 별도의 처리기/미들웨어를 사용하고 일치하지 않는 경우 리디렉션이 실패하도록하십시오. 어쨌든 최종 사용자는 404를 얻을 것이므로, 누가 신경 써야할까요?

하지만 가장 구체적인 핸들러는 일반적으로 의사 결정에 가장 적합한 위치에 있습니다.

아, 아마도 다른 URI로 POST를 전달하지 않을 것입니다.

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

: 경로 정보를 변경해야합니다.