2008-02-29 01:57:38 -05:00
|
|
|
! Copyright (C) 2004, 2008 Slava Pestov.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2008-05-01 17:24:50 -04:00
|
|
|
USING: calendar html io io.files kernel math math.order
|
|
|
|
math.parser http http.server namespaces parser sequences strings
|
|
|
|
assocs hashtables debugger http.mime sorting html.elements
|
|
|
|
logging calendar.format accessors io.encodings.binary fry ;
|
2008-02-29 01:57:38 -05:00
|
|
|
IN: http.server.static
|
|
|
|
|
|
|
|
! special maps mime types to quots with effect ( path -- )
|
2008-05-01 21:03:02 -04:00
|
|
|
TUPLE: file-responder root hook special allow-listings ;
|
2008-02-29 01:57:38 -05:00
|
|
|
|
2008-05-01 17:24:50 -04:00
|
|
|
: modified-since? ( filename -- ? )
|
|
|
|
request get "if-modified-since" header dup [
|
|
|
|
[ file-info modified>> ] [ rfc822>timestamp ] bi* after?
|
|
|
|
] [
|
|
|
|
2drop t
|
|
|
|
] if ;
|
2008-02-29 01:57:38 -05:00
|
|
|
|
|
|
|
: <304> ( -- response )
|
|
|
|
304 "Not modified" <trivial-response> ;
|
|
|
|
|
2008-05-01 21:03:02 -04:00
|
|
|
: <403> ( -- response )
|
|
|
|
403 "Forbidden" <trivial-response> ;
|
|
|
|
|
2008-02-29 01:57:38 -05:00
|
|
|
: <file-responder> ( root hook -- responder )
|
2008-05-01 21:03:02 -04:00
|
|
|
file-responder new
|
|
|
|
swap >>hook
|
|
|
|
swap >>root
|
|
|
|
H{ } clone >>special ;
|
2008-02-29 01:57:38 -05:00
|
|
|
|
|
|
|
: <static> ( root -- responder )
|
|
|
|
[
|
|
|
|
<content>
|
2008-05-01 17:24:50 -04:00
|
|
|
swap [
|
|
|
|
file-info
|
|
|
|
[ size>> "content-length" set-header ]
|
|
|
|
[ modified>> "last-modified" set-header ] bi
|
|
|
|
]
|
2008-05-05 03:19:25 -04:00
|
|
|
[ '[ , binary <file-reader> output-stream get stream-copy ] >>body ] bi
|
2008-02-29 01:57:38 -05:00
|
|
|
] <file-responder> ;
|
|
|
|
|
|
|
|
: serve-static ( filename mime-type -- response )
|
2008-05-01 17:24:50 -04:00
|
|
|
over modified-since?
|
|
|
|
[ file-responder get hook>> call ] [ 2drop <304> ] if ;
|
2008-02-29 01:57:38 -05:00
|
|
|
|
|
|
|
: serving-path ( filename -- filename )
|
2008-03-27 06:18:07 -04:00
|
|
|
file-responder get root>> right-trim-separators
|
|
|
|
"/"
|
|
|
|
rot "" or left-trim-separators 3append ;
|
2008-02-29 01:57:38 -05:00
|
|
|
|
|
|
|
: serve-file ( filename -- response )
|
|
|
|
dup mime-type
|
2008-03-11 04:39:09 -04:00
|
|
|
dup file-responder get special>> at
|
2008-02-29 01:57:38 -05:00
|
|
|
[ call ] [ serve-static ] ?if ;
|
|
|
|
|
|
|
|
\ serve-file NOTICE add-input-logging
|
|
|
|
|
|
|
|
: file. ( name dirp -- )
|
|
|
|
[ "/" append ] when
|
|
|
|
dup <a =href a> write </a> ;
|
|
|
|
|
|
|
|
: directory. ( path -- )
|
|
|
|
dup file-name [
|
2008-03-11 04:39:09 -04:00
|
|
|
[ <h1> file-name write </h1> ]
|
|
|
|
[
|
|
|
|
<ul>
|
|
|
|
directory sort-keys
|
|
|
|
[ <li> file. </li> ] assoc-each
|
|
|
|
</ul>
|
|
|
|
] bi
|
2008-02-29 01:57:38 -05:00
|
|
|
] simple-html-document ;
|
|
|
|
|
|
|
|
: list-directory ( directory -- response )
|
2008-05-01 21:03:02 -04:00
|
|
|
file-responder get allow-listings>> [
|
|
|
|
'[ , directory. ] <html-content>
|
|
|
|
] [
|
|
|
|
drop <403>
|
|
|
|
] if ;
|
2008-02-29 01:57:38 -05:00
|
|
|
|
|
|
|
: find-index ( filename -- path )
|
2008-04-25 04:23:47 -04:00
|
|
|
"index.html" append-path dup exists? [ drop f ] unless ;
|
2008-02-29 01:57:38 -05:00
|
|
|
|
|
|
|
: serve-directory ( filename -- response )
|
2008-04-25 04:23:47 -04:00
|
|
|
request get path>> "/" tail? [
|
|
|
|
dup
|
|
|
|
find-index [ serve-file ] [ list-directory ] ?if
|
2008-02-29 01:57:38 -05:00
|
|
|
] [
|
2008-04-25 04:23:47 -04:00
|
|
|
drop
|
2008-04-27 04:09:00 -04:00
|
|
|
request get path>> "/" append f <standard-redirect>
|
2008-02-29 01:57:38 -05:00
|
|
|
] if ;
|
|
|
|
|
|
|
|
: serve-object ( filename -- response )
|
2008-04-25 04:23:47 -04:00
|
|
|
serving-path dup exists?
|
2008-05-15 00:23:12 -04:00
|
|
|
[ dup file-info directory? [ serve-directory ] [ serve-file ] if ]
|
2008-04-25 04:23:47 -04:00
|
|
|
[ drop <404> ]
|
|
|
|
if ;
|
2008-02-29 01:57:38 -05:00
|
|
|
|
2008-04-27 04:09:00 -04:00
|
|
|
M: file-responder call-responder* ( path responder -- response )
|
2008-03-11 04:39:09 -04:00
|
|
|
file-responder set
|
2008-04-25 04:23:47 -04:00
|
|
|
".." over member?
|
|
|
|
[ drop <400> ] [ "/" join serve-object ] if ;
|