🐛 Fix many bugs introduced with body parsing refactor.

This commit is contained in:
Andrey Antukh 2019-09-21 11:01:15 +00:00
parent e45ad2197a
commit 4425b1a54c
4 changed files with 38 additions and 13 deletions

View file

@ -126,7 +126,7 @@
(s/keys :req-un [::id])) (s/keys :req-un [::id]))
(s/def ::retrieve-page-history|query (s/def ::retrieve-page-history|query
(s/keys :req-un [::max (s/keys :opt-un [::max
::since ::since
::pinned])) ::pinned]))

View file

@ -20,7 +20,7 @@
(s/def ::id ::us/uuid) (s/def ::id ::us/uuid)
(s/def ::name string?) (s/def ::name string?)
(s/def ::version (s/and int? pos?)) (s/def ::version int?)
;; --- List Projects ;; --- List Projects

View file

@ -7,6 +7,7 @@
(ns uxbox.http.middleware (ns uxbox.http.middleware
(:require (:require
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[clojure.java.io :as io]
[cuerdas.core :as str] [cuerdas.core :as str]
[promesa.core :as p] [promesa.core :as p]
[reitit.ring :as rr] [reitit.ring :as rr]
@ -208,7 +209,7 @@
(def format-response-middleware (def format-response-middleware
(letfn [(process-response [{:keys [body] :as rsp}] (letfn [(process-response [{:keys [body] :as rsp}]
(if body (if (coll? body)
(let [body (t/encode body {:type :json-verbose})] (let [body (t/encode body {:type :json-verbose})]
(-> rsp (-> rsp
(assoc :body body) (assoc :body body)
@ -226,11 +227,24 @@
(letfn [(get-content-type [request] (letfn [(get-content-type [request]
(or (:content-type request) (or (:content-type request)
(get (:headers request) "content-type"))) (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] (process-request [request]
(let [ctype (get-content-type request)] (let [ctype (get-content-type request)]
(if (= "application/transit+json" ctype) (if (= "application/transit+json" ctype)
(try (try
(assoc request :body-params (t/decode (:body request))) (let [body (parse-body (:body request))]
(assoc request :body-params body))
(catch Exception e (catch Exception e
(ex/raise :type :parse (ex/raise :type :parse
:message "Unable to parse transit from request body." :message "Unable to parse transit from request body."
@ -243,11 +257,11 @@
([request] ([request]
(handler (process-request request))) (handler (process-request request)))
([request respond raise] ([request respond raise]
(try (let [^HttpInput body (:body request)]
(let [request (process-request request)] (try
(handler request respond raise)) (handler (process-request request) respond raise)
(catch Exception e (catch Exception e
(raise e))))))})) (raise e)))))))}))
(def middleware (def middleware
[cors-middleware [cors-middleware

View file

@ -49,17 +49,28 @@
;; --- High-Level Api ;; --- High-Level Api
;; TODO: check performance of different options
(defn decode (defn decode
([data] ([data]
(decode data nil)) (decode data nil))
([data opts] ([data opts]
(with-open [input (io/input-stream data)] (cond
(read! (reader input opts))))) (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 (defn encode
([data] (^bytes [data]
(encode data nil)) (encode data nil))
([data opts] (^bytes [data opts]
(with-open [out (ByteArrayOutputStream.)] (with-open [out (ByteArrayOutputStream.)]
(let [w (writer out opts)] (let [w (writer out opts)]
(write! w data) (write! w data)