Skip to content

Commit 8dfe243

Browse files
committed
Bring parity to json and transit+json coerce handling
Adds the :coerce setting to transit+json handling Handles empty bodies when coercing with transit+json
1 parent 86876c5 commit 8dfe243

File tree

2 files changed

+52
-7
lines changed

2 files changed

+52
-7
lines changed

src/clj_http/client.clj

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -462,10 +462,26 @@
462462
(read-string (String. ^"[B" body charset)))))))
463463

464464
(defn coerce-transit-body
465-
[{:keys [transit-opts] :as request} {:keys [body] :as resp} type]
466-
(if transit-enabled?
467-
(assoc resp :body (parse-transit body type transit-opts))
468-
resp))
465+
[{:keys [transit-opts coerce] :as request} {:keys [body status] :as resp} type & [charset]]
466+
(let [^String charset (or charset (-> resp :content-type-params :charset)
467+
"UTF-8")
468+
body (util/force-byte-array body)]
469+
(if-not (empty? body)
470+
(if transit-enabled?
471+
(cond
472+
(= coerce :always)
473+
(assoc resp :body (parse-transit (ByteArrayInputStream. body) type transit-opts))
474+
475+
(and (unexceptional-status? status)
476+
(or (nil? coerce) (= coerce :unexceptional)))
477+
(assoc resp :body (parse-transit (ByteArrayInputStream. body) type transit-opts))
478+
479+
(and (not (unexceptional-status? status)) (= coerce :exceptional))
480+
(assoc resp :body (parse-transit (ByteArrayInputStream. body) type transit-opts))
481+
482+
:else (assoc resp :body (String. ^"[B" body charset)))
483+
(assoc resp :body (String. ^"[B" body charset)))
484+
(assoc resp :body nil))))
469485

470486
(defn coerce-form-urlencoded-body
471487
[request {:keys [body] :as resp}]

test/clj_http/test/core_test.clj

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@
5656
"[\"~#set\",[1,3,2]]],\"~:baz\",\"~f7\","
5757
"\"~:foo\",\"bar\"]")
5858
:headers {"content-type" "application/transit+json"}}
59+
[:get "/transit-json-bad"]
60+
{:status 400 :body "[\"^ \", \"~:foo\",\"bar\"]"}
61+
[:get "/transit-json-empty"]
62+
{:status 200
63+
:headers {"content-type" "application/transit+json"}}
5964
[:get "/transit-msgpack"]
6065
{:status 200
6166
:body (->> [-125 -86 126 58 101 103 103 112 108 97 110 116 -127 -90 126
@@ -338,13 +343,37 @@
338343
(run-server)
339344
(let [transit-json-resp (client/get (localhost "/transit-json") {:as :auto})
340345
transit-msgpack-resp (client/get (localhost "/transit-msgpack")
341-
{:as :auto})]
346+
{:as :auto})
347+
bad-status-resp-default (client/get (localhost "/transit-json-bad")
348+
{:throw-exceptions false :as :transit+json})
349+
bad-status-resp-always (client/get (localhost "/transit-json-bad")
350+
{:throw-exceptions false :as :transit+json
351+
:coerce :always})
352+
bad-status-resp-exceptional (client/get (localhost "/transit-json-bad")
353+
{:throw-exceptions false :as :transit+json
354+
:coerce :exceptional})
355+
empty-resp (client/get (localhost "/transit-json-empty")
356+
{:throw-exceptions false :as :transit+json})]
342357
(is (= 200
343358
(:status transit-json-resp)
344-
(:status transit-msgpack-resp)))
359+
(:status transit-msgpack-resp)
360+
(:status empty-resp)))
361+
(is (= 400
362+
(:status bad-status-resp-default)
363+
(:status bad-status-resp-always)
364+
(:status bad-status-resp-exceptional)))
345365
(is (= {:foo "bar" :baz 7M :eggplant {:quux #{1 2 3}}}
346366
(:body transit-json-resp)
347-
(:body transit-msgpack-resp)))))
367+
(:body transit-msgpack-resp)))
368+
369+
(is (nil? (:body empty-resp)))
370+
371+
(is (= "[\"^ \", \"~:foo\",\"bar\"]"
372+
(:body bad-status-resp-default)))
373+
(is (= {:foo "bar"}
374+
(:body bad-status-resp-always)))
375+
(is (= {:foo "bar"}
376+
(:body bad-status-resp-exceptional)))))
348377

349378
(deftest ^:integration t-json-output-coercion
350379
(run-server)

0 commit comments

Comments
 (0)