clj-http
clj-http copied to clipboard
Circumventing cookies with null domain when you need them even if the domain is null
Recently i had a problem that some cookies were coming from the server with the attribute domain being null, i.e:
Set-Cookie: foo=bar;domain=;expires=Wed, 21 Oct 2021 07:28:00 GMT;
This results in an exception being thrown, saying that the domain of a cookie is null. I could completely ignore the cookies, however, i really need this cookie to proceed to the next request, the server is expecting him, and if he's not on the next request, i wont be able to proceed.
So, I've decided to edit the server response, and add the domain to be equal the host of the request!
I've tried adding clj-http custom middlewares but no success. I'm using cookie-store's for cookies handling, and he didn't updated with the edited cookies.
After thinking that the problem might be the order that my middleware was being called, i thought adding the response editing directly on apache, using this https://github.com/dakrone/clj-http#modifying-apache-specific-features-of-the-httpclientbuilder-and-httpasyncclientbuilder
And at the end i came up with:
(defn null-cookie-domain-formatter [^HttpClientBuilder builder {:keys [server-name] :as _request}]
(.addInterceptorFirst
builder
(proxy [HttpResponseInterceptor] []
(process [resp ctx]
(when-let [null-domain-cookies (->> (.getHeaders resp "Set-Cookie")
(filter #(string/includes? (.getValue %) "domain=;"))
seq)]
(let [modified-cookies-vals (map #(string/replace (.getValue %) "domain=;" (format "domain=%s;" server-name))
null-domain-cookies)]
(doseq [header null-domain-cookies]
(.removeHeader resp header))
(doseq [header-val modified-cookies-vals]
(.addHeader resp "Set-Cookie" header-val))))))))
Then i do requests this way
(http/post "..." {:http-builder-fns [null-cookie-domain-formatter] :cookie-store cookie-store})
And everything is working as expected! This is not exactly an issue with clj-http, however someone else might ran into a similar problem, and i wanted to know opinions about my solution, if there's something more simple than what i did, would be awesome to know.