Hello,
Are decorators and requirements mutually exclusive?
Look at the following example. I was trying to setup a route for the same URL
and distinguishing between them via a :requirement declaration on the
authorization header. It works as expected but then I tried to add a
decorator on top of it and it seems to break the routing selection.
(ql:quickload '("restas" "drakma"))
(restas:define-module #:scratch
(:use :cl))
(in-package #:scratch)
(restas:start :scratch :port 8080)
(setf drakma:*header-stream* *standard-output*)
;;; Auth decorator from the documentation
(defclass http-auth-route (routes:proxy-route) ())
(defmethod routes:route-check-conditions ((route http-auth-route) bindings)
(and (call-next-method)
(multiple-value-bind (u p) (hunchentoot:authorization)
(or (and (string= u "foo")
(string= p "bar"))
(hunchentoot:require-authorization)))))
(defun http-auth-require (route)
(make-instance 'http-auth-route :target route))
;;; Simple route
(restas:define-route foo ("foo")
(setf (hunchentoot:content-type*) "text/plain")
"foo")
;;; Works as expected
(nth-value 0 (drakma:http-request "
http://localhost:8080/foo"))
;;; Route with authorization header
(restas:define-route foo/auth ("foo")
(:requirement #'(lambda ()
(hunchentoot:header-in* :authorization)))
(setf (hunchentoot:content-type*) "text/plain")
"foo/auth")
;;; Works as expected
(nth-value 0 (drakma:http-request "
http://localhost:8080/foo" :basic-authorization '("foo" "bar")))
;;; Now lets redefine the last route and add a decorator to it
(restas:define-route foo/auth ("foo")
(:requirement #'(lambda () (hunchentoot:header-in* :authorization)))
(:decorators #'http-auth-require)
(setf (hunchentoot:content-type*) "text/plain")
"foo/auth")
;;; Does not find this route (i.e. route selected is 'foo)
(nth-value 0 (drakma:http-request "
http://localhost:8080/foo" :basic-authorization '("foo" "bar")))
;;; It looks like the :requirement is not considered anymore