Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
16 changes: 8 additions & 8 deletions src/babashka/http_client/interceptors.clj
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
19 changes: 18 additions & 1 deletion test/babashka/http_client_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading