Один простой способ для достижения этой цели, чтобы проверить схему входящего запроса внутри вашего маршрута, например:
(defroutes app-routes
(POST "/route-one" request
(if (= (:scheme req) :http)
(process-requet request)
{:status 403 :body "https not supported"}))
(POST "/route-two" request
(if (= (:scheme req) :https)
(process-requet request)
{:status 403 :body "http not supported"})))
Конечно, Вы можете извлечь эту схему проверки в отдельную функцию или макрос, так что даже если у вас много маршрутов, тогда это может быть жизнеспособным вариантом без лишнего шума в вашем коде.
Если у вас много маршрутов, и вы не хотите добавлять дополнительный вызов или проверку для каждого, тогда другой способ достичь этого - добавить в ваше приложение некоторое промежуточное программное обеспечение. Среднее ПО может проверить :scheme
, включенные в запрос, и отклонить запросы, которые не соответствуют. Например:
(defn wrap-https-only [handler]
(fn [req]
(if (= (:scheme req) :https)
(handler req)
{:status 403 :body "http not supported"})))
(defn wrap-http-only [handler]
(fn [req]
(if (= (:scheme req) :http)
(handler req)
{:status 403 :body "https not supported"})))
Хитрость в том, что вы хотите, чтобы выборочно применять этот промежуточное программное обеспечение для некоторых маршрутов, а не другие, и Compojure не предлагает простой способ сделать это. Если у вас есть какой-то общий путь во всех ваших HTTP маршрутов, и все ваши Https маршруты (сгруппировать их), то вы можете использовать шаблон, как это:
(def http-routes
(-> (routes (POST "/http-only/route-one" request
(process-requet request)))
wrap-http-only))
(def https-routes
(-> (routes (POST "/http-only/route-two" request
(process-requet request)))
wrap-https-only))
(defroutes app-routes
(ANY "/http-only/*" [] http-routes)
(ANY "/https-only/*" [] https-routes))
Вы можете увидеть здесь, что промежуточное программное обеспечение применяется к каждому подмножеству маршрутов, и поэтому он будет выполняться только в том случае, если соответствует первая часть пути. Теперь вы можете добавить столько маршрутов, сколько хотите, а промежуточное ПО позаботится о проверке схемы для всех.Обратите внимание: этот подход требует, чтобы вы каким-то образом идентифицировали подмножества маршрутов на начальных маршрутах «маршруты приложения», в этом случае я идентифицировал их по пути.
При проверке схемы следует обратить внимание, что это не будет работать, если вы решите отключить SSL для балансировки нагрузки. В этом случае ваше приложение всегда будет получать запросы HTTP (не HTTPS). Обычно вы можете добиться того же, просто проверив заголовок X-Forwarded-Proto
вместо значения :scheme
.
Вы еще посмотрели на http://pedestal.io/? Он имеет конфигурацию для обработки нескольких «серверов», которые, как я думаю, вписываются в вашу ситуацию. –