Introduction to the QoreRepl Module
The QoreRepl module provides a reusable REPL (Read-Eval-Print Loop) implementation for Qore. It can be used from:
- Command-line applications (with linenoise for line editing)
- Network handlers (WebSocket, HTTP, etc.)
- WebSocket server for remote REPL access
The module provides:
The core QoreRepl class handles:
- Incremental parsing using Qore's parsePending/parseCommit API
- Multi-line input detection (incomplete statements)
- Result formatting
- Special commands (/help, /vars, /reset, etc.)
Basic Usage
Basic Evaluation
%requires QoreRepl
QoreRepl repl();
*hash<auto> result = repl.eval("1 + 1");
if (result.value) {
printf("Result: %s\n", QoreRepl::formatValue(result.value));
}
result = repl.eval("if (True) {");
printf("Prompt: %s\n", repl.getPrompt());
result = repl.eval(" print('hello');");
result = repl.eval("}");
WebSocket Server Example
The module includes built-in WebSocket server support. Simply add the handler to an HttpServer:
%requires HttpServer
%requires QoreRepl
QoreReplWebSocketHandler handler();
handler.setAuthCallback(sub (hash<auto> cx, hash<auto> hdr) returns bool {
return hdr."x-api-key" == "secret123";
});
HttpServer server({"port": 8080});
server.addHandler("/ws/repl", handler);
server.start();
WebSocket Message Protocol
The WebSocket handler uses a JSON message protocol. See the AsyncAPI schema at QoreRepl/QoreReplApi.asyncapi.yaml for complete message definitions.
Client to Server:
{"type": "eval", "code": "1 + 1"} - Evaluate code
{"type": "command", "command": "/help"} - Execute REPL command
{"type": "ping"} - Keepalive
Server to Client:
{"type": "result", "value": "2"} - Evaluation result
{"type": "error", "error": "PARSE-ERROR", "description": "..."} - Error
{"type": "prompt", "value": "qore> ", "needsMoreInput": false} - Prompt update
{"type": "session", "sessionId": "...", "version": "1.0"} - Session info on connect
Sandboxing and Security
The QoreRepl class supports sandboxing through Qore's parse options. You can restrict what code the REPL can execute by passing parse options when creating the underlying Program object.
Sandboxed REPL Example
%requires QoreRepl
int sandbox_options = PO_NO_FILESYSTEM | PO_NO_NETWORK | PO_NO_EXTERNAL_PROCESS;
QoreRepl repl({"parse_options": sandbox_options});
*hash<auto> result = repl.eval("/pwd");
result = repl.eval("File::readTextFile('/etc/passwd')");
Available Parse Options for Sandboxing
Common parse options for sandboxing:
| Parse Option | Description
|
| Qore::PO_NO_FILESYSTEM | Disables filesystem access (affects /pwd, /cd, /load, /save commands)
|
| Qore::PO_NO_NETWORK | Disables network access (affects Socket, HTTPClient, etc.)
|
| Qore::PO_NO_EXTERNAL_PROCESS | Disables external process execution (system(), backquote, etc.)
|
| Qore::PO_NO_PROCESS_CONTROL | Disables process control functions (exit(), fork(), etc.)
|
| Qore::PO_NO_THREAD_CONTROL | Disables thread control (background operator, thread_exit)
|
| Qore::PO_NO_DATABASE | Disables database access
|
Command Behavior in Sandboxed Mode
When filesystem access is restricted (Qore::PO_NO_FILESYSTEM), the following REPL commands will display helpful error messages instead of failing silently:
/pwd - Shows "filesystem access is restricted (PO_NO_FILESYSTEM)"
/cd - Shows "filesystem access is restricted (PO_NO_FILESYSTEM)"
/load - Shows "filesystem access is restricted (PO_NO_FILESYSTEM)"
/save - Shows "filesystem access is restricted (PO_NO_FILESYSTEM)"
All other REPL commands continue to work normally in sandboxed mode, including introspection commands (/vars, /functions, /classes, etc.) and session commands (/help, /reset, /history, etc.).
Sandboxed WebSocket Server
You can also create sandboxed WebSocket REPL servers:
%requires HttpServer
%requires QoreRepl
int sandbox_options = PO_NO_FILESYSTEM | PO_NO_NETWORK | PO_NO_EXTERNAL_PROCESS;
QoreReplWebSocketHandler handler({"parse_options": sandbox_options});
handler.setAuthCallback(sub (hash<auto> cx, hash<auto> hdr) returns bool {
return hdr."x-api-key" == "secret123";
});
HttpServer server({"port": 8080});
server.addHandler("/ws/repl", handler);
server.start();
Release Notes
v1.0
- Initial release
- Added WebSocket server support with QoreReplWebSocketHandler and QoreReplWebSocketConnection
- Added action-based REPL session for Creator WebSocket integration
- Added AsyncAPI 3.0 schema for the WebSocket message protocol
- Added sandboxing support with graceful handling of restricted commands
- Added introspection commands: /functions, /classes, /constants, /namespaces, /modules, /type, /describe
- Added session commands: /history, /timing
- Added file commands: /save, /pwd, /cd
- Added auto-return for pure expressions (e.g., "1 + 1" displays "=> 2")
- Added comprehensive tests