1 | [[tags: egg]] |
---|
2 | |
---|
3 | == Spiffy |
---|
4 | |
---|
5 | [[toc:]] |
---|
6 | |
---|
7 | === Description |
---|
8 | |
---|
9 | A small web-server written in [[http://www.call-with-current-continuation.org|Chicken]]. |
---|
10 | |
---|
11 | This is the documentation for Spiffy 4, a rewrite from scratch. |
---|
12 | For information on Spiffy 3, please see [[spiffy 3]]. |
---|
13 | |
---|
14 | === Author |
---|
15 | |
---|
16 | [[Felix Winkelmann]]. Currently maintained by [[Peter Bex]]. |
---|
17 | |
---|
18 | === Requirements |
---|
19 | |
---|
20 | Requires the [[intarweb]], [[matchable]] and [[sendfile]] extensions. |
---|
21 | |
---|
22 | === Download |
---|
23 | |
---|
24 | [[http://www.call-with-current-continuation.org/eggs/spiffy.egg|spiffy.egg]] |
---|
25 | |
---|
26 | === Documentation |
---|
27 | |
---|
28 | Spiffy is a web-server library for the Chicken Scheme system. It's |
---|
29 | quite easy to set up and use (whether as a library or a standalone |
---|
30 | server application) and it can be customized in numerous ways. |
---|
31 | |
---|
32 | === Starting the server |
---|
33 | |
---|
34 | <procedure>(start-server [port: port-number])</procedure> |
---|
35 | |
---|
36 | Starts the server, to listen on the given port. Other configuration |
---|
37 | can be tweaked through SRFI-39 parameters. These are listed below. |
---|
38 | Once the server is started, server behaviour can be controlled through |
---|
39 | these parameters as well. By default, Spiffy will only serve static |
---|
40 | files. On directories, it will give a "403 forbidden", unless there |
---|
41 | is an index-file. If there is, that file's contents will be shown. |
---|
42 | |
---|
43 | All arguments directly supplied to {{start-server}} override the |
---|
44 | configuration parameter values. |
---|
45 | |
---|
46 | {{Port-number}} defaults to 8080. |
---|
47 | |
---|
48 | === Configuration parameters |
---|
49 | |
---|
50 | The following parameters can be used to control spiffy's behaviour. |
---|
51 | Besides these parameters, you can also influence spiffy's behaviour by |
---|
52 | tweaking the [[intarweb]] parameters. |
---|
53 | |
---|
54 | <parameter>(root-path [path])</parameter> |
---|
55 | |
---|
56 | The path to the document root. Defaults to {{"./web"}}. |
---|
57 | |
---|
58 | <parameter>(server-port [port-number])</parameter> |
---|
59 | |
---|
60 | The port number on which to listen. Defaults to 8080. |
---|
61 | |
---|
62 | <parameter>(index-files [file-list])</parameter> |
---|
63 | |
---|
64 | A list of filenames which are to be used as index files to serve when |
---|
65 | the requested URL identifies a directory. Defaults to |
---|
66 | {{'("index.html" "index.xhtml")}} |
---|
67 | |
---|
68 | <parameter>(mime-type-map [extension->mimetype-list])</parameter> |
---|
69 | |
---|
70 | An alist of extensions (strings) to mime-types (symbols), to use |
---|
71 | for the content-type header when serving up a static file. Defaults to |
---|
72 | (("xml" . text/xml) |
---|
73 | ("html" . text/html) |
---|
74 | ("xhtml" . text/xhtml+xml) |
---|
75 | ("js" . text/javascript) |
---|
76 | ("pdf" . application/pdf) |
---|
77 | ("css" . text/css) |
---|
78 | ("png" . image/png) |
---|
79 | ("ico" . image/x-icon) |
---|
80 | ("gif" . image/gif) |
---|
81 | ("jpeg" . image/jpeg) |
---|
82 | ("jpg" . image/jpeg) |
---|
83 | ("svg" . image/svg+xml) |
---|
84 | ("bmp" . image/bmp) |
---|
85 | ("txt" . text/plain)) |
---|
86 | |
---|
87 | <parameter>(default-mime-type [mime-type])</parameter> |
---|
88 | |
---|
89 | The mime-type (a symbol) to use if none was found in the |
---|
90 | {{mime-type-map}}. Defaults to {{'application/octet-stream}} |
---|
91 | |
---|
92 | <parameter>(default-host [hostname])</parameter> |
---|
93 | |
---|
94 | The host name to use when no virtual host could be determined from the |
---|
95 | request. See the section on virtual hosts below. |
---|
96 | |
---|
97 | <parameter>(vhost-map [host-regex->vhost-handler])</parameter> |
---|
98 | |
---|
99 | A mapping of virtual hosts (regex) to handlers (procedures of one |
---|
100 | argument; a continuation thunk). See the section on virtual hosts |
---|
101 | below. Defaults to {{`((".*" . ,(lambda (continue) (continue))))}} |
---|
102 | |
---|
103 | <parameter>(file-extension-handlers [extension->handler-list])</parameter> |
---|
104 | |
---|
105 | An alist mapping file extensions (strings) to handler procedures |
---|
106 | (lambdas of one argument; the file name relative to the webroot). |
---|
107 | Defaults to {{'()}}. If no handler was found, defaults to just sending |
---|
108 | a static file. |
---|
109 | |
---|
110 | === Handlers |
---|
111 | |
---|
112 | Besides "static" configuration, Spiffy also has several handlers for |
---|
113 | when something is to be served. |
---|
114 | |
---|
115 | <parameter>(handle-directory [proc])</parameter> |
---|
116 | |
---|
117 | The handler for directory entries. If the requested URL points to a |
---|
118 | directory which has no index file, this handler is invoked. It is a |
---|
119 | procedure of one argument, the path (a string) relative to the |
---|
120 | webroot. Defaults to a procedure which returns a "403 forbidden". |
---|
121 | |
---|
122 | <parameter>(handle-file [proc])</parameter> |
---|
123 | |
---|
124 | The handler for files. If the requested URL points to a file, this |
---|
125 | handler is invoked to serve the file. It is a procedure of one |
---|
126 | argument, the path (a string) relative to the webroot. Defaults to a |
---|
127 | procedure which sets the content-type and determines a handler based |
---|
128 | on the {{file-extension-handlers}}, or {{send-static-file}} if none |
---|
129 | was found. |
---|
130 | |
---|
131 | <parameter>(handle-not-found [proc])</parameter> |
---|
132 | |
---|
133 | The handler for nonexisting files. If the requested URL does not point |
---|
134 | to an existing file or directory, this procedure is called. It is a |
---|
135 | procedure of one argument, the path (a string) that was |
---|
136 | requested. This path should be interpreted as being relative to the |
---|
137 | webroot (even though it points to no existing file). Defaults to a |
---|
138 | procedure which returns a "404 Not found". |
---|
139 | |
---|
140 | === Runtime information |
---|
141 | |
---|
142 | During the handling of a request, Spiffy adds more information to the |
---|
143 | environment by parameterizing the following parameters whenever the |
---|
144 | information becomes available: |
---|
145 | |
---|
146 | <parameter>(current-request [request])</parameter> |
---|
147 | |
---|
148 | An intarweb request-object that defines the current request. Available |
---|
149 | from the moment the request comes in and is parsed. Contains, among |
---|
150 | other things, the query parameters and the request-headers, in fully |
---|
151 | parsed form (as intarweb returns them). |
---|
152 | |
---|
153 | <parameter>(current-response [request])</parameter> |
---|
154 | |
---|
155 | An intarweb response-object that defines the current |
---|
156 | response. Available from the same time current-request is available. |
---|
157 | This keeps getting updated along the way, while the response data is |
---|
158 | being refined (like when headers are being added). |
---|
159 | |
---|
160 | <parameter>(current-file [path])</parameter> |
---|
161 | |
---|
162 | The path to the requested file (a string). Available from the moment |
---|
163 | Spiffy determined the requested URL points to a file (just before the |
---|
164 | {{handle-file}} procedure is called). |
---|
165 | |
---|
166 | <parameter>(current-pathinfo [path])</parameter> |
---|
167 | |
---|
168 | The trailing path ''fragments'' (a list of strings) that were passed |
---|
169 | in the URL after the requested filename. Available from the moment |
---|
170 | Spiffy determined the requested URL points to a file (just before the |
---|
171 | {{handle-file}} procedure is called). |
---|
172 | |
---|
173 | === Virtual hosts |
---|
174 | |
---|
175 | Spiffy has support for virtual hosting, using the HTTP/1.1 Host |
---|
176 | header. This allows you to use one Spiffy instance running on one IP |
---|
177 | address/port number to serve multiple webpages, as determined by the |
---|
178 | hostname that was requested. |
---|
179 | |
---|
180 | The virtual host is defined by a procedure, which can set arbitrary |
---|
181 | parameters on-the-fly. It is passed a continuation thunk, which it |
---|
182 | should explicitly call if it wants the processing to continue. The |
---|
183 | most used parameter in virtual host setups is the {{root-path}} |
---|
184 | parameter, so that another docroot can be selected based on the |
---|
185 | requested hostname, showing different websites for different hosts: |
---|
186 | |
---|
187 | <example> |
---|
188 | (vhost-map `(("foo\\.bar\\.com" . |
---|
189 | ,(lambda (continue) |
---|
190 | (parameterize ((file-extension-handlers |
---|
191 | `(("ssp" . ,ssp-handler) ("ws" . ,web-scheme-handler))) |
---|
192 | (root-path "/var/www/domains/foo.bar.com")) |
---|
193 | (continue)))) |
---|
194 | (,(glob->regexp "*.domain.com") . |
---|
195 | ,(lambda (continue) |
---|
196 | (parameterize ((file-extension-handlers |
---|
197 | `(("php" . ,(cgi-handler* "/usr/pkg/bin/php")))) |
---|
198 | (root-path "/var/www/domains/domain.com")) |
---|
199 | (continue)))))) |
---|
200 | </example> |
---|
201 | |
---|
202 | In this example, if a client accesses |
---|
203 | {{foo.bar.com/mumble/blah.html}}, the file |
---|
204 | {{/var/www/domains/foo.bar.com/mumble/blah.html}} will be served. Any |
---|
205 | files ending in {{.ssp}} or {{.ws}} will be served by the |
---|
206 | corresponding file type handler. If there's any PHP file, its source |
---|
207 | will simply be displayed. In case of |
---|
208 | {{my.domain.com/something/bar.html}}, the file |
---|
209 | {{/var/www/domains/domain.com/something/bar.html}} will be served. If |
---|
210 | there's a {{.ssp}} or {{.ws}} file there, it will not be interpreted. |
---|
211 | Its source will be displayed instead. A {{.php}} file, on the other |
---|
212 | hand, will be passed via CGI to the program {{/usr/pkg/bin/php}}. |
---|
213 | |
---|
214 | Domain names are mapped to a lambda that sets up any parameters it |
---|
215 | wants to override from the defaults. The host names are matched using |
---|
216 | {{string-match}}. If the host name is not yet a regexp, it will be |
---|
217 | converted to a ''case-insensitive'' regexp. |
---|
218 | |
---|
219 | === Procedures and macros |
---|
220 | |
---|
221 | The following procedures and macros can be used in dynamic web |
---|
222 | programs, or dynamic server configuration: |
---|
223 | |
---|
224 | <procedure>(with-headers new-headers thunk)</procedures> |
---|
225 | |
---|
226 | Call {{thunk}} with the header list {{new-headers}}. This |
---|
227 | parameterizes the current response to contain the new headers. The |
---|
228 | existing headers are extended with {{new-headers}} through intarweb's |
---|
229 | {{headers}} procedure. |
---|
230 | |
---|
231 | <procedure>(send-status code reason [message])</procedure> |
---|
232 | |
---|
233 | Easy way to send a page and a status code to the client. The optional |
---|
234 | message is a string containing HTML to add in the body of the |
---|
235 | response. Example: |
---|
236 | |
---|
237 | <example> |
---|
238 | <expr> |
---|
239 | (send-status 404 "Not found" |
---|
240 | "Sorry, page not found! Please try <a href='/search.ws'>our search page</a>") |
---|
241 | </expr> |
---|
242 | </example> |
---|
243 | |
---|
244 | <procedure>(send-static-file filename)</procedure> |
---|
245 | |
---|
246 | Send a file to the client. This sets the {{content-length}} header and |
---|
247 | tries to send the file as quickly as possible to the client. The |
---|
248 | filename is interpreted relative to {{root-path}}. |
---|
249 | |
---|
250 | <procedure>(restart-request request)</procedure> |
---|
251 | |
---|
252 | Restart the entire request-handling starting at the point where the |
---|
253 | request was just parsed. The argument is the new request to use. |
---|
254 | Be careful, this makes it very easy to introduce unwanted endless loops! |
---|
255 | |
---|
256 | === Changelog |
---|
257 | |
---|
258 | * 4.0 Rewrite from scratch, using Intarweb |
---|
259 | * pre-4.0 See the changelog for [[spiffy 3]] |
---|
260 | |
---|
261 | === License |
---|
262 | |
---|
263 | Copyright (c) 2005-2008, Felix L. Winkelmann and Peter Bex |
---|
264 | All rights reserved. |
---|
265 | |
---|
266 | Redistribution and use in source and binary forms, with or without |
---|
267 | modification, are permitted provided that the following conditions are |
---|
268 | met: |
---|
269 | |
---|
270 | Redistributions of source code must retain the above copyright |
---|
271 | notice, this list of conditions and the following disclaimer. |
---|
272 | |
---|
273 | Redistributions in binary form must reproduce the above copyright |
---|
274 | notice, this list of conditions and the following disclaimer in the |
---|
275 | documentation and/or other materials provided with the distribution. |
---|
276 | |
---|
277 | Neither the name of the author nor the names of its contributors may |
---|
278 | be used to endorse or promote products derived from this software |
---|
279 | without specific prior written permission. |
---|
280 | |
---|
281 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
---|
282 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
---|
283 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
---|
284 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
---|
285 | COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
---|
286 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
---|
287 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
---|
288 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
289 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
---|
290 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
---|
291 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
---|
292 | OF THE POSSIBILITY OF SUCH DAMAGE. |
---|