-
Notifications
You must be signed in to change notification settings - Fork 14
Open
Description
I use the proxy to add credentials or offload TLS client cert handling for http clients that don't support these things. Noticed two bugs recently.
- The query parameter '?' was always being appended and newer versions of elasticsearch rejected the query.
- If the http-options included a HTTP header, {:headers {:authorization "Bearer secret-token"}} for example, the request HTTP headers would get removed.
The solutions were to add logic to the :url processing and replace the merge function with the deep-merge function.
index 6a37c33..a2349b0 100644
--- a/src/tailrecursion/ring_proxy.clj
+++ b/src/tailrecursion/ring_proxy.clj
@@ -25,14 +24,19 @@
(.read rdr buf)
buf)))
+(defn deep-merge
+ "Recursively merges maps. If keys are not maps, the last value wins."
+ [& vals]
+ (if (every? map? vals)
+ (apply merge-with deep-merge vals)
+ (last vals)))
+
(defn wrap-proxy
"Proxies requests from proxied-path, a local URI, to the remote URI at
remote-base-uri, also a string."
[handler ^String proxied-path remote-base-uri & [http-opts]]
(wrap-cookies
(fn [req]
(if (.startsWith ^String (:uri req) proxied-path)
(let [rmt-full (URI. (str remote-base-uri "/"))
rmt-path (URI. (.getScheme rmt-full)
@@ -40,8 +44,8 @@
(.getPath rmt-full) nil nil)
lcl-path (URI. (subs (:uri req) (.length proxied-path)))
remote-uri (.resolve rmt-path lcl-path) ]
- (-> (merge {:method (:request-method req)
- :url (str remote-uri "?" (:query-string req))
+ (-> (deep-merge {:method (:request-method req)
+ :url (str remote-uri (if (nil? (:query-string req)) "" "?") (:query-string req))
:headers (dissoc (:headers req) "host" "content-length")
:body (if-let [len (get-in req [:headers "content-length"])]
(slurp-binary (:body req) (Integer/parseInt len)))
Metadata
Metadata
Assignees
Labels
No labels