145 lines
3.7 KiB
Factor
Executable File
145 lines
3.7 KiB
Factor
Executable File
! Copyright (C) 2003, 2008 Slava Pestov.
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
USING: continuations destructors kernel math math.parser
|
|
namespaces parser sequences strings prettyprint debugger
|
|
quotations combinators logging calendar assocs
|
|
fry accessors arrays io io.sockets io.encodings.ascii
|
|
io.sockets.secure io.files io.streams.duplex io.timeouts
|
|
io.encodings threads concurrency.combinators
|
|
concurrency.semaphores concurrency.flags
|
|
combinators.short-circuit ;
|
|
IN: io.servers.connection
|
|
|
|
TUPLE: threaded-server
|
|
name
|
|
secure insecure
|
|
secure-config
|
|
sockets
|
|
max-connections
|
|
semaphore
|
|
timeout
|
|
encoding
|
|
handler
|
|
ready ;
|
|
|
|
: local-server ( port -- addrspec ) "localhost" swap <inet> ;
|
|
|
|
: internet-server ( port -- addrspec ) f swap <inet> ;
|
|
|
|
: new-threaded-server ( class -- threaded-server )
|
|
new
|
|
"server" >>name
|
|
ascii >>encoding
|
|
1 minutes >>timeout
|
|
V{ } clone >>sockets
|
|
<secure-config> >>secure-config
|
|
[ "No handler quotation" throw ] >>handler
|
|
<flag> >>ready ; inline
|
|
|
|
: <threaded-server> ( -- threaded-server )
|
|
threaded-server new-threaded-server ;
|
|
|
|
SYMBOL: remote-address
|
|
|
|
GENERIC: handle-client* ( threaded-server -- )
|
|
|
|
<PRIVATE
|
|
|
|
: >insecure ( addrspec -- addrspec' )
|
|
dup { [ integer? ] [ string? ] } 1|| [ internet-server ] when ;
|
|
|
|
: >secure ( addrspec -- addrspec' )
|
|
>insecure
|
|
dup { [ secure? ] [ not ] } 1|| [ <secure> ] unless ;
|
|
|
|
: listen-on ( threaded-server -- addrspecs )
|
|
[ secure>> >secure ] [ insecure>> >insecure ] bi
|
|
[ resolve-host ] bi@ append ;
|
|
|
|
LOG: accepted-connection NOTICE
|
|
|
|
: log-connection ( remote local -- )
|
|
[ [ remote-address set ] [ local-address set ] bi* ]
|
|
[ 2array accepted-connection ]
|
|
2bi ;
|
|
|
|
M: threaded-server handle-client* handler>> call ;
|
|
|
|
: handle-client ( client remote local -- )
|
|
'[
|
|
, , log-connection
|
|
threaded-server get
|
|
[ timeout>> timeouts ] [ handle-client* ] bi
|
|
] with-stream ;
|
|
|
|
: thread-name ( server-name addrspec -- string )
|
|
unparse-short " connection from " swap 3append ;
|
|
|
|
: accept-connection ( threaded-server -- )
|
|
[ accept ] [ addr>> ] bi
|
|
[ '[ , , , handle-client ] ]
|
|
[ drop threaded-server get name>> swap thread-name ] 2bi
|
|
spawn drop ;
|
|
|
|
: accept-loop ( threaded-server -- )
|
|
[
|
|
threaded-server get semaphore>>
|
|
[ [ accept-connection ] with-semaphore ]
|
|
[ accept-connection ]
|
|
if*
|
|
] [ accept-loop ] bi ; inline recursive
|
|
|
|
: started-accept-loop ( threaded-server -- )
|
|
threaded-server get
|
|
[ sockets>> push ] [ ready>> raise-flag ] bi ;
|
|
|
|
: start-accept-loop ( addrspec -- )
|
|
threaded-server get encoding>> <server>
|
|
[ started-accept-loop ] [ [ accept-loop ] with-disposal ] bi ;
|
|
|
|
\ start-accept-loop ERROR add-error-logging
|
|
|
|
: init-server ( threaded-server -- threaded-server )
|
|
dup semaphore>> [
|
|
dup max-connections>> [
|
|
<semaphore> >>semaphore
|
|
] when*
|
|
] unless ;
|
|
|
|
PRIVATE>
|
|
|
|
: start-server ( threaded-server -- )
|
|
init-server
|
|
dup secure-config>> [
|
|
dup threaded-server [
|
|
dup name>> [
|
|
listen-on [
|
|
start-accept-loop
|
|
] parallel-each
|
|
] with-logging
|
|
] with-variable
|
|
] with-secure-context ;
|
|
|
|
: wait-for-server ( threaded-server -- )
|
|
ready>> wait-for-flag ;
|
|
|
|
: start-server* ( threaded-server -- )
|
|
[ [ start-server ] curry "Threaded server" spawn drop ]
|
|
[ wait-for-server ]
|
|
bi ;
|
|
|
|
: stop-server ( -- )
|
|
threaded-server get [ f ] change-sockets drop dispose-each ;
|
|
|
|
GENERIC: port ( addrspec -- n )
|
|
|
|
M: integer port ;
|
|
|
|
M: object port port>> ;
|
|
|
|
: secure-port ( -- n )
|
|
threaded-server get dup [ secure>> port ] when ;
|
|
|
|
: insecure-port ( -- n )
|
|
threaded-server get dup [ insecure>> port ] when ;
|