| 
									
										
										
										
											2009-03-15 19:19:29 -04:00
										 |  |  | ! Copyright (C) 2003, 2009 Slava Pestov. | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							|  |  |  | USING: continuations destructors kernel math math.parser | 
					
						
							| 
									
										
										
										
											2008-12-08 20:45:48 -05:00
										 |  |  | namespaces parser sequences strings prettyprint | 
					
						
							| 
									
										
										
										
											2008-09-22 17:09:10 -04:00
										 |  |  | quotations combinators logging calendar assocs present | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | fry accessors arrays io io.sockets io.encodings.ascii | 
					
						
							|  |  |  | io.sockets.secure io.files io.streams.duplex io.timeouts | 
					
						
							| 
									
										
										
										
											2008-09-22 17:09:10 -04:00
										 |  |  | io.encodings threads make concurrency.combinators | 
					
						
							| 
									
										
										
										
											2008-06-25 17:58:19 -04:00
										 |  |  | concurrency.semaphores concurrency.flags | 
					
						
							| 
									
										
										
										
											2009-03-16 21:11:36 -04:00
										 |  |  | combinators.short-circuit ;
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | IN: io.servers.connection | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: threaded-server | 
					
						
							| 
									
										
										
										
											2009-06-15 14:07:15 -04:00
										 |  |  | name | 
					
						
							|  |  |  | log-level | 
					
						
							|  |  |  | secure | 
					
						
							|  |  |  | insecure | 
					
						
							|  |  |  | secure-config | 
					
						
							|  |  |  | sockets | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | max-connections | 
					
						
							|  |  |  | semaphore | 
					
						
							| 
									
										
										
										
											2009-06-15 14:07:15 -04:00
										 |  |  | timeout | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | encoding | 
					
						
							| 
									
										
										
										
											2009-06-15 14:07:15 -04:00
										 |  |  | handler | 
					
						
							|  |  |  | ready ;
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : local-server ( port -- addrspec ) "localhost" swap <inet> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : internet-server ( port -- addrspec ) f swap <inet> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-30 20:15:53 -04:00
										 |  |  | : new-threaded-server ( encoding class -- threaded-server )
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  |     new
 | 
					
						
							| 
									
										
										
										
											2009-06-15 14:07:15 -04:00
										 |  |  |         "server" >>name | 
					
						
							|  |  |  |         DEBUG >>log-level | 
					
						
							|  |  |  |         <secure-config> >>secure-config | 
					
						
							|  |  |  |         V{ } clone >>sockets | 
					
						
							|  |  |  |         1 minutes >>timeout | 
					
						
							|  |  |  |         [ "No handler quotation" throw ] >>handler | 
					
						
							|  |  |  |         <flag> >>ready | 
					
						
							| 
									
										
										
										
											2009-06-11 21:20:38 -04:00
										 |  |  |         swap >>encoding ;
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-30 20:15:53 -04:00
										 |  |  | : <threaded-server> ( encoding -- threaded-server )
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  |     threaded-server new-threaded-server ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-30 16:25:53 -04:00
										 |  |  | GENERIC: handle-client* ( threaded-server -- )
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | <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 ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-22 17:09:10 -04:00
										 |  |  | : accepted-connection ( remote local -- )
 | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         [ "remote: " % present % ", " % ] | 
					
						
							|  |  |  |         [ "local: " % present % ] | 
					
						
							|  |  |  |         bi*
 | 
					
						
							|  |  |  |     ] "" make | 
					
						
							|  |  |  |     \ accepted-connection NOTICE log-message ;
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : log-connection ( remote local -- )
 | 
					
						
							| 
									
										
										
										
											2008-09-22 17:09:10 -04:00
										 |  |  |     [ accepted-connection ] | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  |     [ [ remote-address set ] [ local-address set ] bi* ] | 
					
						
							|  |  |  |     2bi ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-15 19:19:29 -04:00
										 |  |  | M: threaded-server handle-client* handler>> call( -- ) ;
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : handle-client ( client remote local -- )
 | 
					
						
							|  |  |  |     '[ | 
					
						
							| 
									
										
										
										
											2008-09-10 23:11:40 -04:00
										 |  |  |         _ _ log-connection | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  |         threaded-server get
 | 
					
						
							|  |  |  |         [ timeout>> timeouts ] [ handle-client* ] bi
 | 
					
						
							|  |  |  |     ] with-stream ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-28 18:56:44 -04:00
										 |  |  | \ handle-client ERROR add-error-logging | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | : thread-name ( server-name addrspec -- string )
 | 
					
						
							| 
									
										
										
										
											2008-12-03 20:10:41 -05:00
										 |  |  |     unparse-short " connection from " glue ;
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-30 16:25:53 -04:00
										 |  |  | : accept-connection ( threaded-server -- )
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  |     [ accept ] [ addr>> ] bi
 | 
					
						
							| 
									
										
										
										
											2008-09-10 23:11:40 -04:00
										 |  |  |     [ '[ _ _ _ handle-client ] ] | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  |     [ drop threaded-server get name>> swap thread-name ] 2bi
 | 
					
						
							|  |  |  |     spawn drop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-30 16:25:53 -04:00
										 |  |  | : accept-loop ( threaded-server -- )
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  |     [ | 
					
						
							|  |  |  |         threaded-server get semaphore>> | 
					
						
							|  |  |  |         [ [ accept-connection ] with-semaphore ] | 
					
						
							|  |  |  |         [ accept-connection ] | 
					
						
							|  |  |  |         if*
 | 
					
						
							| 
									
										
										
										
											2008-08-28 23:28:01 -04:00
										 |  |  |     ] [ accept-loop ] bi ; inline recursive
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-30 16:25:53 -04:00
										 |  |  | : started-accept-loop ( threaded-server -- )
 | 
					
						
							| 
									
										
										
										
											2008-06-25 17:58:19 -04:00
										 |  |  |     threaded-server get
 | 
					
						
							|  |  |  |     [ sockets>> push ] [ ready>> raise-flag ] bi ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : start-accept-loop ( addrspec -- )
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  |     threaded-server get encoding>> <server> | 
					
						
							| 
									
										
										
										
											2008-06-25 17:58:19 -04:00
										 |  |  |     [ started-accept-loop ] [ [ accept-loop ] with-disposal ] bi ;
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-03 02:12:50 -04:00
										 |  |  | \ start-accept-loop NOTICE add-error-logging | 
					
						
							| 
									
										
										
										
											2008-06-17 06:21:45 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | : init-server ( threaded-server -- threaded-server )
 | 
					
						
							|  |  |  |     dup semaphore>> [ | 
					
						
							|  |  |  |         dup max-connections>> [ | 
					
						
							|  |  |  |             <semaphore> >>semaphore | 
					
						
							|  |  |  |         ] when*
 | 
					
						
							|  |  |  |     ] unless ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-17 19:42:44 -05:00
										 |  |  | : (start-server) ( threaded-server -- )
 | 
					
						
							|  |  |  |     init-server | 
					
						
							|  |  |  |     dup threaded-server [ | 
					
						
							| 
									
										
										
										
											2009-02-18 17:01:53 -05:00
										 |  |  |         [ ] [ name>> ] bi [ | 
					
						
							| 
									
										
										
										
											2008-11-17 19:42:44 -05:00
										 |  |  |             [ listen-on [ start-accept-loop ] parallel-each ] | 
					
						
							|  |  |  |             [ ready>> raise-flag ] | 
					
						
							|  |  |  |             bi
 | 
					
						
							|  |  |  |         ] with-logging | 
					
						
							|  |  |  |     ] with-variable ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : start-server ( threaded-server -- )
 | 
					
						
							| 
									
										
										
										
											2008-11-17 19:42:44 -05:00
										 |  |  |     #! Only create a secure-context if we want to listen on | 
					
						
							|  |  |  |     #! a secure port, otherwise start-server won't work at | 
					
						
							|  |  |  |     #! all if SSL is not available. | 
					
						
							|  |  |  |     dup secure>> [ | 
					
						
							|  |  |  |         dup secure-config>> [ | 
					
						
							|  |  |  |             (start-server) | 
					
						
							|  |  |  |         ] with-secure-context | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         (start-server) | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-25 17:58:19 -04:00
										 |  |  | : wait-for-server ( threaded-server -- )
 | 
					
						
							|  |  |  |     ready>> wait-for-flag ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : start-server* ( threaded-server -- )
 | 
					
						
							|  |  |  |     [ [ start-server ] curry "Threaded server" spawn drop ] | 
					
						
							|  |  |  |     [ wait-for-server ] | 
					
						
							|  |  |  |     bi ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-02 09:30:38 -04:00
										 |  |  | : stop-server ( threaded-server -- )
 | 
					
						
							|  |  |  |     [ f ] change-sockets drop dispose-each ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : stop-this-server ( -- )
 | 
					
						
							|  |  |  |     threaded-server get stop-server ;
 | 
					
						
							| 
									
										
										
										
											2008-06-17 01:04:18 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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 ;
 |