简体   繁体   中英

lein ring auto-refresh overwrites request body?

I wrote simple client-server app referring to "ClojureScript: Up and Running".

https://github.com/phaendal/clojure-simple-client-server

As shown in below server-code, /text prints request and body to console and returns body from (slurp (:body req)) .

But if :auto-refresh? is set to true in project.clj , (slurp (:body req)) will returns empty string instead of sent value.

Why it returns empty? and How to get request-body with auto-refresh?

(ns client-server.server
  (:gen-class)
  (:require [compojure.route :as route]
            [compojure.core :as compojure]
            [ring.util.response :as response]))

(defn simple-print [req]
  (let [body (slurp (:body req) :encoding "utf-8")]
    (println req)
    (println (str "slurped: " body))
    body))

(compojure/defroutes app
  (compojure/POST "/text" request (simple-print request))
  (compojure/GET "/" request
                 (-> "public/index.html"
                     (response/resource-response)
                     (response/content-type "text/html")
                     (response/charset "utf-8")))
  (route/resources "/"))

When you set auto-refresh: true , lein-ring also adds ring.middleware.params through wrap-params . see https://github.com/weavejester/ring-refresh/blob/master/src/ring/middleware/refresh.clj#L90-L102 .

The ring.middleware.params do its job to parse form-parameter from request body by draining the request body through slurp just like you do in your handler. see https://github.com/mmcgrana/ring/blob/master/ring-core/src/ring/middleware/params.clj#L29

So, the request body already emptied by the time you try to slurp it in your handler.

Also, when you try to POST, please pay attention to the content-type sent. It's application/www-form-urlencoded by default and it needs parameter name and value. see http://www.w3.org/MarkUp/html-spec/html-spec_8.html#SEC8.2.1

Just sending the plain value just like you do in your clojurescript does not play nice with form-parameter parser. In your project example, ring param middleware just skip it because the value sent from your javascript does not conform to the spec. If you put name and value in your POST request, it shows up in :params key in your request.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM