factor/extra/http/server/server.factor

94 lines
2.5 KiB
Factor
Raw Normal View History

2008-02-07 02:05:10 -05:00
! Copyright (C) 2003, 2008 Slava Pestov.
2007-09-20 18:09:08 -04:00
! See http://factorcode.org/license.txt for BSD license.
2008-06-02 16:00:03 -04:00
USING: kernel accessors sequences arrays namespaces splitting
vocabs.loader http http.server.responses logging calendar
destructors html.elements html.streams io.server
io.encodings.8-bit io.timeouts io assocs debugger continuations
fry tools.vocabs math ;
2007-09-20 18:09:08 -04:00
IN: http.server
2008-06-02 16:00:03 -04:00
SYMBOL: responder-nesting
SYMBOL: main-responder
SYMBOL: development-mode
2008-04-25 04:23:47 -04:00
! path is a sequence of path component strings
GENERIC: call-responder* ( path responder -- response )
2008-03-11 04:39:09 -04:00
2008-02-29 01:57:38 -05:00
TUPLE: trivial-responder response ;
2008-02-25 15:53:18 -05:00
2008-02-29 01:57:38 -05:00
C: <trivial-responder> trivial-responder
2008-02-25 15:53:18 -05:00
2008-06-02 16:00:03 -04:00
M: trivial-responder call-responder* nip response>> clone ;
2008-02-25 15:53:18 -05:00
2008-06-02 22:59:23 -04:00
main-responder global [ <404> <trivial-responder> or ] change-at
2008-04-25 04:23:47 -04:00
: invert-slice ( slice -- slice' )
2008-06-02 16:00:03 -04:00
dup slice? [ [ seq>> ] [ from>> ] bi head-slice ] [ drop { } ] if ;
2008-06-02 16:00:03 -04:00
: add-responder-nesting ( path responder -- )
[ invert-slice ] dip 2array responder-nesting get push ;
2008-04-25 04:23:47 -04:00
: call-responder ( path responder -- response )
2008-06-02 16:00:03 -04:00
[ add-responder-nesting ] [ call-responder* ] 2bi ;
2008-03-03 03:19:36 -05:00
2008-04-22 22:08:27 -04:00
: http-error. ( error -- )
"Internal server error" [
2008-06-02 16:00:03 -04:00
[ print-error nl :c ] with-html-stream
2008-04-22 22:08:27 -04:00
] simple-page ;
2008-02-29 01:57:38 -05:00
: <500> ( error -- response )
500 "Internal server error" <trivial-response>
2008-06-02 16:00:03 -04:00
development-mode get [ swap '[ , http-error. ] >>body ] [ drop ] if ;
2008-02-29 01:57:38 -05:00
2008-03-11 04:39:09 -04:00
: do-response ( response -- )
2008-02-29 01:57:38 -05:00
dup write-response
2008-03-11 04:39:09 -04:00
request get method>> "HEAD" =
2008-06-02 16:00:03 -04:00
[ drop ] [ '[ , write-response-body ] [ http-error. ] recover ] if ;
2008-02-25 15:53:18 -05:00
LOG: httpd-hit NOTICE
: log-request ( request -- )
[ method>> ] [ url>> [ host>> ] [ path>> ] bi ] bi 3array httpd-hit ;
2008-03-17 05:31:13 -04:00
2008-04-25 04:23:47 -04:00
: split-path ( string -- path )
2008-05-14 00:36:55 -04:00
"/" split harvest ;
2008-04-25 04:23:47 -04:00
: init-request ( request -- )
request set
2008-06-02 16:00:03 -04:00
V{ } clone responder-nesting set ;
: dispatch-request ( request -- response )
url>> path>> split-path main-responder get call-responder ;
2008-03-11 04:39:09 -04:00
: do-request ( request -- response )
2008-06-02 18:51:06 -04:00
'[
,
[ init-request ]
[ log-request ]
[ dispatch-request ] tri
2008-06-02 16:00:03 -04:00
] [ [ \ do-request log-error ] [ <500> ] bi ] recover ;
2008-03-11 04:39:09 -04:00
2008-03-05 22:38:15 -05:00
: ?refresh-all ( -- )
2008-02-29 01:57:38 -05:00
development-mode get-global
2008-03-05 22:38:15 -05:00
[ global [ refresh-all ] bind ] when ;
: handle-client ( -- )
[
1 minutes timeouts
2008-03-05 22:38:15 -05:00
?refresh-all
read-request
2008-03-11 04:39:09 -04:00
do-request
do-response
2008-03-05 22:38:15 -05:00
] with-destructors ;
2008-02-29 01:57:38 -05:00
2007-09-20 18:09:08 -04:00
: httpd ( port -- )
2008-05-23 18:45:33 -04:00
dup integer? [ internet-server ] when
2008-06-02 16:00:03 -04:00
"http.server" latin1 [ handle-client ] with-server ;
2007-09-20 18:09:08 -04:00
2008-05-23 18:45:33 -04:00
: httpd-main ( -- )
8888 httpd ;
2007-09-20 18:09:08 -04:00
MAIN: httpd-main