zcaudate
zcaudate

Reputation: 14258

where does ring get the wrap-params information for forms?

I'm trying to delve deeper into ring and have the following code to look at what is going on in the request map:

(require '[ring.adapter.jetty :as serv])
(require '[ring.middleware.params :as wp])

(defn base-handler [params]
  {:code 200
   :type "txt/html"
   :body (str params)})

(defn wp-handler [params]
  ((wp/wrap-params base-handler) params))

(serv/run-jetty #'wp-handler {:port 8099})

When I want to look at the get query data on the request map, it is there. Say i typed in http://localhost:8099/api/tasks/remove?hello=3 in the browser the response looks something like this:

{:ssl-client-cert nil, 
 :remote-addr "127.0.0.1", 
 :scheme :http, 
 :request-method :get, 
 :uri "/api/tasks/remove"
 :query-string "hello=3"
  .... more ....}

and you can see that "hello=3" is in the query string.


But for post, the response has :content-type "application/x-www-form-urlencoded", the entire response looks like this example below and I do not see any form parameters:

{:ssl-client-cert nil, :remote-addr "127.0.0.1", :scheme :http, :request-method :post, :query-string nil, :content-type "application/x-www-form-urlencoded", :uri "/api/tasks/remove", :server-name "localhost", :headers {"user-agent" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.47 Safari/536.11", "origin" "http://localhost:8099", "accept-charset" "ISO-8859-1,utf-8;q=0.7,*;q=0.3", "accept" "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "host" "localhost:8099", "referer" "http://localhost:8099/form.html", "content-type" "application/x-www-form-urlencoded", "cache-control" "max-age=0", "accept-encoding" "gzip,deflate,sdch", "content-length" "23", "accept-language" "en-US,en;q=0.8", "connection" "keep-alive"}, :content-length 23, :server-port 8099, :character-encoding nil, :body #}

My question is in two parts:

  1. What exactly is ring or jetty doing when a form is submitted?
  2. If i'm trying to write my own handler for handling form data, what is a simplified code skeleton of how I am able to access the form query parameters?

I've isolated the 'magic' to this function in params.clj:

(defn- assoc-form-params
  "Parse and assoc parameters from the request body with the request."
  [request encoding]
  (merge-with merge request
    (if-let [body (and (urlencoded-form? request) (:body request))]
      (let [params (parse-params (slurp body :encoding encoding) encoding)]
        {:form-params params, :params params})
      {:form-params {}, :params {}})))

in particular this line:

(parse-params (slurp body :encoding encoding) encoding)

but am not sure what it is doing.

Upvotes: 2

Views: 2328

Answers (1)

Ivan Koblik
Ivan Koblik

Reputation: 4315

Judging by source code of urlencode-form? parse-params is never called as your request is application/x-www-form-urlencoded. Please see description of request types here.

How do you send post request? As far as I understand what happens is parameters are sent in multipart/form-data mode, but request itself is marked as application/x-www-form-urlencoded.

Upvotes: 0

Related Questions