bidi
bidi copied to clipboard
bidi.ring/make-handler function messes with requests using nginx-clojure-embed.
Had this issue of partly destroyed request maps when using bidi
with nginx-clojure-embed
.
Noticed that nginx returns request as nginx.clojure.clj.LazyRequestMap
type, while for example jetty returns clojure.lang.PersistentHashMap
. (Wrapping request and changing it's type to PersistentHashMap
solved the problem, but I suppose that's not a solution)
Code snippet:
(defn index-handler [req]
{:body (with-out-str (clojure.pprint/pprint req))})
(def routes
["/" {"" index-handler}])
(def bidi-handler
(bidi.ring/make-handler routes))
;(def my-app index-handler)
(def my-app bidi-handler)
(nginx.clojure.embed/run-server my-app {:port 8181})
Result when I use bidi-handler
:
{:body nil,
:server-port "8181",
:remote-addr "127.0.0.1",
:scheme "http",
:content-type nil,
:websocket? false,
:route-params nil}
Result when I call index-handler
directly:
{:uri "/",
:body nil,
:headers
{"Host" "localhost:8181",
"Connection" "keep-alive",
"Cache-Control" "max-age=0",
"Accept"
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Upgrade-Insecure-Requests" "1",
"User-Agent"
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36",
"Accept-Encoding" "gzip, deflate, sdch",
"Accept-Language"
"nb-NO,nb;q=0.8,no;q=0.6,nn;q=0.4,en-US;q=0.2,en;q=0.2,da;q=0.2,lt;q=0.2,sv;q=0.2,ceb;q=0.2",
"Cookie"
"__utma=111872281.1858584428.1455043971.1455043971.1455043971.1; __utmc=111872281; __utmz=111872281.1455043971.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)"},
:server-port "8181",
:server-name "",
:remote-addr "127.0.0.1",
:query-string nil,
:scheme "http",
:request-method :get,
:content-type nil,
:character-encoding nil,
:websocket? false}
We were talking about nginx-clojure over lunch! How coincidental.
Looks like there's some issues with running assoc/update over the map perhaps? https://github.com/juxt/bidi/blob/master/src/bidi/ring.clj#L39 Bidi doesn't do much to the request object, definitely nothing fancy. This needs a little bit of deeper digging to see who should fix what. (I'm not betting the issue is with bidi, on a cursory look into the code)
As you said, a piece of middleware could turn it into a normal persistent hashmap, that seems like a decent solution for now.
Since nginx-clojure 0.4.2. nginx.clojure.clj.LazyRequestMap
has been different from the general PersistentHashMap
.
Calling dissoc
and assoc
on it won't return a new map but the original one. So dissoc
and assoc
will modify the original one.
It seems that bidi
will call dissoc
on the derivative request object and it results the modification of the original request object because every derivative request object by dissoc
or assoc
is the same with the original one.
I see. That explains this behavior then.
In my opinion, that does derive from the ring specification somewhat. I'm not sure bidi's ring handlers should be updated to accommodate derivations from the ring specification.
But theoretically, a protocol could be implemented over the modification to the provided request. If it's a hashmap, assoc like normal, or a LazyRequestMap could have whatever changes are needed there.
Since 0.5.0 nginx-clojure fixed this issue.