Decorators and requirements mutually exclusive?

57 views
Skip to first unread message

Frank

unread,
Apr 7, 2013, 3:00:27 PM4/7/13
to res...@googlegroups.com
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

Andrey Moskvitin

unread,
Apr 7, 2013, 4:00:15 PM4/7/13
to res...@googlegroups.com
> Are decorators and requirements mutually exclusive?

No, the problem lies elsewhere. RESTAS not guaranteed order of
checking routes. If you want to use multiple routes with the same URL,
you must specify the requirements for each such route.

Instead:

(restas:define-route foo ("foo")
  (setf (hunchentoot:content-type*) "text/plain")
         "foo")

Use:

(restas:define-route foo ("foo")
  (:requirement (lambda ()
                       (not (hunchentoot:header-in* :authorization))))
  (setf (hunchentoot:content-type*) "text/plain")
         "foo")

Andrey

2013/4/7 Frank <frank....@gmail.com>


--
You received this message because you are subscribed to the Google Groups "restas" group.
To unsubscribe from this group and stop receiving emails from it, send an email to restas+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Reply all
Reply to author
Forward
0 new messages