diff --git a/backend/src/uxbox/http/cors.clj b/backend/src/uxbox/http/cors.clj index 06133c085..181a46888 100644 --- a/backend/src/uxbox/http/cors.clj +++ b/backend/src/uxbox/http/cors.clj @@ -10,7 +10,6 @@ (defn- allow-origin? [value {:keys [origin]}] - (prn "allow-origin?" value origin) (cond (nil? value) value (= origin "*") origin diff --git a/backend/src/uxbox/http/etag.clj b/backend/src/uxbox/http/etag.clj new file mode 100644 index 000000000..173f24516 --- /dev/null +++ b/backend/src/uxbox/http/etag.clj @@ -0,0 +1,54 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) 2019 Andrey Antukh + +(ns uxbox.http.etag + "ETag calculation helpers." + (:require [clojure.java.io :as io] + [buddy.core.hash :as hash] + [buddy.core.codecs :as codecs] + [buddy.core.codecs.base64 :as b64])) + +(defn digest + [^bytes data] + (-> (hash/blake2b-256 data) + (b64/encode true) + (codecs/bytes->str))) + +(defn- etag-match? + [request new-tag] + (when-let [etag (get-in request [:headers "if-none-match"])] + (= etag new-tag))) + +(defn stream-bytes + [is] + (let [baos (java.io.ByteArrayOutputStream.)] + (io/copy is baos) + (.toByteArray baos))) + +(defn handle-response + [request {:keys [body] :as response}] + (when (instance? java.io.ByteArrayInputStream body) + (let [data (stream-bytes body) + etag (digest data)] + (.reset body) + (if-not (etag-match? request etag) + (update response :headers assoc "etag" etag) + (-> response + (assoc :body "" :status 304) + (update :headers assoc "etag" etag)))))) + +(defn wrap-etag + [handler] + (fn [request respond raise] + (handler request + (fn [response] + (prn "wrap-etag" (= (:request-method request) :get)) + (if (= (:request-method request) :get) + (respond (or (handle-response request response) response)) + (respond response))) + raise))) + + diff --git a/backend/src/uxbox/http/middleware.clj b/backend/src/uxbox/http/middleware.clj index e343602b1..043aa5f84 100644 --- a/backend/src/uxbox/http/middleware.clj +++ b/backend/src/uxbox/http/middleware.clj @@ -7,9 +7,6 @@ (ns uxbox.http.middleware (:require [promesa.core :as p] [cuerdas.core :as str] - ;; [buddy.core.hash :as hash] - ;; [buddy.core.codecs :as codecs] - ;; [buddy.core.codecs.base64 :as b64] [struct.core :as st] [reitit.ring :as rr] [reitit.ring.middleware.multipart :as multipart] @@ -19,6 +16,7 @@ [ring.middleware.session :refer [wrap-session]] [ring.middleware.session.cookie :refer [cookie-store]] [ring.middleware.multipart-params :refer [wrap-multipart-params]] + [uxbox.http.etag :refer [wrap-etag]] [uxbox.http.cors :refer [wrap-cors]] [uxbox.http.errors :as errors] [uxbox.http.response :as rsp] @@ -124,26 +122,9 @@ {:name ::cors-middleware :wrap #(wrap-cors % cors-conf)}) -;; (def ^:private cors-middleware -;; {:name ::cors-middleware -;; :wrap #(wrap-cors % -;; :access-control-allow-origin [#".*"] -;; :access-control-allow-methods [:get :put :post :delete] -;; :access-control-allow-headers ["x-requested-with" -;; "content-type" -;; "authorization"])}) - -;; (defn digest -;; [^bytes data] -;; (-> (hash/blake2b-256 data) -;; (b64/encode true) -;; (codecs/bytes->str))) - -;; (defn- etag-match? -;; [^Request request ^String new-tag] -;; (let [^Headers headers (.getHeaders request)] -;; (when-let [etag (.get headers "if-none-match")] -;; (= etag new-tag)))) +(def ^:private etag-middleware + {:name ::etag-middleware + :wrap wrap-etag}) (def ^:private exception-middleware (exception/create-exception-middleware @@ -167,6 +148,10 @@ (def middleware [cors-middleware session-middleware + + ;; etag + etag-middleware + parameters/parameters-middleware muuntaja/format-negotiate-middleware ;; encoding response body @@ -175,6 +160,7 @@ exception-middleware ;; decoding request body muuntaja/format-request-middleware + ;; multipart multipart-params-middleware ;; parameters normalization