bidi icon indicating copy to clipboard operation
bidi copied to clipboard

bidi.ring/make-handler function messes with requests using nginx-clojure-embed.

Open kveselis opened this issue 8 years ago • 4 comments

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}

kveselis avatar Feb 19 '16 14:02 kveselis

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.

SevereOverfl0w avatar Feb 19 '16 15:02 SevereOverfl0w

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.

xfeep avatar Feb 21 '16 03:02 xfeep

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.

SevereOverfl0w avatar Feb 21 '16 07:02 SevereOverfl0w

Since 0.5.0 nginx-clojure fixed this issue.

xfeep avatar Dec 26 '20 13:12 xfeep