From 504f833a539a3cb584c443731486bb7fbb4dde0f Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 18 Jun 2024 14:42:58 +0200 Subject: [PATCH 1/3] :bug: Fix global error handler incorrect body encoding --- backend/src/app/http.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/app/http.clj b/backend/src/app/http.clj index a696d54776..cacf158056 100644 --- a/backend/src/app/http.clj +++ b/backend/src/app/http.clj @@ -114,7 +114,7 @@ (partial not-found-handler request))) (on-error [cause request] - (let [{:keys [body] :as response} (errors/handle cause request)] + (let [{:keys [::rres/body] :as response} (errors/handle cause request)] (cond-> response (map? body) (-> (update ::rres/headers assoc "content-type" "application/transit+json") From 06bab212b53ce82e39d50e0d5c82e8f9135f96b7 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 18 Jun 2024 14:43:15 +0200 Subject: [PATCH 2/3] :bug: Set correct order for http middlewares --- backend/src/app/http.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/app/http.clj b/backend/src/app/http.clj index cacf158056..c45c95c1cd 100644 --- a/backend/src/app/http.clj +++ b/backend/src/app/http.clj @@ -150,10 +150,10 @@ [["" {:middleware [[mw/server-timing] [mw/params] [mw/format-response] + [mw/errors errors/handle] [mw/parse-request] [session/soft-auth cfg] [actoken/soft-auth cfg] - [mw/errors errors/handle] [mw/restrict-methods]]} (::mtx/routes cfg) From 3363793d647093a72b9f683681e4e3cb5c50a09f Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 18 Jun 2024 14:44:25 +0200 Subject: [PATCH 3/3] :bug: Fix json encoding truncation issue --- backend/src/app/http/middleware.clj | 37 +++++++++++++++++----------- backend/src/app/util/objects_map.clj | 7 +++++- backend/src/app/util/pointer_map.clj | 11 ++++++++- 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/backend/src/app/http/middleware.clj b/backend/src/app/http/middleware.clj index 4ea815f07f..a6eabd9a4f 100644 --- a/backend/src/app/http/middleware.clj +++ b/backend/src/app/http/middleware.clj @@ -10,16 +10,13 @@ [app.common.logging :as l] [app.common.transit :as t] [app.config :as cf] - [app.util.json :as json] + [clojure.data.json :as json] [cuerdas.core :as str] [ring.request :as rreq] [ring.response :as rres] [yetti.adapter :as yt] [yetti.middleware :as ymw]) (:import - com.fasterxml.jackson.core.JsonParseException - com.fasterxml.jackson.core.io.JsonEOFException - com.fasterxml.jackson.databind.exc.MismatchedInputException io.undertow.server.RequestTooBigException java.io.InputStream java.io.OutputStream)) @@ -34,11 +31,22 @@ {:name ::params :compile (constantly ymw/wrap-params)}) -(def ^:private json-mapper - (json/mapper - {:encode-key-fn str/camel - :decode-key-fn (comp keyword str/kebab) - :pretty true})) +(defn- get-reader + ^java.io.BufferedReader + [request] + (let [^InputStream body (rreq/body request)] + (java.io.BufferedReader. + (java.io.InputStreamReader. body)))) + +(defn- read-json-key + [k] + (-> k str/kebab keyword)) + +(defn- write-json-key + [k] + (if (or (keyword? k) (symbol? k)) + (str/camel k) + (str k))) (defn wrap-parse-request [handler] @@ -53,8 +61,8 @@ (update :params merge params)))) (str/starts-with? header "application/json") - (with-open [^InputStream is (rreq/body request)] - (let [params (json/decode is json-mapper)] + (with-open [reader (get-reader request)] + (let [params (json/read reader :key-fn read-json-key)] (-> request (assoc :body-params params) (update :params merge params)))) @@ -74,9 +82,7 @@ :code :request-body-too-large :hint (ex-message cause)) - (or (instance? JsonEOFException cause) - (instance? JsonParseException cause) - (instance? MismatchedInputException cause)) + (instance? java.io.EOFException cause) (ex/raise :type :validation :code :malformed-json :hint (ex-message cause) @@ -128,7 +134,8 @@ (-write-body-to-stream [_ _ output-stream] (try (with-open [^OutputStream bos (buffered-output-stream output-stream buffer-size)] - (json/write! bos data json-mapper)) + (with-open [^java.io.OutputStreamWriter writer (java.io.OutputStreamWriter. bos)] + (json/write data writer :key-fn write-json-key))) (catch java.io.IOException _) (catch Throwable cause diff --git a/backend/src/app/util/objects_map.clj b/backend/src/app/util/objects_map.clj index 19a7bdea63..c7e4f42eb4 100644 --- a/backend/src/app/util/objects_map.clj +++ b/backend/src/app/util/objects_map.clj @@ -19,7 +19,8 @@ [app.common.fressian :as fres] [app.common.transit :as t] [app.common.uuid :as uuid] - [clojure.core :as c]) + [clojure.core :as c] + [clojure.data.json :as json]) (:import clojure.lang.Counted clojure.lang.IHashEq @@ -83,6 +84,10 @@ ^:unsynchronized-mutable loaded? ^:unsynchronized-mutable modified?] + json/JSONWriter + (-write [this writter options] + (json/-write (into {} this) writter options)) + IHashEq (hasheq [this] (when-not hash diff --git a/backend/src/app/util/pointer_map.clj b/backend/src/app/util/pointer_map.clj index 16ce73bb0a..ba84d3d4be 100644 --- a/backend/src/app/util/pointer_map.clj +++ b/backend/src/app/util/pointer_map.clj @@ -40,7 +40,8 @@ [app.common.transit :as t] [app.common.uuid :as uuid] [app.util.time :as dt] - [clojure.core :as c]) + [clojure.core :as c] + [clojure.data.json :as json]) (:import clojure.lang.Counted clojure.lang.IDeref @@ -75,6 +76,14 @@ ^:unsynchronized-mutable modified? ^:unsynchronized-mutable loaded?] + json/JSONWriter + (-write [this writter options] + (json/-write {:type "pointer" + :id (get-id this) + :meta (meta this)} + writter + options)) + IPointerMap (load! [_] (when-not *load-fn*