Changeset 20875 in project

10/18/10 15:46:30 (11 years ago)
Moritz Heidkamp

gazette: spiffy omelette!

1 edited


  • gazette/src/issues/

    r20874 r20875  
    1515[[|dict 1.4]],
    1616[[|pstk 1.1]] and
    17 [[|colorize 0.3]] 0.3), as well as
     17[[|colorize 0.3]]), as well as
    1818some releases introducing new features:
    2626Core development has been pretty quiet this week with only a little
    2727activity on the
    28 [[;a=log;h=refs/heads/experimental|experimental branch]]. Let's
     28[[;a=log;h=refs/heads/experimental|experimental branch]]. The most visible change is the [[|addition of a blob literal syntax]] by [[|Felix Winkelmann]].
    3030== 3. Chicken Talk
    4545== 4. Omelette Recipes - Tips and Tricks
    47 TODO
     47This week I'd like to direct your attention at our web server
     48[[|Spiffy]]. Its feature set is
     49comparable to that of the
     50[[|Apache HTTP Server]] or
     51[[|lighttpd]], although it doesn't sport as
     52many extension modules (yet). While that may seem intimidating at
     53first, it actually isn't: Since Spiffy is a Scheme web server, no
     54idiosyncratic configuration file format is needed to set it up, all
     55you need is a few s-exprs to get started! Let's start with a simple
     58<enscript language="scheme">
     59(use spiffy)
     61(vhost-map `(((* any) . ,(lambda (continue)
     62                        (send-response body: "hey there!\n"
     63                                       headers: '((content-type text/plain)))))))
     65(start-server port: 12345)
     68Alright, what does that mean? The {{vhost-map}} thing may look a
     69little odd at first. This is necessary because Spiffy has been built
     70from the ground up to support virtual hosting. The {{vhost-map}}
     71parameter is just an alist of hostnames to handlers. Hostnames are
     72given as regular expressions (either traditional or
     73[[|SREs]]). In the
     74example we just define a handler for {{(* any)}}, i.e. we use the same
     75handler for all hostnames.
     77The handler procedure is called whenever a request for the matching
     78hostname is to be handled. In the example, we always send a static
     79plain text response regardless of what the request was using the
     80convenience function {{send-response}} (let's ignore the {{continue}}
     81argument for the moment). Execute the code using {{csi}} to make
     82Spiffy listen on TCP port 12345. Try it like this:
     84    $ curl 'http://localhost:12345/'
     85    hey there!
     87Or with a more complex URI, inspecting the response headers:
     89    $ curl -D - 'http://localhost:12345/foo/bar?baz'   
     90    HTTP/1.1 200 OK
     91    Content-Type: text/plain
     92    Server: Spiffy/4.8 (Running on Chicken 4.6.0)
     93    Content-Length: 11
     94    Date: Mon, 18 Oct 2010 13:06:39 GMT
     96    hey there!
     98Very well! Now, usually a handler would inspect the
     99{{current-request}} parameter (which holds an
     100[[|intarweb request record]]
     101representing the currently handled request) to determine how to
     102respond. Let's try to change our handler so that it only sends {{"hey
     103there"}} when the path {{/hey}} is requested. Otherwise, we'd like to
     104serve files from a certain directory (say {{/var/www}}) or, if no such
     105file exists, send a {{404}} response. This is how it can be done:
     107<enscript language="scheme">
     108(use spiffy uri-common intarweb)
     110(root-path "/var/www")
     112(vhost-map `(((* any) . ,(lambda (continue)
     113                           (if (equal? '(/ "hey") (uri-path (request-uri (current-request))))
     114                               (send-response body: "hey there!\n"
     115                                              headers: '((content-type text/plain)))
     116                               (continue))))))
     118(start-server port: 12345)
     121As you can see, we now need
     122[[|intarweb]] and
     123[[|uri-common]] to be able to
     124inspect {{current-request}}. We also set the {{root-path}} which is
     125akin do Apache's {{DocumentRoot}} directive. Since it is a paramter,
     126it can be easily altered by handlers using {{paramterize}}. The
     127handler itself is only slightly more complicated now: We check whether
     128{{current-request}}'s {{uri-path}} is {{(/ "hey")}} ({{uri-common}}'s
     129way of representing the {{/hey}}) and if so, send just the response as
     130before. For any other path we call the {{continue}} procedure which is
     131passed to our handler by Spiffy. This tells Spiffy "I am done with
     132that request, please pass control on to the next handler". As it
     133happens, the next handler is Spiffy's file system handler which will
     134just take the {{uri-path}}, check whether it exists under the current
     135{{root-path}} and then delivers the file. If the path doesn't exist, a
     136{{404}} response is sent.
     138Spiffy ships
     139[[a few more useful handlers|]]
     140which you can easily integrate into your own application. There's also
     142[[|egg providing a directory listing handler]]
     143as well as several eggs that may help you creating more advanced
     144applications such as
     151For real-world uses check out the Spiffy based
     152[[|image gallery application phoghorn]],
     153[[|qwiki]] (the wiki software
     154powering [[|the Chicken wiki]]) and, of
     155course, the infamous
     156[[|awful web framework]].
    49159== 5. About the Chicken Gazette
Note: See TracChangeset for help on using the changeset viewer.