ring

2021-08-02T00:17:32.003700Z

I have a simple server running and when I try to access a POST endpoint, it doesn’t return the add-record handler, instead goes the the not-found handler. On the network tab, it actually says that the request method is a GET. What am I missing here? Also if I curl -v http:/127.0.0.1:3000/foo , I get HTTP/1.1 404 Not Found The GET endpoint works fine.

(ns practice.server
  (:require
     [compojure.core :refer [defroutes GET POST]]
     [org.httpkit.server :as server]
     [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
     [compojure.route :as route]))

(defn add-record 
  [req]
  (println req))

(defn get-bar 
  [req]
  {:status 200
   :headers {"Content-Type" "text/html"}
   :body "Hello World"})

(defroutes app-routes
  (POST "/foo" [] add-record)
  (GET "/bar" [] get-bar)
  (route/not-found "Error, page not found!"))

(defn web-server
  [& args]
  (let [port (Integer/parseInt (or (System/getenv "PORT") "3000"))]
    ; Run the server with Ring.defaults middleware
    (server/run-server (wrap-defaults #'app-routes site-defaults) {:port port})
    (println (str "Running webserver at http:/127.0.0.1:" port "/"))))

seancorfield 2021-08-02T00:28:52.005Z

@audyarandela That is because your handler returns nil (from the println call) and Compojure treats a nil handler response as "doesn't match" and moves on to the next possible route match, which will be not-found in this case.

seancorfield 2021-08-02T00:29:10.005400Z

As soon as you make add-record return a response, it will work as you expect.

2021-08-02T00:34:29.006300Z

Thanks for your response! I just tried adding a simple response, same as get-bar and still was getting the same 404 error.

2021-08-02T00:37:02.007200Z

Oddly enough, when I change the POST route to ANY it works. But thats not REST-y and the request method on the network tab shows GET still

seancorfield 2021-08-02T00:40:42.007800Z

Are you sure you're sending a POST request with curl? I thought you needed -d to POST data...

2021-08-02T00:43:13.008500Z

Yes you’re correct, -d is needed for POST. getting a different error now, <h1>Invalid anti-forgery token</h1>

2021-08-02T00:44:14.009700Z

When trying to access it via web browser, all I was getting was that 404 error and seeing that the request method was GET, time to google some more with the new error lol

2021-08-02T00:47:41.011100Z

Thanks @seancorfield, I disabled the :security and :anti-forgery in site-defaults and was able to curl through. (its only a practice app to understand the tech)

seancorfield 2021-08-02T00:53:51.012100Z

Yeah, to use curl when you have CSRF in place you need to GET the form first, copy the anti-forgery token in it, then POST the form fields and the anti-forgery token.

seancorfield 2021-08-02T00:55:25.013Z

The idea behind CSRF is that you can't just randomly POST stuff to an app -- you have to actually fill in the form fields and then submit the form. That's the security aspect of it 🙂

2021-08-02T00:56:09.013700Z

Yea that makes sense now lol. Probably also why the web browser showing an error because it doesn’t have the right credentials

seancorfield 2021-08-02T01:17:48.015Z

I think you have to actually add stuff to the form so that the CSRF token is available as a hidden field... I've never used it myself (I mostly do REST APIs which use the API defaults, not the site default).

seancorfield 2021-08-02T01:18:32.015800Z

ring-defaults is good for that -- there's API, secure API, web site, and secure web site I think as four base profiles.