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
|
2008-06-12 04:50:20 -04:00
|
|
|
vocabs.loader destructors assocs debugger continuations
|
2008-06-12 19:53:53 -04:00
|
|
|
combinators tools.vocabs math
|
2008-06-12 04:50:20 -04:00
|
|
|
io
|
|
|
|
io.server
|
2008-06-12 19:53:53 -04:00
|
|
|
io.sockets
|
|
|
|
io.sockets.secure
|
2008-06-12 04:50:20 -04:00
|
|
|
io.encodings
|
|
|
|
io.encodings.utf8
|
|
|
|
io.encodings.ascii
|
|
|
|
io.encodings.binary
|
|
|
|
io.streams.limited
|
|
|
|
io.timeouts
|
2008-06-12 19:53:53 -04:00
|
|
|
fry logging calendar urls
|
2008-06-12 04:50:20 -04:00
|
|
|
http
|
|
|
|
http.server.responses
|
|
|
|
html.elements
|
|
|
|
html.streams ;
|
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
|
2008-04-27 04:09:00 -04:00
|
|
|
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-01 18:22:39 -04:00
|
|
|
|
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
|
|
|
|
2008-04-27 04:09:00 -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-04 20:54:05 -04:00
|
|
|
swap development-mode get [ '[ , 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-06-12 04:50:20 -04:00
|
|
|
[ write-response ]
|
|
|
|
[
|
|
|
|
request get method>> "HEAD" = [ drop ] [
|
|
|
|
'[
|
|
|
|
,
|
|
|
|
[ content-charset>> encode-output ]
|
|
|
|
[ write-response-body ]
|
|
|
|
bi
|
|
|
|
]
|
|
|
|
[
|
|
|
|
utf8 [
|
|
|
|
development-mode get
|
2008-06-13 01:47:47 -04:00
|
|
|
[ http-error. ] [ drop "Response error" rethrow ] if
|
2008-06-12 04:50:20 -04:00
|
|
|
] with-encoded-output
|
|
|
|
] recover
|
|
|
|
] if
|
|
|
|
] bi ;
|
2008-02-25 15:53:18 -05:00
|
|
|
|
|
|
|
LOG: httpd-hit NOTICE
|
|
|
|
|
|
|
|
: log-request ( request -- )
|
2008-06-12 04:50:20 -04:00
|
|
|
[ 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
|
|
|
|
2008-06-01 18:22:39 -04:00
|
|
|
: init-request ( request -- )
|
|
|
|
request set
|
2008-06-02 16:00:03 -04:00
|
|
|
V{ } clone responder-nesting set ;
|
2008-04-27 04:09:00 -04:00
|
|
|
|
2008-06-01 18:22:39 -04:00
|
|
|
: dispatch-request ( request -- response )
|
|
|
|
url>> path>> split-path main-responder get call-responder ;
|
|
|
|
|
2008-06-12 19:53:53 -04:00
|
|
|
: prepare-request ( request -- request )
|
|
|
|
[
|
|
|
|
local-address get
|
|
|
|
[ secure? "https" "http" ? >>protocol ]
|
|
|
|
[ port>> '[ , or ] change-port ]
|
|
|
|
bi
|
|
|
|
] change-url ;
|
|
|
|
|
|
|
|
: valid-request? ( request -- ? )
|
|
|
|
url>> port>> local-address get port>> = ;
|
|
|
|
|
2008-03-11 04:39:09 -04:00
|
|
|
: do-request ( request -- response )
|
2008-06-02 18:51:06 -04:00
|
|
|
'[
|
|
|
|
,
|
2008-06-12 19:53:53 -04:00
|
|
|
{
|
|
|
|
[ init-request ]
|
|
|
|
[ prepare-request ]
|
|
|
|
[ log-request ]
|
|
|
|
[ dup valid-request? [ dispatch-request ] [ drop <400> ] if ]
|
|
|
|
} cleave
|
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 ;
|
|
|
|
|
2008-06-12 04:50:20 -04:00
|
|
|
: setup-limits ( -- )
|
|
|
|
1 minutes timeouts
|
|
|
|
64 1024 * limit-input ;
|
|
|
|
|
2008-03-05 22:38:15 -05:00
|
|
|
: handle-client ( -- )
|
|
|
|
[
|
2008-06-12 04:50:20 -04:00
|
|
|
setup-limits
|
|
|
|
ascii decode-input
|
|
|
|
ascii encode-output
|
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-12 04:50:20 -04:00
|
|
|
"http.server" binary [ 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
|