sve*_*hie 5 clojure http-post compojure ring undertow
如何:body从compojure 安全地获取InputStream 的内容?
我正在尝试使用Friend使用我的环路径进行身份验证,compojure handler/site但是当我尝试:body从http POST请求(这是一个Java InputStream)读取时,它已关闭:
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]
Run Code Online (Sandbox Code Playgroud)
如果我删除处理程序,问题就会消失.我找到了一个名为groundhog的可能解决方案,它捕获并存储所有请求.我正在使用的库,clojure-paypal-ipn最初reset在流上调用,但是Undertow(或者其他几个Java/Clojure服务器)不支持它,所以我解决了它.
这是与compojure的作者weavejester的相关讨论.
以下是我的代码的一些片段:
(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))
Run Code Online (Sandbox Code Playgroud)
而且,这里的胆量payment.clj(paypal-data和paypal-error刚刚pprint输入现在):
(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 ""})))))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
726 次 |
| 最近记录: |