From 4425b1a54cf9e05e05aae2f5d02b089808a9dad6 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sat, 21 Sep 2019 11:01:15 +0000 Subject: [PATCH] :bug: Fix many bugs introduced with body parsing refactor. --- backend/src/uxbox/api/pages.clj | 2 +- backend/src/uxbox/api/projects.clj | 2 +- backend/src/uxbox/http/middleware.clj | 28 ++++++++++++++++++++------- backend/src/uxbox/util/transit.clj | 19 ++++++++++++++---- 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/backend/src/uxbox/api/pages.clj b/backend/src/uxbox/api/pages.clj index 4001c8817..315a19426 100644 --- a/backend/src/uxbox/api/pages.clj +++ b/backend/src/uxbox/api/pages.clj @@ -126,7 +126,7 @@ (s/keys :req-un [::id])) (s/def ::retrieve-page-history|query - (s/keys :req-un [::max + (s/keys :opt-un [::max ::since ::pinned])) diff --git a/backend/src/uxbox/api/projects.clj b/backend/src/uxbox/api/projects.clj index 5167a80d9..9b587cf2c 100644 --- a/backend/src/uxbox/api/projects.clj +++ b/backend/src/uxbox/api/projects.clj @@ -20,7 +20,7 @@ (s/def ::id ::us/uuid) (s/def ::name string?) -(s/def ::version (s/and int? pos?)) +(s/def ::version int?) ;; --- List Projects diff --git a/backend/src/uxbox/http/middleware.clj b/backend/src/uxbox/http/middleware.clj index 3d7c4db9e..8bdd59302 100644 --- a/backend/src/uxbox/http/middleware.clj +++ b/backend/src/uxbox/http/middleware.clj @@ -7,6 +7,7 @@ (ns uxbox.http.middleware (:require [clojure.spec.alpha :as s] + [clojure.java.io :as io] [cuerdas.core :as str] [promesa.core :as p] [reitit.ring :as rr] @@ -208,7 +209,7 @@ (def format-response-middleware (letfn [(process-response [{:keys [body] :as rsp}] - (if body + (if (coll? body) (let [body (t/encode body {:type :json-verbose})] (-> rsp (assoc :body body) @@ -226,11 +227,24 @@ (letfn [(get-content-type [request] (or (:content-type request) (get (:headers request) "content-type"))) + + (slurp-bytes [body] + (with-open [input (io/input-stream body) + output (java.io.ByteArrayOutputStream. (.available input))] + (io/copy input output) + (.toByteArray output))) + + (parse-body [body] + (let [^bytes body (slurp-bytes body)] + (when (pos? (alength body)) + (t/decode body)))) + (process-request [request] (let [ctype (get-content-type request)] (if (= "application/transit+json" ctype) (try - (assoc request :body-params (t/decode (:body request))) + (let [body (parse-body (:body request))] + (assoc request :body-params body)) (catch Exception e (ex/raise :type :parse :message "Unable to parse transit from request body." @@ -243,11 +257,11 @@ ([request] (handler (process-request request))) ([request respond raise] - (try - (let [request (process-request request)] - (handler request respond raise)) - (catch Exception e - (raise e))))))})) + (let [^HttpInput body (:body request)] + (try + (handler (process-request request) respond raise) + (catch Exception e + (raise e)))))))})) (def middleware [cors-middleware diff --git a/backend/src/uxbox/util/transit.clj b/backend/src/uxbox/util/transit.clj index 15c25c0b2..4254a1caf 100644 --- a/backend/src/uxbox/util/transit.clj +++ b/backend/src/uxbox/util/transit.clj @@ -49,17 +49,28 @@ ;; --- High-Level Api +;; TODO: check performance of different options + (defn decode ([data] (decode data nil)) ([data opts] - (with-open [input (io/input-stream data)] - (read! (reader input opts))))) + (cond + (string? data) + (decode (.getBytes data "UTF-8") opts) + + (bytes? data) + (with-open [input (ByteArrayInputStream. data)] + (read! (reader input opts))) + + :else + (with-open [input (io/input-stream data)] + (read! (reader input opts)))))) (defn encode - ([data] + (^bytes [data] (encode data nil)) - ([data opts] + (^bytes [data opts] (with-open [out (ByteArrayOutputStream.)] (let [w (writer out opts)] (write! w data)