Unable to parse EDN in this server request

I think I am doing everything right, but I cannot get my EDN from the input stream :body

. Ring handler and Compojure:

dependencies:

 [ring.middleware.params :as params]
 [ring.middleware.edn :as edn]; https://github.com/tailrecursion/ring-edn

      

Handler:

(defroutes ajax-example
  (PUT "/ajax-example" r
       (println r)
       {:status 200
        :headers {"Content-Type" "application/edn"}
        :body "yo"}))

      

I'll wrap it up like:

  (def ajax-wrapped
   (-> ajax-example
      edn/wrap-edn-params
      params/wrap-params))

      

Correct answer println

'd shows it is EDN and content length is correct based on a simple test card I am posting, but the card itself is not found anywhere, it is forever captured by the input stream from :body

... how to get to it?

Here is println's answer:

{: ssl-client-cert nil ,: remote-addr 0: 0: 0: 0: 0: 0: 0: 1 ,: params {} ,: route-params {} ,: headers {origin http: // localhost : 6542 , host localhost: 6542, Mozilla user agent / 5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit / 537.36 (KHTML like Gecko) Chrome / 42.0.2311.135 Safari / 537.36, content type app / edn, cookie _ga = GA1 .1.1354518981.1429622648; content-length 20, referer http: // localhost: 6542 /, keep-alive connection, accept /, accept-language en-US, en; q = 0.8, sq; q = 0.6, accept-encoding gzip, deflate, sdch, cache-control max-age = 0} ,: server-port 6542 ,: content-length 20 ,: form- params {} ,: query-params {} ,: application-type application / edn ,: character-encoding nil ,: uri / ajax-example ,: server-name localhost ,: query-string nil ,: body # ,: edn -params nil ,: scheme: http ,: request- method: put}

The: body is not inserted correctly above, it looks like this:

 [open corner bracket] HttpInput org.eclipse.jetty.server.HttpInput@5d969109 [end corner bracket]

      

Client code sent from browser using cljs-ajax

lib:

(defn ajax-send
  []
  (let [push {:adder1 2 :add2 3}]
    (PUT "/ajax-example" 
         {:format :edn 
          :params push
          :handler ajax-result
          :error-handler error-handler})))

      

Here is the result of the test suggested by one of the answers:

hf.examples> ((-> ajax-example  params/wrap-params edn/wrap-edn-params) (-> (mock/request :put "/ajax-example")
                                                             (mock/content-type "application/edn")
                                                             (mock/body "{:hello \"there\"}"))) 
{:status 200,
 :headers {"Content-Type" "application/edn"},
 :body
 "{:remote-addr \"localhost\", :params {:hello \"there\"}, :route-params {}, :headers {\"content-length\" \"16\", \"content-type\" \"application/edn\", \"host\" \"localhost\"}, :server-port 80, :content-length 16, :form-params {}, :query-params {}, :content-type \"application/edn\", :uri \"/ajax-example\", :server-name \"localhost\", :query-string nil, :edn-params {:hello \"there\"}, :scheme :http, :request-method :put}"}
hf.examples> 

      

I also tried this:

(defroutes ajax-example
  (PUT "/ajax-example" r
       {:status 200
        :headers {"Content-Type" "application/edn"}
        :body (pr-str (dissoc r :body))}))

      

Curling result regardless of front end:

curl -X PUT -H "Content-Type: application/edn" -d '{:name :barnabas}' http://localhost:6542/ajax-example
{:ssl-client-cert nil, :remote-addr "0:0:0:0:0:0:0:1", :params {}, :route-params {}, :headers {"host" "localhost:6542", "content-length" "17", "content-type" "application/edn", "user-agent" "curl/7.37.1", "accept" "*/*"}, :server-port 6542, :content-length 17, :content-type "application/edn", :character-encoding nil, :uri "/ajax-example", :server-name "localhost", :query-string nil, :edn-params nil, :scheme :http, :request-method

      

content-length

of 17 corresponds to the number of symbols on the card transmitted via Curl. But edn-params

- this is zero! Where is the content located?

+3


source to share


2 answers


EDIT . As an answer to the updated question, the wrap-edn-params function consumes the request body by reading in full: body InputStream. Compojure routes pass the request to each parameter handler until non nil is returned. In this case, whichever handler is passed to the routes, since the first handler will consume: the body and will not: the body value for the 2nd handler to be consumed, resulting in the nil value of the body being read using wrap-edn-params.

The request passed to the call handler probably does not have its own content type equal to edn. The wrap-edn-params function will only parse edn if the request content type is set to edn.



Also, the parsed edn parameters will only be placed in the: params and: edn-params query map keys using the wrap-edn-params function, and therefore: body should not be used to access the parsed edn.

(require '[ring.mock.request :as mock])
(require '[ring.middleware.edn :as edn]) 

((-> ajax-example  params/wrap-params edn/wrap-edn-params) (-> (mock/request :put "/ajax-example")
                                                             (mock/content-type "application/edn")
                                                             (mock/body "{:hello \"there\"}"))) 

{:remote-addr "localhost",
 :params {:hello "there"},
 :route-params {},
 :headers
 {"content-length" "16",
  "content-type" "application/edn",
  "host" "localhost"},
 :server-port 80,
 :content-length 16,
 :form-params {},
 :query-params {},
 :content-type "application/edn",
 :uri "/ajax-example",
 :server-name "localhost",
 :query-string nil,
 :body #<ByteArrayInputStream java.io.ByteArrayInputStream@171788d8>,
 :edn-params {:hello "there"},
 :scheme :http,
 :request-method :put}

      

+3


source


I fixed this, but I don't know why the problem exists. I had another independent route that also wrapped EDN medium cookware. Here's an example of reproducibility:

(defroutes example-routes2
  (PUT "/test-edn" r
       (println r)
       {:status 200
        :headers {"Content-Type" "application/edn"}
        :body (pr-str (str "request is: " r))}))

(defroutes ajax-example
  (PUT "/ajax-example" r
       (println r)
       {:status 200
        :headers {"Content-Type" "application/edn"}
        :body (pr-str (str "request is: " r))}))

(def edn-routes 
  (-> example-routes2
      edn/wrap-edn-params))

(def ajax-wrapped
  (-> ajax-example
      edn/wrap-edn-params))

;;combining all routes on this page into a single handler
(def example-routes (routes example-routes1  ajax-wrapped edn-routes))

      

Note that these two routes are essentially identical and wrap the same way. The one that cannot parse the EDN in edn-params is the second one specified in example-routes

def!

curl -X PUT -H "Content-Type: application / edn" -d '{: name: barnabasss}' http: // localhost: 6542 / test-edn

returns:



": {: ssl-client-cert nil ,: remote-addr \" 0: 0: 0: 0: 0: 0: 0: 1 \ ",: params {} ,: route-params {} ,: headers { \ "host \" \ "localhost: 6542 \", \ "content-length \" \ "19 \", \ "content-type \" \ "application / edn \", \ "user-agent \" \ " curl / 7.37.1 \ ", \" accept \ "\" / \ "} ,: server-port 6542 ,: content-length 19 ,: content-type \" application / edn \ ",: character encoding nil ,: uri \ "/ test -edn \",: server_name \ "localhost \",: query string nil,: body #,: edn-params nil ,: scheme: http ,: request-method: put} "

curl -X PUT -H "Content-Type: application / edn" -d '{: name: barnabasss}' http: // localhost: 6542 / ajax-example

returns:



": {: ssl-client-cert nil ,: remote-addr \" 0: 0: 0: 0: 0: 0: 0: 1 \ ",: params {: name: barnabasss} ,: route-params {} ,: headers {\ "host \" \ "localhost: 6542 \", \ "content-length \" \ "19 \", \ "content-type \" \ "application / edn \", \ "user-agent \ "\" curl / 7.37.1 \ ", \" accept \ "\" / \ "} ,: server-port 6542 ,: content-length 19 ,: content-type \" application / edn \ ",: character -encoding nil ,: uri \ "/ ajax -example \",: server-name \ "localhost \",: query-string noil ,: body #,: edn-params {: name: barnabasss},: scheme: http ,: request-method: put} "

Switching their order in switches example-routes

that works. Can someone please explain?

0


source







All Articles