Fork me on GitHub
#ring
<
2021-08-02
>
Audy00:08:32

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 "/"))))

seancorfield00:08:52

@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.

seancorfield00:08:10

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

Audy00:08:29

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

Audy00:08:02

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

seancorfield00:08:42

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

Audy00:08:13

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

Audy00:08:14

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

Audy00:08:41

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)

seancorfield00:08:51

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.

seancorfield00:08:25

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 🙂

Audy00:08:09

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

seancorfield01:08:48

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).

seancorfield01:08:32

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