[hunchentoot-devel] Middleware with Hunchentoot
Robert Uhl
eadmund42 at gmail.com
Fri Jul 20 15:24:22 UTC 2007
"Mac Chan" <emailmac at gmail.com> writes:
>
>> (create-regex-dispatcher "/foo/bar?baz" (null-effect #'my-handler))
>
> Sorry but your null-effect example doesn't really show the benefit of
> using this middleware wrapper. I can't really tell why I'd want to do
> something like this.
Here's a more realistic example:
(def-middleware authentication (request)
(if (apply #'authenticatedp (multiple-value-list (authorization)))
(call-next-middleware)
(require-authentication)))
Then the user can force a page to use authentication with:
(create-regex-dispatcher "/foo/bar" (authentication #'my-handler))
Instead of having to write any code inside MY-HANDLER.
I've not fully fleshed out the idea yet, of course.
Ideally, it'd be possible to specify a single stack of middleware to use
on the _entire_ Hunchentoot server, but I've not yet figured out where
to do that.
>> Obviously middleware could be chained:
>>
>> (create-regex-dispatcher "/foo/bar?baz"
>> (authentication (caching #'my-handler)))
>
> I'm really confused here. I assume that both authentication and
> caching are macros, right?
Nope, just functions created by DEF-MIDDLEWARE. Something like:
(defun authentication (handler-or-middleware)
(lambda (request)
(if (apply #'authenticatedp (multiple-value-list (authorization)))
(when (handler-or-middleware)
(funcall handler-or-middleware request))
(require-authentication))))
That is, they're just functions which create handler wrappers.
> If they are functions, then what do they do? what does the middleware
> framework do? and what all these buy us?
>
> If they are macros, then why not just define them straightforwardly?
>
> (defmacro with-authentication (&body body)
> `(progn
> (require-authorization)
> , at body))
Because having to write:
(defun display-foo-page (request)
(with-authentication
(with-caching
(with-etags
(with-gzip
(do-stuff))))))
Gets unwieldy.
But on reflection you're right: handler-specific code is probably best
expressed as a WITH- macro. Normally one would probably be doing
something like:
(defun display-foo-page (request)
(with-authorisation (maintainer editor)
(do-stuff)))
Without more than a single macro. The other stuff I was thinking of
doing (caching, URL cleaning, gzipping) should really be run around
_all_ handlers, not just a few. I don't think Hunchentoot exposes a
good place for this kind of thing. URL cleaning is easy enough: put it
at the beginning of *dispatch-table* where it'll get called early on and
can rewrite (request-uri). But where would one put gzipping? It has to
do its magic _after_ any handler runs, and process the handler's output.
It'd be nicest to specify it once, and not in every single handler's
code.
--
Robert Uhl <http://public.xdi.org/=ruhl>
I used to think that the brain was the most wonderful organ in my
body. Then I realised who was telling me this. --Emo Phillips
More information about the Tbnl-devel
mailing list