clojure http-post ring compojure undertow

clojure - Compojure handler friend/authenticate come el cuerpo de la solicitud POST



http-post ring (0)

¿Cómo puedo obtener de forma segura el contenido de :body InputStream de compojure?

Ver preguntas relacionadas pero diferentes para el fondo.

Estoy tratando de autenticar mis rutas de anillo con Friend usando compojure handler/site pero cuando trato de leer el :body de una POST http POST (que es Java InputStream ), se cierra:

23:01:20.505 ERROR [io.undertow.request] (XNIO-1 task-3) Undertow request failed HttpServerExchange{ POST /paypal/ipn} java.io.IOException: UT000034: Stream is closed at io.undertow.io.UndertowInputStream.read(UndertowInputStream.java:84) ~[undertow-core-1.1.0.Final.jar:1.1.0.Final] at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) ~[na:1.8.0_45] at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) ~[na:1.8.0_45] at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) ~[na:1.8.0_45] at java.io.InputStreamReader.read(InputStreamReader.java:184) ~[na:1.8.0_45] at java.io.BufferedReader.fill(BufferedReader.java:161) ~[na:1.8.0_45] at java.io.BufferedReader.read(BufferedReader.java:182) ~[na:1.8.0_45] at clojure.core$slurp.doInvoke(core.clj:6650) ~[clojure-1.7.0-beta1.jar:na] at clojure.lang.RestFn.invoke(RestFn.java:410) ~[clojure-1.7.0-beta1.jar:na]

Si elimino el controlador, el problema desaparece. He encontrado una posible solución llamada groundhog que captura y almacena todas las solicitudes. La biblioteca que estoy usando, clojure-paypal-ipn originalmente se llamaba reset en la transmisión , pero eso no es compatible con Undertow (ni tampoco con otros servidores Java / Clojure), así que trabajé en torno a eso.

Aquí hay una discusión relacionada con weavejester, autor de compojure.

Aquí hay algunos fragmentos de mi código:

(defroutes routes ... (POST "/paypal/ipn" [] (payment/paypal-ipn-handler payment/paypal-data payment/paypal-error paypal-sandbox?)) (route/resources "/")) (defn authenticate-routes "Add Friend handler to routes" [routes-set] (handler/site (friend/authenticate routes-set friend-settings))) ;; middleware below from immutant.web.middleware (defn -main [& {:as args}] (web/run (-> routes (web-middleware/wrap-session {:timeout 20}) (authenticate-routes) ; use friend handler ;; wrap the handler with websocket support ;; websocket requests will go to the callbacks, ring requests to the handler (web-middleware/wrap-websocket websocket-callbacks)) args))

Y aquí están las agallas de payment.clj ( paypal-data y paypal-error solo entrada de pprint este momento):

(defn req->body-str [req] "Get request body from ring POST http request" (let [input-stream (:body req)] (let [raw-body-str (slurp input-stream)] raw-body-str))) (defn paypal-ipn-handler ([on-success on-failure] (paypal-ipn-handler on-success on-failure true)) ([on-success on-failure sandbox?] (fn [req] (let [body-str (req->body-str req) ipn-data (paypal/parse-paypal-ipn-string body-str)] (do (.start (Thread. (fn [] (paypal/handle-ipn ipn-data on-success on-failure sandbox?)))) ; respond to PayPal right away, then go and process the ipn-data {:status 200 :headers {"Content-Type" "text/html"} :body ""})))))