]> gitweb.factorcode.org Git - factor.git/blob - library/httpd/file-responder.factor
7bfbda4da750793c399df19708ca25eeb3070074
[factor.git] / library / httpd / file-responder.factor
1 !:folding=indent:collapseFolds=0:
2
3 ! $Id$
4 !
5 ! Copyright (C) 2004 Slava Pestov.
6
7 ! Redistribution and use in source and binary forms, with or without
8 ! modification, are permitted provided that the following conditions are met:
9
10 ! 1. Redistributions of source code must retain the above copyright notice,
11 !    this list of conditions and the following disclaimer.
12
13 ! 2. Redistributions in binary form must reproduce the above copyright notice,
14 !    this list of conditions and the following disclaimer in the documentation
15 !    and/or other materials provided with the distribution.
16
17 ! THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 ! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19 ! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 ! DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 ! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 ! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 ! OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 ! WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 ! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 IN: file-responder
29 USE: combinators
30 USE: html
31 USE: kernel
32 USE: lists
33 USE: namespaces
34 USE: parser
35 USE: regexp
36 USE: stack
37 USE: stdio
38 USE: streams
39 USE: strings
40
41 USE: httpd
42 USE: httpd-responder
43
44 !!! Support words.
45 : mime-types ( -- alist )
46     [
47         [  "html"   | "text/html"                ]
48         [  "txt"    | "text/plain"               ]
49                                                 
50         [  "gif"    | "image/gif"                ]
51         [  "png"    | "image/png"                ]
52         [  "jpg"    | "image/jpeg"               ]
53         [  "jpeg"   | "image/jpeg"               ]
54                     
55         [  "jar"    | "application/octet-stream" ]
56         [  "zip"    | "application/octet-stream" ]
57         [  "tgz"    | "application/octet-stream" ]
58         [  "tar.gz" | "application/octet-stream" ]
59         [  "gz"     | "application/octet-stream" ]
60     ] ;
61
62 : mime-type ( filename -- mime-type )
63     file-extension mime-types assoc [ "text/plain" ] unless* ;
64
65 !!! Serving files.
66 : file-header ( filename -- header )
67     "200 Document follows" swap mime-type response ;
68
69 : serve-file ( filename -- )
70     dup file-header print <filebr> "stdio" get fcopy ;
71
72 !!! Serving directories.
73 : file>html ( filename -- ... )
74     "<li><a href=\"" swap
75     !dup directory? [ "/" cat2 ] when
76     chars>entities
77     "\">" over "</a></li>" ;
78
79 : directory>html ( directory -- html )
80     directory [ file>html ] map cat ;
81
82 : list-directory ( directory -- )
83     serving-html
84     [
85         "<html><head><title>" swap
86         "</title></head><body><h1>" over
87         "</h1><ul>" over
88         directory>html
89         "</ul></body></html>"
90     ] cons expand cat write ;
91
92 : serve-directory ( directory -- )
93     dup "/index.html" cat2 dup exists? [
94         nip serve-file
95     ] [
96         drop list-directory
97     ] ifte ;
98
99 !!! Serving objects.
100 : serve-static ( filename -- )
101     dup directory? [
102         serve-directory
103     ] [
104         serve-file
105     ] ifte ;
106
107 : serve-script ( argument filename -- )
108     <namespace> [ swap "argument" set run-file ] bind ;
109
110 : parse-object-name ( filename -- argument filename )
111     dup [
112         dup #"(.*?)\?(.*)" groups dup [ nip call ] when swap
113     ] [
114         drop f "/"
115     ] ifte ;
116
117 : file-responder ( filename -- )
118     "doc-root" get [
119         parse-object-name "doc-root" get swap cat2
120         dup exists? [
121             dup file-extension "lhtml" = [
122                 serve-script
123             ] [
124                 nip serve-static
125             ] ifte
126         ] [
127             2drop "404 not found" httpd-error
128         ] ifte
129     ] [
130         drop "404 doc-root not set" httpd-error
131     ] ifte ;