diff --git a/CHANGELOG.md b/CHANGELOG.md index be417a4..9f0d7be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ Babashka [http-client](https://github.com/babashka/http-client): HTTP client for Clojure and babashka built on java.net.http +## Unreleased + +- [#91](https://github.com/babashka/http-client/issues/91): `decode-body` passes a nil body through, e.g. of a 407 to `CONNECT` + ## 0.4.25 (2026-09-11) - [#86](https://github.com/babashka/http-client/issues/86): `uri-with-query` no longer decodes the existing query, fragment and user info when `:query-params` are used ([@dylanpulver](https://github.com/dylanpulver)) diff --git a/src/babashka/http_client/interceptors.clj b/src/babashka/http_client/interceptors.clj index b8596b1..75105fa 100644 --- a/src/babashka/http_client/interceptors.clj +++ b/src/babashka/http_client/interceptors.clj @@ -211,7 +211,7 @@ :response (fn [resp] (let [as (or (-> resp :request :as) :string) body (:body resp) - body (if (not (string? body)) + body (if-not (or (nil? body) (string? body)) (case as :string (slurp body) :stream body diff --git a/test/babashka/http_client_test.clj b/test/babashka/http_client_test.clj index 844f201..438da39 100644 --- a/test/babashka/http_client_test.clj +++ b/test/babashka/http_client_test.clj @@ -549,6 +549,27 @@ (is (thrown-with-msg? clojure.lang.ExceptionInfo #":host and :port" (http/->ProxySelector {:host "127.0.0.1"}))))) +(deftest proxy-connect-407-test + (let [server (java.net.ServerSocket. 0) + port (.getLocalPort server)] + (future (try (loop [] + (with-open [socket (.accept server)] + (let [r (io/reader (.getInputStream socket)) + out (io/writer (.getOutputStream socket))] + (dorun (take-while seq (repeatedly #(.readLine r)))) + (.write out "HTTP/1.1 407 Proxy Authentication Required\r\nProxy-Authenticate: Basic realm=\"x\"\r\nContent-Length: 0\r\n\r\n") + (.flush out))) + (recur)) + (catch Exception _ nil))) + (try + (let [client (http/client {:proxy {:host "127.0.0.1" :port port}})] + (doseq [as [:string :bytes :stream]] + (testing (str "a 407 to CONNECT returns status 407 and a nil body with :as " as) + (let [resp (http/get "https://example.invalid/" {:client client :throw false :as as})] + (is (= 407 (:status resp))) + (is (nil? (:body resp))))))) + (finally (.close server))))) + (deftest cookie-handler-test (testing "nil passthrough" (is (nil? (http/->CookieHandler nil))))