Compojure регулярное выражение для соответствия конечной косой черты - PullRequest
7 голосов
/ 05 декабря 2011

Может быть, я просто идиот, но я не могу настроить соответствие для дополнительной косой черты в Clojure.

lein repl
REPL started; server listening on localhost port 47383
user=> (use 'ring.mock.request 'clout.core)
nil
user=> (route-matches "/article/" (request :get "/article/"))
{}
user=> (route-matches "/article/?" (request :get "/article"))
nil
user=> (route-matches "/article/?" (request :get "/article/"))
nil
user=> (route-matches #"/article/?" (request :get "/article/"))
java.lang.IllegalArgumentException: No implementation of method: :route-matches of protocol: #'clout.core/Route found for class: java.util.regex.Pattern (NO_SOURCE_FILE:0)

Какое регулярное выражение я могу использовать для сопоставления с дополнительной косой чертой в Compojure?

Ответы [ 3 ]

5 голосов
/ 05 декабря 2011

Строка пути, ожидаемая clout в качестве первого аргумента route-matches, является не регулярным выражением, а строкой, которая может содержать ключевые слова и подстановочный знак *.

Я считаю, clout неизначально не поддерживает определение маршрутов, которые игнорируют косую черту.Вы можете решить проблему с помощью функции промежуточного программного обеспечения, которая удаляет завершающие косые черты.Следующие функции были взяты из старой версии compojure исходного кода (до большого рефакторинга), я не мог узнать, переместились ли они на новое место.Вот оригинальный коммит , который ввел эти функции.

(defn with-uri-rewrite
  "Rewrites a request uri with the result of calling f with the
   request's original uri.  If f returns nil the handler is not called."
  [handler f]
  (fn [request]
    (let [uri (:uri request)
          rewrite (f uri)]
      (if rewrite
        (handler (assoc request :uri rewrite))
        nil))))

(defn- uri-snip-slash
  "Removes a trailing slash from all uris except \"/\"."
  [uri]
  (if (and (not (= "/" uri))
           (.endsWith uri "/"))
    (chop uri)
    uri))

(defn ignore-trailing-slash
  "Makes routes match regardless of whether or not a uri ends in a slash."
  [handler]
  (with-uri-rewrite handler uri-snip-slash))
1 голос
/ 20 марта 2014

Вот сокращенная версия промежуточного программного обеспечения без зависимостей:

(defn with-ignore-trailing-slash [handler] (fn [request]
  (let [uri       (request :uri)
        clean-uri (if (and (not= "/" uri) (.endsWith uri "/"))
                    (subs uri 0 (- (count uri) 1))
                    uri)]
    (handler (assoc request :uri clean-uri)))))

Добро пожаловать в исправление ошибок.

0 голосов
/ 10 марта 2016

Для тех, кто ищет равномерное больше сжатое решение:)

(defn- with-ignore-trailing-slash [handler]
  (fn [request]
    (let [uri (request :uri)
          clean-uri (str/replace uri #"^(.+?)/+$" "$1")]
      (handler (assoc request :uri clean-uri)))))
...