diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b0a823..92c6f75 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 + +- [#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)) + ## 0.4.24 (2026-07-26) - [#80](https://github.com/babashka/http-client/issues/80): accept a function of the request URI in `:proxy` to select a proxy per request ([@jeeger](https://github.com/jeeger)) diff --git a/src/babashka/http_client/interceptors.clj b/src/babashka/http_client/interceptors.clj index b3b52ad..b8596b1 100644 --- a/src/babashka/http_client/interceptors.clj +++ b/src/babashka/http_client/interceptors.clj @@ -103,16 +103,16 @@ "We can't use the URI constructor because it encodes all arguments for us. See https://stackoverflow.com/a/77971448/6264" [^java.net.URI uri new-query] - (let [old-query (.getQuery uri) + (let [old-query (.getRawQuery uri) new-query (if old-query (str old-query "&" new-query) new-query)] (java.net.URI. (str (.getScheme uri) "://" - (.getAuthority uri) + (.getRawAuthority uri) (.getRawPath uri) (when-let [nq new-query] (str "?" nq)) - (when-let [f (.getFragment uri)] + (when-let [f (.getRawFragment uri)] (str "#" f)))))) (def query-params @@ -129,12 +129,12 @@ (comment (def uri (java.net.URI. "https://borkdude:foobar@foobar.net:80/single%2felement?q=1#/dude")) (.getScheme uri) ;;=> https - (.getSchemeSpecificPart uri) ;;=> //foobar.net/?q=1 - (.getUserInfo uri) ;;=> nil - (.getAuthority uri) ;;=> "foobar.net" + (.getSchemeSpecificPart uri) ;;=> "//borkdude:foobar@foobar.net:80/single/element?q=1" + (.getUserInfo uri) ;;=> "borkdude:foobar" + (.getRawAuthority uri) ;;=> "borkdude:foobar@foobar.net:80" (.getRawPath uri) ;;=> "/single%2felement" - (.getQuery uri) ;;=> q=1 - (.getFragment uri) ;;=> nil + (.getRawQuery uri) ;;=> "q=1" + (.getRawFragment uri) ;;=> "/dude" (uri-with-query uri "f=dude%26hello")) (def form-params diff --git a/test/babashka/http_client_test.clj b/test/babashka/http_client_test.clj index bee92a9..844f201 100644 --- a/test/babashka/http_client_test.clj +++ b/test/babashka/http_client_test.clj @@ -619,7 +619,24 @@ (is (= "https://borkdude:foobar@foobar.net:80/single%2felement?q=1&q=%26moo#/dude" (str (#'i/uri-with-query (java.net.URI. "https://borkdude:foobar@foobar.net:80/single%2felement?q=1#/dude") - "q=%26moo")))))) + "q=%26moo")))) + (testing "existing query, fragment and user info are not decoded" + (is (= + "https://example.com/search?q=a%26b&page=2" + (str (#'i/uri-with-query (java.net.URI. "https://example.com/search?q=a%26b") + "page=2")))) + (is (= + "https://example.com/search?q=a%20b&page=2" + (str (#'i/uri-with-query (java.net.URI. "https://example.com/search?q=a%20b") + "page=2")))) + (is (= + "https://example.com/p?a=1&page=2#foo%20bar" + (str (#'i/uri-with-query (java.net.URI. "https://example.com/p?a=1#foo%20bar") + "page=2")))) + (is (= + "https://user:p%40ss@example.com/p?a=1&page=2" + (str (#'i/uri-with-query (java.net.URI. "https://user:p%40ss@example.com/p?a=1") + "page=2"))))))) (deftest ring-client-test (testing "inputstring body"