This extension provides a safe, portable, very flexible remote REPL facility. The server component is fully threaded and may be plugged into any existing codebase without modification. The client component is not threaded.
For maximum flexibility, all procedures involved in the operation of these extensions may be specified. The default is to use the tcp extension with no authentication and no sandboxing, but the design should make it easy to extend (e.g. through SSL sockets, ACL authentication, shared or unshared environments, etc) while maintaining safety. All conditions are caught and handled properly, and no knowledge of threading, exception handling, or chicken internals is required. Just plug it in and go!
For the server component, use: (require-extension remote-repl-server)
Creates a new remote-repl server and returns a rrepl-server object. The server automatically starts a listener thread, waiting for connections on PORTNUM. KEYARGS are optional keyword arguments for extending/tuning the server's behaviour, as given below:
Keyword | Default | Description |
---|---|---|
listen | tcp-listen |
Procedure to create a listener for incoming connections. Must take three arguments: an integer portnum on which to listen, an integer count of maximum pending connections, and a string (or #f) corresponding to a hostname/IP. The final string argument, if given, is the only host from which connections are allowed. |
accept | tcp-accept |
Procedure to accept an incoming connection from a listener port. Takes in a listener argument and returns an input port and an output port for the new connection. |
clisten | tcp-close |
Procedure to close and release a listener port given as an argument. |
auth | identity |
After accepting a connection with accept, the auth procedure is evaluated on the server object and the new session object created from the ports. If the session authenticates, it is returned; if it does not pass, return #f. The REPL thread for a session is not started until after authentication. |
host | #f |
If given, only accept connections originating from this hostname/IP. See listen for more details. |
backlog | 4 |
Maximum number of pending connections. See listen for more details. |
timeout-read | 50000 |
Timeout in milliseconds before aborting a read operation. NOTE: DO NOT SET THIS TO #f! Timeouts are handled gracefully and will not generate errors, and are required for proper operation. |
timeout-write | 50000 |
Timeout in milliseconds before aborting a write operation. NOTE: DO NOT SET THIS TO #f! Timeouts are handled gracefully and will not generate errors, and are required for proper operation. |
timeout-accept | 50000 |
Timeout in milliseconds before aborting an accept operation. NOTE: DO NOT SET THIS TO #f! Timeouts are handled gracefully and will not generate errors, and are required for proper operation. |
reader | read |
Procedure to read from a session's input port. |
evaler | eval |
Procedure for evaluating input in a session. Takes TWO arguments, the expression to evaluate and the session object. This allows the rrepl-session:extra field to be used, if desired. |
printer | write + newline |
Procedure for displaying evaluated output to a session's output port. Takes two arguments, the object to be written and the output port. NOTE: A NEWLINE MUST BE ADDED BY THIS PROCEDURE FOLLOWING OUTPUT. |
close-in | close-input-port |
Procedure for closing a session's input port. |
close-out | close-output-port |
Procedure for closing a session's output port. |
Closes the remote-repl server specified by SERVER-OBJ. This includes closing the listener port and all active sessions.
Returns #t if OBJ is a rrepl-server object.
Returns the procedure for closing the listener port. This is a wrapper around the procedure specified by the keyword clisten for condition safety and metadata cleanup.
Returns the procedure for reading from a session's input port, as specified by the reader keyword.
Returns the procedure for evaluating input in a session, as specified by the evaler keyword.
Returns the procedure for printing to a session's output port, as specified by the printer keyword.
Returns a procedure that takes a rrepl-server object and a rrepl-session object, and shuts down the session, after closing the ports. Uses the procedures specified by the close-in and close-out keywords.
Returns the listener port associated with SERVER-OBJ, or #f if not accepting connections.
Returns SERVER-OBJ's listener thread.
Returns a list of currently active rrepl-session objects connected to SERVER-OBJ.
Returns #t if SERVER-OBJ is accepting new connections, or #f otherwise.
Sets the accepting-new-connections state of SERVER-OBJ to BOOL. This is intended for use in auth procedures to force the listener port to close after a certain number of connections. Setting this to #f will irrevocably kill the listener port.
Returns #t if SERVER-OBJ is currently active, or #f if it is closed. Note: A server running with a closed listener port is explicitly allowed.
Sets the running state of SERVER-OBJ to BOOL. This should generally never be used, as setting to #f will shut down the server without proper cleanup.
Returns #t if OBJ is a rrepl-session object.
Returns the input socket port associated with SESSION-OBJ.
Returns the output socket port associated with SESSION-OBJ.
Returns SESSION-OBJ's REPL thread.
Returns SESSION-OBJ's "extra" object (initially #f). This is an arbitrary user-settable object for augmenting any other functionality.
Sets the "extra" object for SESSION-OBJ to OBJ. OBJ may be any object.
Returns #t if session is open and active, or #f otherwise.
Sets the running state of SESSION-OBJ to BOOL. This should generally never be used, as setting to #f will end the session without proper cleanup.
For the client component, use: (require-extension remote-repl-client)
Creates a new remote-repl client and returns a rrepl-client object. The server automatically connects and authenticates to HOSTNAME on port PORTNUM. KEYARGS are optional keyword arguments for extending/tuning the client's behaviour, as given below:
Keyword | Default | Description |
---|---|---|
connect | tcp-connect |
Procedure to create a socket connection to a remote host. Must take the hostname and portnum as its arguments, and returns an input port and an output port. |
auth | identity |
After connecting with connect, the auth procedure is evaluated on a new rrepl-client object to perform any authentication steps before handing off to the user. Returns the rrepl-client object on success, or #f on failure. |
reader | read-line |
Procedure to read the output (one line) from the remote REPL. |
printer | write + newline |
Procedure for sending expressions to the output port for evaluation by the remote REPL. Takes two arguments, the expression to be run and the output port. NOTE: A NEWLINE MUST BE ADDED BY THIS PROCEDURE FOLLOWING OUTPUT. |
close-in | close-input-port |
Procedure for closing a client's input port. |
close-out | close-output-port |
Procedure for closing a client's output port. |
Sends EXPRESSION to the remote REPL for evaluation, and returns the result as a string.
Closes the remote REPL client specified by CLIENT-OBJ. This includes closing the ports and notifying the server that the session is over.
Returns #t if OBJ is a rrepl-client object.
Returns the procedure for reading from a client's input port, as specified by the reader keyword.
Returns the procedure for printing to a client's output port, as specified by the printer keyword.
Returns a procedure that takes a rrepl-client object, and shuts down the client, after closing the ports. Uses the procedures specified by the close-in and close-out keywords.
Returns the input socket port associated with CLIENT-OBJ.
Returns the output socket port associated with CLIENT-OBJ.
Returns #t if client is connected and active, or #f otherwise.
None known
Simplest (default) usage, with tcp connections and no auth:
> (require-extension remote-repl-server) ; loading chicken/3/remote-repl-server.so ... > (define srv (rrepl-server-start 5555)) > (require-extension remote-repl-client) ; loading chicken/3/remote-repl-client.so ... > (define cli (rrepl-client-connect "localhost" 5555)) > (rrepl-client-send cli '(define foo 3)) "#<unspecified>" > (rrepl-client-send cli 'foo) "3" > (rrepl-client-close cli) shutting down session... > (rrepl-server-close srv) "#t"
Using SSL with no authentication and restricting to local connections:
> (require-extension openssl) ; loading chicken/3/openssl.so ... > (require-extension remote-repl-server) ; loading chicken/3/remote-repl-server.so ... > (define srv (rrepl-server-start 5555 host: "localhost" listen: ssl-listen accept: ssl-accept clisten: ssl-close)) > (require-extension remote-repl-client) ; loading chicken/3/remote-repl-client.so ... > (define cli (rrepl-client-connect "localhost" 5555 connect: ssl-connect)) > (rrepl-client-send cli '(define foo 3)) "#<unspecified>" > (rrepl-client-send cli 'foo) "3" > (rrepl-client-close cli) shutting down session... > (rrepl-server-close srv) "#t"
Sandboxed evaluation for each session, tcp connections, no authentication:
> (require-extension sandbox) ; loading chicken/3/sandbox.so ... > (require-extension remote-repl-server) ; loading chicken/3/remote-repl-server.so ... > (define srv (rrepl-server-start 5555 auth: (lambda (serv sess) (rrepl-session:extra! sess (make-safe-environment parent: (current-environment) mutable: #t extendable: #t)) sess) evaler: (lambda (expr sess) (eval expr (rrepl-session:extra sess))))) > (require-extension remote-repl-client) ; loading chicken/3/remote-repl-client.so ... > (define cli (rrepl-client-connect "localhost" 5555)) > (rrepl-client-send cli '(define foo 3)) "#<unspecified>" > (rrepl-client-send cli 'foo) "3" > (define cli2 (rrepl-client-connect "localhost" 5555)) > (rrepl-client-send cli2 'foo) "\"condition: (exn) - unbound variable args: (foo)\"" > (rrepl-client-close cli) shutting down session... > (rrepl-client-close cli2) shutting down session... > (rrepl-server-close srv) "#t"
Copyright (C) 2008, Elf. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED AS-IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.