0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-12 07:41:43 -05:00

Write transit data to response output-stream.

Previously, all responses from GET and POST requests are serialized
to a byte array (using transit) which is returned as response body.

With this commit, the response body of POST requests is written
directly to the response output-stream, reducing the memmory need
to perform that operation.

The responses for GET request still uses the old mechanism because
we need the whole response as byte array for calculate the ETAG and
check it before returning the body.
This commit is contained in:
Andrey Antukh 2021-06-10 16:11:24 +02:00 committed by Alonso Torres
parent 022d57ef42
commit 8d703a3fb4

View file

@ -13,6 +13,7 @@
[buddy.core.codecs :as bc]
[buddy.core.hash :as bh]
[clojure.java.io :as io]
[ring.core.protocols :as rp]
[ring.middleware.cookies :refer [wrap-cookies]]
[ring.middleware.keyword-params :refer [wrap-keyword-params]]
[ring.middleware.multipart-params :refer [wrap-multipart-params]]
@ -73,17 +74,28 @@
{:name ::parse-request-body
:compile (constantly wrap-parse-request-body)})
(defn- transit-streamable-body
[data opts]
(reify rp/StreamableResponseBody
(write-body-to-stream [_ response output-stream]
(try
(let [tw (t/writer output-stream opts)]
(t/write! tw data))
(finally
(.close ^java.io.OutputStream output-stream))))))
(defn- impl-format-response-body
[response]
[response request]
(let [body (:body response)
type :json-verbose]
opts {:type :json-verbose}]
(cond
(coll? body)
(-> response
(assoc :body (t/encode body {:type type}))
(update :headers assoc
"content-type"
"application/transit+json"))
(update :headers assoc "content-type" "application/transit+json")
(assoc :body
(if (= :post (:request-method request))
(transit-streamable-body body opts)
(t/encode body opts))))
(nil? body)
(assoc response :status 204 :body "")
@ -96,7 +108,7 @@
(fn [request]
(let [response (handler request)]
(cond-> response
(map? response) (impl-format-response-body)))))
(map? response) (impl-format-response-body request)))))
(def format-response-body
{:name ::format-response-body