From edi at agharta.de Sun Jul 1 16:16:37 2007 From: edi at agharta.de (Edi Weitz) Date: Sun, 01 Jul 2007 18:16:37 +0200 Subject: [hunchentoot-devel] port to sbcl win32: timouts are not implemented In-Reply-To: (Anton Vodonosov's message of "Sun, 01 Jul 2007 02:32:06 +0400") References: Message-ID: On Sun, 01 Jul 2007 02:32:06 +0400, Anton Vodonosov wrote: > I've just tried hunchentoot on sbcl win32. When you first time start > hunchentoot, lisp enters debugger with message "undefined function > sb-unix:create-timer" or something in that fashion. Looks like > timeouts are not implemented in sbcl win32 so I've changed > with-timeout macro in the port-sbcl.lisp to just execute its body > without timeout. It helps. Thanks for the info. I wonder why this hasn't been an issue for the other SBCL/Win32 users so far, though. Anyway, I'd rather see a more unobtrusive patch which automagically starts to work once timeouts are implemented. Something along the lines of http://www.cl-user.net/asp/web-sites/features Cheers, Edi. From vodonosov at mail.ru Tue Jul 3 01:13:32 2007 From: vodonosov at mail.ru (Anton Vodonosov) Date: Tue, 03 Jul 2007 05:13:32 +0400 Subject: =?koi8-r?Q?Re[2]=3A_[hunchentoot-devel]_port_to_sbcl_win32=3A_timouts_are_notimplemented?= In-Reply-To: References: Message-ID: Edi Weitz: > I wonder why this hasn't been an issue for the > other SBCL/Win32 users so far, though. I'm using sbcl 1.0.6 win32 binary downloaded from sbcl site. The error UNDEFINED-FUNCTION: SB-UNIX:UNIX-SETITIMER is signaled only when you start hunchentoot first time (i.e. when you invoke sb-ext:with-timeout first time). You may just press 'q' in the slime debugger and start hunchentoot again. But the function is definitely not works for win32, I even checkd sbcl sources. BTW, in the patch suggested here http://common-lisp.net/pipermail/tbnl-devel/2006-November/000815.html Luís Oliveira also removes sb-ext:with-timeout (he redefines force-output* - the only place where with-timout is used) > Anyway, I'd rather see a more unobtrusive patch which automagically > starts to work once timeouts are implemented. Something along the > lines of > > http://www.cl-user.net/asp/web-sites/features Thank you for the link. What do you think about the following mega-solution: ;; determine whether SB-EXT:WITH-TIMEOUT function is supported; ;; we can't just check (FBOUNDP 'SB-EXT:WITH-TIMEOUT) ;; because, for example in sbcl 1.0.6 for win32, the function ;; is present, but doesn't work (it signals UNDEFINED-FUNCTION: ;; SB-UNIX:UNIX-SETITIMER) (eval-when (:compile-toplevel :load-toplevel :execute) (defun ensured-sleep-millis (milliseconds) "Sleeps (in fact loops) not less then MILLISECONDS number of milliseconds; the minimal sleep time is one internal time unit. Don't use this function for large time values, because it may take up much processor power." (do ((start-time (get-internal-real-time))) ((< (+ start-time (ceiling (* internal-time-units-per-second (/ milliseconds 1000)))) (get-internal-real-time))))) (handler-case (sb-ext:with-timeout 0.0000001 (ensured-sleep-millis 5)) (sb-ext:timeout () (pushnew :hunchentoot-sbcl-with-timeout *features*)) (t ()))) (defmacro with-timeout ((seconds &body timeout-forms) &body body) "Executes the code BODY and returns the results of the last form but stops execution after SECONDS seconds and then instead executes the code in TIMEOUT-FORMS." #-:hunchentoot-sbcl-with-timeout `(progn , at body) #+:hunchentoot-sbcl-with-timeout `(cl:handler-case (sb-ext:with-timeout ,seconds , at body) (sb-ext:timeout () , at timeout-forms))) In the paper it is suggested to insert symbols from library's package but not keywoards into *features*, but I follow the way already used in port-sbcl (see :hunchentoot-sbcl-debug-print-variable-alist). I've tried this code on sbcl win32 and on linux. It works as expected. Best regards, -Anton From emailmac at gmail.com Mon Jul 9 04:42:06 2007 From: emailmac at gmail.com (Mac Chan) Date: Sun, 8 Jul 2007 21:42:06 -0700 Subject: [hunchentoot-devel] https server - no shared cipher error Message-ID: <4877ae640707082142t52abe797v8a2f95841440a754@mail.gmail.com> Hi, Have anyone successfully started a https server with the latest hunchentoot? For some reason I'm getting a "no shared cipher" error. I hoped that I'm not making stupid mistake with the ssl setup. # To generate a key $ openssl genrsa 1024 > server.key # To generate a Certificate Signing Request $openssl req -new -key server.key > server.csr # self-sign cert $openssl req -x509 -key server.key -in server.csr > server.crt (asdf:oos 'asdf:load-op :hunchentoot-test) (hunchentoot:start-server :port 4443 :ssl-certificate-file "server.crt") (setq hunchentoot:*catch-errors-p* nil) When I point firefox to https://localhost:4443/, a error dialog pops up: `Firefox and localhost cannot communicate securely because they have no common encryption algorithms.' I'm using lispworks 5.0.2 32-bit pro. This happens in both fedora core 6 and winxp. I used the precompiled ssl package found here : http://www.slproweb.com/download/Win32OpenSSL-0_9_8e.exe Here's the backtrace: SSL failure in #: error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher [Condition of type COMM:SSL-FAILURE] Restarts: 0: [ABORT] Quit process. Backtrace: 0: SIGNAL (# &REST NIL) 1: CONDITIONS::CONDITIONS-ERROR (:INVISIBLEP T COMM:SSL-FAILURE (:STREAM #1=# :FORMAT-STRING "SSL failure in ~s: ~a" :FORMAT-ARGUMENTS (#1# "error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher"))) 2: COMM::SSL-READ-OR-WRITE-BUFFER (# T "ULT-DISPATCHERB at HC9 3: (METHOD STREAM:STREAM-FILL-BUFFER (STREAM:BUFFERED-STREAM)) (#) 4: (METHOD STREAM:STREAM-READ-CHAR (STREAM:BUFFERED-STREAM)) (#) 5: (METHOD STREAM:STREAM-READ-BYTE (COMM:SOCKET-STREAM)) (#) 6: READ-BYTE (# &OPTIONAL "<(EOF-ERROR-P T)>" :EOF) 7: READ-BYTE (# &OPTIONAL "<(EOF-ERROR-P T)>" NIL) 8: (METHOD FLEXI-STREAMS::READ-BYTE* (FLEXI-STREAMS::FLEXI-BINARY-INPUT-STREAM)) (#) 9: (METHOD STREAM:STREAM-READ-CHAR (FLEXI-STREAMS::FLEXI-LATIN-1-INPUT-STREAM)) (#) 10: READ-CHAR (&OPTIONAL "<(STREAM *STANDARD-INPUT*)>" "<(EOF-ERROR-P T)>" NIL :DONT-KNOW) 11: CHUNGA:READ-LINE* (# &OPTIONAL NIL) 12: HUNCHENTOOT::GET-REQUEST-DATA NIL 13: HUNCHENTOOT::PROCESS-CONNECTION (# 420) 14: (SUBFUNCTION MP::PROCESS-SG-FUNCTION MP::INITIALIZE-PROCESS-STACK) (:DONT-KNOW) 15: SYSTEM::%%FIRST-CALL-TO-STACK NIL Regards, -- Mac From austin at pettomato.com Mon Jul 9 15:06:40 2007 From: austin at pettomato.com (Austin Haas) Date: Mon, 9 Jul 2007 11:06:40 -0400 Subject: [hunchentoot-devel] Hunchentoot standalone with and without ssl Message-ID: <20070709150640.GA2292@bean.chicago> If I am running Hunchentoot standalone with ssl, should it be able to handle requests that are NOT using ssl as well? Currently, I am getting the following error if I send a request to "http" and not "https": [2007-07-09 10:56:45 [ERROR]] Error while processing connection: A failure in the SSL library occurred on handle #.(SB-SYS:INT-SAP #X080EE6E0). (Return code: 1)SSL error queue: error:1407609C:SSL routines:SSL23_GET_CLIENT_HELLO:http request Do people normally start two servers, one w/ ssl and one w/o, if they want to be able to handle both types of requests? The requests would be to different resources, obviously. -austin -- Austin Haas Pet Tomato, Inc. http://pettomato.com From rm at seid-online.de Mon Jul 9 15:17:43 2007 From: rm at seid-online.de (Ralf Mattes) Date: Mon, 09 Jul 2007 17:17:43 +0200 Subject: [hunchentoot-devel] Hunchentoot standalone with and without ssl In-Reply-To: <20070709150640.GA2292@bean.chicago> References: <20070709150640.GA2292@bean.chicago> Message-ID: <1183994263.13799.1.camel@localhost.localdomain> On Mon, 2007-07-09 at 11:06 -0400, Austin Haas wrote: > If I am running Hunchentoot standalone with ssl, should it be able to handle requests that are NOT using ssl as well? Currently, I am getting the following error if I send a request to "http" and not "https": Just to get things clear: are you trying to do this on _one_ port (i.e. non-SSL connects on the same port as SSL)? Cheers, RalfD From austin at pettomato.com Mon Jul 9 17:16:11 2007 From: austin at pettomato.com (Austin Haas) Date: Mon, 9 Jul 2007 13:16:11 -0400 Subject: [hunchentoot-devel] Hunchentoot standalone with and without ssl In-Reply-To: <1183994263.13799.1.camel@localhost.localdomain> References: <20070709150640.GA2292@bean.chicago> <1183994263.13799.1.camel@localhost.localdomain> Message-ID: <20070709171611.GA3113@bean.chicago> Yes, one port. Maybe that is where my own internal logic is breaking down. I was thinking about one instance of Apache handling both ssl and non-ssl connections, though it uses separate ports. -austin -- Austin Haas Pet Tomato, Inc. http://pettomato.com On Mon Jul 09 17:17 , Ralf Mattes wrote: > On Mon, 2007-07-09 at 11:06 -0400, Austin Haas wrote: > > If I am running Hunchentoot standalone with ssl, should it be able to handle requests that are NOT using ssl as well? Currently, I am getting the following error if I send a request to "http" and not "https": > > Just to get things clear: are you trying to do this on _one_ port (i.e. > non-SSL connects on the same port as SSL)? > > Cheers, RalfD > > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel > From nowhere.man at levallois.eu.org Mon Jul 9 17:29:57 2007 From: nowhere.man at levallois.eu.org (Pierre THIERRY) Date: Mon, 9 Jul 2007 19:29:57 +0200 Subject: [hunchentoot-devel] Hunchentoot standalone with and without ssl In-Reply-To: <20070709171611.GA3113@bean.chicago> References: <20070709150640.GA2292@bean.chicago> <1183994263.13799.1.camel@localhost.localdomain> <20070709171611.GA3113@bean.chicago> Message-ID: <20070709172957.GE31026@bateleur.arcanes.fr.eu.org> Scribit Austin Haas dies 09/07/2007 hora 13:16: > Yes, one port. Maybe that is where my own internal logic is breaking > down. Well, I don't know about earlier versions of SSL, and which ones Hunchentoot handles, but TLS has a START-TLS command that enables the use of the same port for clear and encrypted communications. Duplication of ports for secure channels would be a nightmare if it was generalized. Quickly, Pierre -- nowhere.man at levallois.eu.org OpenPGP 0xD9D50D8A -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 189 bytes Desc: Digital signature URL: From emailmac at gmail.com Mon Jul 9 18:52:48 2007 From: emailmac at gmail.com (Mac Chan) Date: Mon, 9 Jul 2007 11:52:48 -0700 Subject: [hunchentoot-devel] Re: https server - no shared cipher error In-Reply-To: <4877ae640707082142t52abe797v8a2f95841440a754@mail.gmail.com> References: <4877ae640707082142t52abe797v8a2f95841440a754@mail.gmail.com> Message-ID: <4877ae640707091152r3cc86cfbp827a8857cebac3f5@mail.gmail.com> So it turns out that it was indeed a stupid mistake :( I forgot to supply the :ssl-privatekey-file keyword argument. SBCL (using CL+SSL) gives much more descriptive error message and that's how I track down the problem. Sorry for the false alarm ! Regards, -- Mac On 7/8/07, Mac Chan wrote: > Hi, > > Have anyone successfully started a https server with the latest hunchentoot? > > For some reason I'm getting a "no shared cipher" error. I hoped that > I'm not making stupid mistake with the ssl setup. > > # To generate a key > $ openssl genrsa 1024 > server.key > > # To generate a Certificate Signing Request > $openssl req -new -key server.key > server.csr > > # self-sign cert > $openssl req -x509 -key server.key -in server.csr > server.crt > > > (asdf:oos 'asdf:load-op :hunchentoot-test) > > (hunchentoot:start-server :port 4443 :ssl-certificate-file "server.crt") > > (setq hunchentoot:*catch-errors-p* nil) > > When I point firefox to https://localhost:4443/, a error dialog pops up: > > `Firefox and localhost cannot communicate securely because they have > no common encryption algorithms.' From rm at seid-online.de Tue Jul 10 10:20:35 2007 From: rm at seid-online.de (Ralf Mattes) Date: Tue, 10 Jul 2007 12:20:35 +0200 Subject: [hunchentoot-devel] Re: https server - no shared cipher error In-Reply-To: <4877ae640707091152r3cc86cfbp827a8857cebac3f5@mail.gmail.com> References: <4877ae640707082142t52abe797v8a2f95841440a754@mail.gmail.com> <4877ae640707091152r3cc86cfbp827a8857cebac3f5@mail.gmail.com> Message-ID: <1184062835.6239.1.camel@localhost.localdomain> On Mon, 2007-07-09 at 11:52 -0700, Mac Chan wrote: > So it turns out that it was indeed a stupid mistake :( > > I forgot to supply the :ssl-privatekey-file keyword argument. > > SBCL (using CL+SSL) gives much more descriptive error message and > that's how I track down the problem. Hey, we should save this message for all these people that complain about SBCL's over-verboseness ... ;-) BTW - oversight isn't stupidity. Cheers, RalfD From edi at agharta.de Thu Jul 12 19:18:31 2007 From: edi at agharta.de (Edi Weitz) Date: Thu, 12 Jul 2007 21:18:31 +0200 Subject: [hunchentoot-devel] Hunchentoot standalone with and without ssl In-Reply-To: <20070709171611.GA3113@bean.chicago> (Austin Haas's message of "Mon, 9 Jul 2007 13:16:11 -0400") References: <20070709150640.GA2292@bean.chicago> <1183994263.13799.1.camel@localhost.localdomain> <20070709171611.GA3113@bean.chicago> Message-ID: On Mon, 9 Jul 2007 13:16:11 -0400, Austin Haas wrote: > Yes, one port. Maybe that is where my own internal logic is breaking > down. I was thinking about one instance of Apache handling both ssl > and non-ssl connections, though it uses separate ports. You'll have to start two different Hunchentoot servers (one for each port, one SSL and one not) then. As a result, you'll have one Lisp image handling all connections which is very similar to the Apache setup. Edi. From vodonosov at mail.ru Sat Jul 14 00:34:05 2007 From: vodonosov at mail.ru (Anton Vodonosov) Date: Sat, 14 Jul 2007 04:34:05 +0400 Subject: =?koi8-r?Q?Re[3]=3A_[hunchentoot-devel]_port_to_sbcl_win32=3A_timouts_are_notimplemented?= In-Reply-To: References: Message-ID: It's strange. Today I've tried to load hunchentoot via asdf and the code I've sent in previous message don't work. I fixed it a little and now it's possible to load hunchentoot using asdf and sbcl win32: ;; Determine whether sb-ext:with-timeout is supported; ;; we can't just check (FIND-SYMBOL "WITH-TIMEOUT" "SB-EXT") ;; because, for example in sbcl 1.0.6 for win32, the function ;; is present, but doesn't work (it signals UNDEFINED-FUNCTION: ;; SB-UNIX:UNIX-SETITIMER) (eval-when (:compile-toplevel :load-toplevel :execute) (defun ensured-sleep-millis (milliseconds) "Sleeps (in fact loops) not less then MILLISECONDS number of milliseconds; the minimal sleep time is one internal time unit. Don't use this function for large time values, because it eats processor power." (do ((start-time (get-internal-real-time))) ((< (+ start-time (ceiling (* internal-time-units-per-second (/ milliseconds 1000)))) (get-internal-real-time))))) (cl:handler-case (sb-ext:with-timeout 0.0000001 (ensured-sleep-millis 5)) (sb-ext:timeout () (pushnew :hunchentoot-sbcl-with-timeout *features*)) (cl:t ()))) (defmacro with-timeout ((seconds &body timeout-forms) &body body) "Executes the code BODY and returns the results of the last form but stops execution after SECONDS seconds and then instead executes the code in TIMEOUT-FORMS." (declare (ignorable seconds timeout-forms body)) #-:hunchentoot-sbcl-with-timeout `(cl:progn , at body) #+:hunchentoot-sbcl-with-timeout `(cl:handler-case (sb-ext:with-timeout ,seconds , at body) (sb-ext:timeout () , at timeout-forms))) BTW, in the top of port-sbcl.lisp there is #-:sb-thread (eval-when (:compile-toplevel :load-toplevel :execute) (warn "Without thread support, this library is only useful for development.")) It's quite annoying because compilation with asdf fails on this (today; strange again I don't remember that it happened before) Regards, -Anton From ch-tbnl at bobobeach.com Wed Jul 18 19:51:51 2007 From: ch-tbnl at bobobeach.com (Cyrus Harmon) Date: Wed, 18 Jul 2007 12:51:51 -0700 Subject: [hunchentoot-devel] host/port question In-Reply-To: <7B32045B-D6FB-4E27-A245-82A75A8E797A@bobobeach.com> References: <7B32045B-D6FB-4E27-A245-82A75A8E797A@bobobeach.com> Message-ID: Unfortunately, this leaves things in an unnice way when one wants to change the port but the original request came in on a nonstandard port. In this case we end up redirecting to, e.g., https://foo.com: 4242:4243/the_url , which is no good. It's easy enough to pass in a host, but perhaps we should strip off the port from the host if a host is explicitly provided? Thanks, Cyrus On Apr 28, 2007, at 2:47 PM, Cyrus Harmon wrote: > I'm not sure what "the right thing" here is, but it struck me as > odd that redirect didn't include a port argument, so I made the > following changes to redirect: > > --- hunchentoot-0.9.0/misc.lisp 2007-03-30 14:01:27.000000000 -0700 > +++ ../hunchentoot-0.9.0/misc.lisp 2007-04-27 > 22:45:00.000000000 -0700 > @@ -229,6 +229,7 @@ > (add-session-id (not (or host-provided-p > (starts-with- > scheme-p target) > (cookie-in > *session-cookie-name*)))) > + port > permanently) > "Redirects the browser to TARGET which should be a string. > If TARGET is a full URL starting with a scheme, HOST and PROTOCOL > @@ -240,11 +241,11 @@ > otherwise a 302." > (let ((url (if (starts-with-scheme-p target) > target > - (format nil "~A://~A~A" > + (format nil "~A://~A~@[:~A~]~A" > (ecase protocol > ((:http) "http") > ((:https) "https")) > - host target)))) > + host port target)))) > (when add-session-id > (setq url (add-cookie-value-to-url url :replace-ampersands-p > nil))) > (setf (header-out :location) > > > but then I realized that what we call "host" here really is > host:port. Should these two notions be more "decoupled" or should I > just think host:port when I see host? > > Thanks, > > Cyrus > > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel From edi at agharta.de Wed Jul 18 20:16:28 2007 From: edi at agharta.de (Edi Weitz) Date: Wed, 18 Jul 2007 22:16:28 +0200 Subject: [hunchentoot-devel] host/port question In-Reply-To: (Cyrus Harmon's message of "Wed, 18 Jul 2007 12:51:51 -0700") References: <7B32045B-D6FB-4E27-A245-82A75A8E797A@bobobeach.com> Message-ID: On Wed, 18 Jul 2007 12:51:51 -0700, Cyrus Harmon wrote: > but perhaps we should strip off the port from the host if a host is > explicitly provided? You mean if a port is provided? Yes, sounds reasonable. From ch-tbnl at bobobeach.com Wed Jul 18 20:24:00 2007 From: ch-tbnl at bobobeach.com (Cyrus Harmon) Date: Wed, 18 Jul 2007 13:24:00 -0700 Subject: [hunchentoot-devel] host/port question In-Reply-To: References: <7B32045B-D6FB-4E27-A245-82A75A8E797A@bobobeach.com> Message-ID: <932B779F-F304-4921-A012-09EE55DCA6DD@bobobeach.com> Hi Edi, Yes, that was what I meant to say. Thanks, Cyrus On Jul 18, 2007, at 1:16 PM, Edi Weitz wrote: > On Wed, 18 Jul 2007 12:51:51 -0700, Cyrus Harmon tbnl at bobobeach.com> wrote: > >> but perhaps we should strip off the port from the host if a host is >> explicitly provided? > > You mean if a port is provided? Yes, sounds reasonable. > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel From eadmund42 at gmail.com Fri Jul 20 04:11:58 2007 From: eadmund42 at gmail.com (Robert Uhl) Date: Thu, 19 Jul 2007 22:11:58 -0600 Subject: [hunchentoot-devel] Middleware with Hunchentoot Message-ID: >From Python's WSGI I've gotten the idea of middleware--that is, stuff which runs around user-defined code in some user-defined order. A null-effect middleware function might be defined like this: (defun null-effect (request next) (when next (funcall next request))) One can see how a middleware function could set things up for the user-defined handler, could decide whether or not to call the user's handler and could override whatever that handler returns. A convenience macro def-middleware might make it possible to write the null-effect function like this: (def-middleware null-effect (request) (call-next-middleware)) And the user might be able to create a dispatcher thus: (create-regex-dispatcher "/foo/bar?baz" (null-effect #'my-handler)) Obviously middleware could be chained: (create-regex-dispatcher "/foo/bar?baz" (authentication (caching #'my-handler))) Question: does this seem like a reasonable way to handle middleware, particularly authentication/authorisation mechanisms? I'm fairly new to Lisp, but it _seems_ like it's a fairly Lispy way to go about things. Thoughts? -- Robert Uhl England really needs France around to provide comic relief. --Matt McLeod in comp.sys.mac.games.strategic From emailmac at gmail.com Fri Jul 20 06:25:19 2007 From: emailmac at gmail.com (Mac Chan) Date: Thu, 19 Jul 2007 23:25:19 -0700 Subject: [hunchentoot-devel] Middleware with Hunchentoot In-Reply-To: References: Message-ID: <4877ae640707192325v27d74ab5m7140f8c995a6fba2@mail.gmail.com> On 7/19/07, Robert Uhl wrote: > >From Python's WSGI I've gotten the idea of middleware--that is, stuff > which runs around user-defined code in some user-defined order. A > null-effect middleware function might be defined like this: No offense but I find it amusing that people using other languages always need to invent new design pattern `terms' to describe something that is just common sense. Just earlier in c.l.l I learned something new called "front controller" and spent 10 minutes reading a website with fancy graphs that describes what a "front controller" is. That turned out to be a big waste of time because it is nothing new (and of course hunchentoot already have it built in). > One can see how a middleware function could set things up for the > user-defined handler, could decide whether or not to call the user's > handler and could override whatever that handler returns. > > A convenience macro def-middleware might make it possible to write the > null-effect function like this: > > (def-middleware null-effect (request) > (call-next-middleware)) > > And the user might be able to create a dispatcher thus: > > (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. > 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? 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)) > Question: does this seem like a reasonable way to handle middleware, > particularly authentication/authorisation mechanisms? I'm fairly new to > Lisp, but it _seems_ like it's a fairly Lispy way to go about things. Assuming that you've already gone through the extensive documentation, I think your not understanding the Hunchentoot code might be the problem. It actually already does 90% of the work for you. Hunchentoot is very well written and easy to read. If you are using slime, just open the test.lisp and go through the example.lisp. Whenever you see some functions / macros that might look non-trival to you, press Meta-. to jump to the source and see how it's implemented. For instance (defun authorization-page () (multiple-value-bind (user password) (authorization) (cond ((and (equal user "nanook") (equal password "igloo")) (with-html (:html (:head (:title "Hunchentoot page with Basic Authentication")) (:body (:h2 (hunchentoot-link) " page with Basic Authentication") (info-table (header-in "Authorization") (authorization)))))) (t (require-authorization))))) what does (require-authorization) do ? (defun require-authorization (&optional (realm "Hunchentoot")) "Sends back appropriate headers to require basic HTTP authentication (see RFC 2617) for the realm REALM." (setf (header-out "WWW-Authenticate") (format nil "Basic realm=\"~A\"" (quote-string realm)) (return-code *reply*) +http-authorization-required+) (throw 'handler-done nil)) So it seems like that it will (throw 'handler-done nil) when authorization fails >From http://weitz.de/hunchentoot/#handler-done "This is a catch tag which names a catch which is active during the lifetime of a handler. The handler can at any time throw the outgoing content body (or NIL) to this catch to immediately abort handling the request. See the source code of REDIRECT for an example." With this knowledge you can see that to password protect a page you can just simply insert a call to require-authorization at the begining of your function body. No design pattern required. (define-easy-handler (my-url-handler :uri "/my-url") () (require-authorization) (with-html (:h1 "hi")) Similarly you can define your session checking routine the same way. (defun ensure-login () (unless (session-value :user) (redirect "/login"))) (define-easy-handler (my-url-handler :uri "/my-url") () (ensure-login) (with-html (:h1 "hi")) The caching functionality would probably require a macro that wrap around define-easy-handler. Using the uri as a key to a hashtable, you can first check if it is already generated (assuming your html page generation is time consuming and complicated) and return right away. It could be a good exercise to try your hands on. BTW, before Edi introduced define-easy-handler in hunchentoot, I used to have my own version of allegro's "Extended Maps" running on tbnl. http://opensource.franz.com/aserve/aserve-dist/webactions/doc/webactions.html#Webactions It is very similar to what you tried to describe above, and very easy to work with. However, let me tell you a little secret - define-easy-handler is probably all you ever need :-) Anyway, happy hacking! Regards, -- Mac From emailmac at gmail.com Fri Jul 20 06:34:23 2007 From: emailmac at gmail.com (Mac Chan) Date: Thu, 19 Jul 2007 23:34:23 -0700 Subject: [hunchentoot-devel] Middleware with Hunchentoot In-Reply-To: <4877ae640707192325v27d74ab5m7140f8c995a6fba2@mail.gmail.com> References: <4877ae640707192325v27d74ab5m7140f8c995a6fba2@mail.gmail.com> Message-ID: <4877ae640707192334y10adc18dn4246a85396d292ac@mail.gmail.com> > (defmacro with-authentication (&body body) > `(progn > (require-authorization) > , at body)) Ah, I forget to reread my email before I click send. It should be something like this: (defun do-authorization () (multiple-value-bind (user password) (authorization) (unless (and (equal user "nanook") (equal password "igloo")) (require-authorization)))) (defmacro with-authentication (&body body) `(progn (do-authorization) , at body)) > (define-easy-handler (my-url-handler :uri "/my-url") () > (require-authorization) > (with-html (:h1 "hi")) Similarly the above is wrong. (define-easy-handler (my-url-handler :uri "/my-url") () (do-authorization) (with-html (:h1 "hi")) BTW none of the code are tested, but you get the idea ... Regards, -- Mac From vagif at cox.net Fri Jul 20 07:29:25 2007 From: vagif at cox.net (Vagif Verdi) Date: Fri, 20 Jul 2007 00:29:25 -0700 Subject: [hunchentoot-devel] Middleware with Hunchentoot In-Reply-To: <4877ae640707192334y10adc18dn4246a85396d292ac@mail.gmail.com> Message-ID: <20070720072929.IMLB1393.fed1rmmtao106.cox.net@fed1rmimpo01.cox.net> Why that fancy, complicated and unessesary machinery ? I do authentication much simpler with hunchentoot dispatch. Remember, dispatch can pass request further, if it returns nil. (setq *dispatch-table* (nconc (mapcar (lambda (x) (create-folder-dispatcher-and-handler (conc "/" x) (conc *app-path* "www/" x))) '("js/" "css/" "images/" "swf/")) (prefix-dispatchers '(("/app" login-swf) ("/login.json" login-json))) (list #'check-if-logged-in) (list 'dispatch-easy-handlers #'default-dispatcher))) So first you list open resources that do not need authentication. Then goes your function that checks authentication: (check-if-logged-in), and then all other pages that require authentication. -----Original Message----- From: tbnl-devel-bounces at common-lisp.net [mailto:tbnl-devel-bounces at common-lisp.net] On Behalf Of Mac Chan Sent: Thursday, July 19, 2007 11:34 PM To: General interest list for Hunchentoot and CL-WEBDAV Subject: Re: [hunchentoot-devel] Middleware with Hunchentoot > (defmacro with-authentication (&body body) > `(progn > (require-authorization) > , at body)) Ah, I forget to reread my email before I click send. It should be something like this: (defun do-authorization () (multiple-value-bind (user password) (authorization) (unless (and (equal user "nanook") (equal password "igloo")) (require-authorization)))) (defmacro with-authentication (&body body) `(progn (do-authorization) , at body)) > (define-easy-handler (my-url-handler :uri "/my-url") () > (require-authorization) > (with-html (:h1 "hi")) Similarly the above is wrong. (define-easy-handler (my-url-handler :uri "/my-url") () (do-authorization) (with-html (:h1 "hi")) BTW none of the code are tested, but you get the idea ... Regards, -- Mac _______________________________________________ tbnl-devel site list tbnl-devel at common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel From ctdean at sokitomi.com Fri Jul 20 08:57:11 2007 From: ctdean at sokitomi.com (Chris Dean) Date: Fri, 20 Jul 2007 01:57:11 -0700 Subject: [hunchentoot-devel] Middleware with Hunchentoot In-Reply-To: (Robert Uhl's message of "Thu, 19 Jul 2007 22:11:58 -0600") References: Message-ID: > Thoughts? Like others have said, this might not be the best example since it is so easy to do this in hunchentoot proper. However, don't be discouraged! I think that there is plenty of interesting work to be done here. For example, a widget based framework that sat on top of of hunchentoot would be useful if done properly. Cheers, Chris Dean From xach at xach.com Fri Jul 20 10:19:53 2007 From: xach at xach.com (Zach Beane) Date: Fri, 20 Jul 2007 06:19:53 -0400 Subject: [hunchentoot-devel] Middleware with Hunchentoot In-Reply-To: References: Message-ID: <20070720101953.GF30050@xach.com> On Thu, Jul 19, 2007 at 10:11:58PM -0600, Robert Uhl wrote: > >From Python's WSGI I've gotten the idea of middleware--that is, stuff > which runs around user-defined code in some user-defined order. A > null-effect middleware function might be defined like this: > > (defun null-effect (request next) > (when next > (funcall next request))) > > One can see how a middleware function could set things up for the > user-defined handler, could decide whether or not to call the user's > handler and could override whatever that handler returns. > > A convenience macro def-middleware might make it possible to write the > null-effect function like this: > > (def-middleware null-effect (request) > (call-next-middleware)) > > And the user might be able to create a dispatcher thus: > > (create-regex-dispatcher "/foo/bar?baz" (null-effect #'my-handler)) > > Obviously middleware could be chained: > > (create-regex-dispatcher "/foo/bar?baz" > (authentication (caching #'my-handler))) > > Question: does this seem like a reasonable way to handle middleware, > particularly authentication/authorisation mechanisms? I'm fairly new to > Lisp, but it _seems_ like it's a fairly Lispy way to go about things. > > Thoughts? These are called "closures". Here's a function I use in several places: (defun call-with-protection (&key username password realm function) "Return a closure that calls FUNCTION if the remote username and password match USERNAME and PASSWORD, or returns an authorization required response otherwise." (lambda () (multiple-value-bind (web-username web-password) (authorization) (if (and web-username web-password (string= web-username username) (string= web-password password)) (funcall function) (require-authorization realm))))) Here's an example use; (wf:serve-function (wf:call-with-protection :username "blubba" :password "frink" :realm "roflbot" :function 'recent-page) "/roflbot/recent") The FUNCTION argument to CALL-WITH-PROTECTION could be another closure generator, and these could be chained as much or as little as you like. Zach From eadmund42 at gmail.com Fri Jul 20 15:24:22 2007 From: eadmund42 at gmail.com (Robert Uhl) Date: Fri, 20 Jul 2007 09:24:22 -0600 Subject: [hunchentoot-devel] Middleware with Hunchentoot References: <4877ae640707192325v27d74ab5m7140f8c995a6fba2@mail.gmail.com> Message-ID: "Mac Chan" 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 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 From edi at agharta.de Fri Jul 20 15:38:34 2007 From: edi at agharta.de (Edi Weitz) Date: Fri, 20 Jul 2007 17:38:34 +0200 Subject: [hunchentoot-devel] Middleware with Hunchentoot In-Reply-To: (Robert Uhl's message of "Fri, 20 Jul 2007 09:24:22 -0600") References: <4877ae640707192325v27d74ab5m7140f8c995a6fba2@mail.gmail.com> Message-ID: On Fri, 20 Jul 2007 09:24:22 -0600, Robert Uhl wrote: > 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. http://weitz.de/hunchentoot/#dispatch-request From emailmac at gmail.com Fri Jul 20 17:51:12 2007 From: emailmac at gmail.com (Mac Chan) Date: Fri, 20 Jul 2007 10:51:12 -0700 Subject: [hunchentoot-devel] Middleware with Hunchentoot In-Reply-To: References: <4877ae640707192325v27d74ab5m7140f8c995a6fba2@mail.gmail.com> Message-ID: <4877ae640707201051m33bcfbedu312d9fc3d9dd2859@mail.gmail.com> On 7/20/07, Robert Uhl wrote: > 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. If that's what you want (not having to write any code inside handlers), and if all your handlers that require the same checking share a common uri prefix (like everything under "/admin/..." will require login, then you can probably just use Vagif's suggestion. In my case I have no more than 20 define-easy-handlers so it was very easy to manage by just adding a simple function call when needed (and they don't need to share a common uri prefix). > 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))) > (defun display-foo-page (request) > (with-authentication > (with-caching > (with-etags > (with-gzip > (do-stuff)))))) Exactly. The with-xxx macros are abstraction and you can also use it indirectly. That's the beauty of macro. Once you have a set of these simple building blocks you can easier group them together. Here's what I'd typically do (defmacro with-admin-template (&body body) `(with-authentication (with-caching (with-etags (with-gzip (with-html (:html (:head ...) (:admin-header-html ...) , at body (:admin-footer-html ...)))))))) Notice there is a top level hunchentoot dispatch table, and then define-easy-handler is _another_ level of dispatch table. You can probably build another dispatch table for each uri prefix like you suggested easily. Have you looked at webaction's documentation? Is that what you want? BTW, please excuse my pompous reply earlier. It was early in the morning and I was feeling cranky. Regards, -- Mac From eadmund42 at gmail.com Fri Jul 20 20:41:29 2007 From: eadmund42 at gmail.com (Robert Uhl) Date: Fri, 20 Jul 2007 14:41:29 -0600 Subject: [hunchentoot-devel] Middleware with Hunchentoot References: <4877ae640707192325v27d74ab5m7140f8c995a6fba2@mail.gmail.com> Message-ID: Edi Weitz writes: > >> 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. > > http://weitz.de/hunchentoot/#dispatch-request I imagine the suggested usage is something like this? (defclass my-dispatch-table () ((table :accessor table))) (defmethod dispatch-request ((table my-dispatch-table)) (with-cleverness (dispatch-request (table table)))) Cool! Thanks much. -- Robert Uhl Asking a girl out is like finding sqrt(pi) using roman numerals. --unknown From eadmund42 at gmail.com Fri Jul 20 20:44:22 2007 From: eadmund42 at gmail.com (Robert Uhl) Date: Fri, 20 Jul 2007 14:44:22 -0600 Subject: [hunchentoot-devel] Middleware with Hunchentoot References: <4877ae640707192325v27d74ab5m7140f8c995a6fba2@mail.gmail.com> <4877ae640707201051m33bcfbedu312d9fc3d9dd2859@mail.gmail.com> Message-ID: "Mac Chan" writes: > > Have you looked at webaction's documentation? Is that what you want? Yeah, I used to play around with webactions, but I ended up deciding that it's not quite my cuppa tea. It's pretty cool, but it's way of doing things doesn't quite sync with my own. At work I'm a big Django user, and I'm playing with creating a Django-like framework for Lisp using Hunchentoot as the server. > BTW, please excuse my pompous reply earlier. It was early in the > morning and I was feeling cranky. Oh, no worries. Thanks for the ideas; you helped me rethink things. -- Robert Uhl New! Microsoft Wheel! Now available with three or four corners. Microsoft Wheel Pro is available with five--yes, FIVE--corners! And for those who need the best and latest, Microsoft Wheel Pro 2005 Platinum will be out in July 2019. From edi at agharta.de Fri Jul 20 21:00:42 2007 From: edi at agharta.de (Edi Weitz) Date: Fri, 20 Jul 2007 23:00:42 +0200 Subject: [hunchentoot-devel] Middleware with Hunchentoot In-Reply-To: (Robert Uhl's message of "Fri, 20 Jul 2007 14:41:29 -0600") References: <4877ae640707192325v27d74ab5m7140f8c995a6fba2@mail.gmail.com> Message-ID: On Fri, 20 Jul 2007 14:41:29 -0600, Robert Uhl wrote: > I imagine the suggested usage is something like this? > > (defclass my-dispatch-table () > ((table :accessor table))) > > (defmethod dispatch-request ((table my-dispatch-table)) > (with-cleverness > (dispatch-request (table table)))) Or just write an :AROUND method around the existing one. From ignas.mikalajunas at gmail.com Sat Jul 21 15:16:29 2007 From: ignas.mikalajunas at gmail.com (Ignas Mikalajunas) Date: Sat, 21 Jul 2007 18:16:29 +0300 Subject: [hunchentoot-devel] Middleware with Hunchentoot In-Reply-To: References: Message-ID: On 7/20/07, Robert Uhl wrote: > >From Python's WSGI I've gotten the idea of middleware--that is, stuff > which runs around user-defined code in some user-defined order. A > null-effect middleware function might be defined like this: > > (defun null-effect (request next) > (when next > (funcall next request))) It seems strange to talk about the concept middleware when you have only 1 webframework which will support it. The whole point of WSGI is to make your application capable of using any of the available python webservers, and all such applications and servers being extended in the same way through middleware (code that runs between the server and the application). So you can have Zope3 application with xslt styling middleware + interactive through the web traceback middleware + twisted server. And you can add as much middleware as you want, change the server, or change the framework used to create the application without having to change the code of the other parts. (this is done by defining the way server passes information to the application and making all the servers conform to that way) While something like that would be useful to common-lisp as well (being able to have hunchentoot based application run on araneida) or using AllegroServe as a backend for a UCW application. IMHO the place for changes to the code is inside the hunchentoot, AllegroServe and other web frameworks, rather than in the hunchentoot dispatcher. And if it is only to allow some standartized "plugins" for hunchentoot that can be added to your working application in some easy way, then comparison with WSGI is a bit out of place. Ignas Mikalajunas From yazicivo at ttnet.net.tr Fri Jul 27 20:18:01 2007 From: yazicivo at ttnet.net.tr (Volkan YAZICI) Date: Fri, 27 Jul 2007 23:18:01 +0300 Subject: [hunchentoot-devel] ALIW (A Lisp in Wonderland) Wiki Project Message-ID: <87ejitk3d2.fsf@ttnet.net.tr> Hi all! I've just finished the wiki project[1] that I've been working on for some time. Project uses Hunchentoot as its web server (and lots of other EdiWare, e.g., cl-who, cl-ppcre, flexi-streams...) and I thought channel citizens would want to check it. [1] http://node2.core.gen.tr:8080/ And more important of all, thanks so much to Dr. Edmund Weitz for creating such great tools! Regards. From rkris at kriyative.net Sun Jul 29 04:16:57 2007 From: rkris at kriyative.net (Ram Krishnan) Date: Sat, 28 Jul 2007 21:16:57 -0700 Subject: [hunchentoot-devel] Virtual hosts support using *META-DISPATCHER* Message-ID: <87tzrnu9mu.fsf@kriyative.dyndns.org> Hi all, I'm in the process of migrating a Web app from Portable Allegroserve to Hunchentoot (0.10), and I had a question about implementing virtual hosts by overriding the *META-DISPATCHER* function binding. Here's what I have so far: ---------------- (defvar *vhost-dispatch-table-map* (make-hash-table :test 'string=)) (defun vhost-meta-dispatcher (server) (declare (ignore server)) (or (gethash (hunchentoot:host) *vhost-dispatch-table-map*) *dispatch-table*)) (defun vhost-set-dispatch-table (hosts dispatch-table &key defaultp) (dolist (hostname (pg:mklist hosts)) (setf (gethash hostname *vhost-dispatch-table-map*) dispatch-table)) (when defaultp (setq *dispatch-table* dispatch-table))) (setq hunchentoot:*meta-dispatcher* 'vhost-meta-dispatcher) ---------------- Now, I'm able to return different *DISPATCH-TABLE* bindings based on the hostname, like so: ---------------- (vhost-set-dispatch-table "foo.bar.com" (list (hunchentoot:create-folder-dispatcher-and-handler "/assets/" #p"/var/www/foo.bar.com/assets/"))) (vhost-set-dispatch-table "quux.bar.com" (list (hunchentoot:create-folder-dispatcher-and-handler "/assets/" #p"/var/www/quux.bar.com/assets/"))) ---------------- Are there any problems in subverting the *META-DISPATCHER* binding this way? Is there a better alternative? Thanks. -ram From edi at agharta.de Sun Jul 29 16:43:30 2007 From: edi at agharta.de (Edi Weitz) Date: Sun, 29 Jul 2007 18:43:30 +0200 Subject: [hunchentoot-devel] Virtual hosts support using *META-DISPATCHER* In-Reply-To: <87tzrnu9mu.fsf@kriyative.dyndns.org> (Ram Krishnan's message of "Sat, 28 Jul 2007 21:16:57 -0700") References: <87tzrnu9mu.fsf@kriyative.dyndns.org> Message-ID: On Sat, 28 Jul 2007 21:16:57 -0700, "Ram Krishnan" wrote: > Are there any problems in subverting the *META-DISPATCHER* binding > this way? Is there a better alternative? Looks OK to me. That (virtual host support) was actually one of the reasons why *META-DISPATCHER* is there. Cheers, Edi. From rkris at kriyative.net Sun Jul 29 21:37:29 2007 From: rkris at kriyative.net (Ram Krishnan) Date: Sun, 29 Jul 2007 14:37:29 -0700 Subject: [hunchentoot-devel] Virtual hosts support using *META-DISPATCHER* In-Reply-To: References: <87tzrnu9mu.fsf@kriyative.dyndns.org> Message-ID: <6e7f31bf0707291437o49316491y9ce069c51badb808@mail.gmail.com> Perfect. Thanks for the follow up. Also, thanks Edi for Hunchentoot and all the other excellent Lisp packages you've contributed. Regards, -ram On 7/29/07, Edi Weitz wrote: > > On Sat, 28 Jul 2007 21:16:57 -0700, "Ram Krishnan" > wrote: > > > Are there any problems in subverting the *META-DISPATCHER* binding > > this way? Is there a better alternative? > > Looks OK to me. That (virtual host support) was actually one of the > reasons why *META-DISPATCHER* is there. > > Cheers, > Edi. > _______________________________________________ > tbnl-devel site list > tbnl-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/tbnl-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: