Written from a line-by-line source review; the deterministic example outputs are from a real run.
Introduction
The tls plugin enables encrypted (TLS) network connections from the script: as a client you can connect to a TLS server (for example an HTTPS server), or you can accept encrypted connections yourself as a server. The encryption is done by OpenSSL. The plugin is handle-based: every connection and server context receives an integer identifier (a handle) by which further operations refer to it.
OpenSSL at runtime (the backend)
The plugin loads OpenSSL at runtime (it does not link it at build time), following the pattern of the project's other plugins (sqlite, json). If OpenSSL is available, tls.Backend() is “openssl” and encryption works. If it is not available, loading still succeeds, but tls.Backend() will be “stub” and the network calls return a clean error message — the rest of the interpreter is unaffected.
Client and server
As a client the flow is: NewClient (connect) → Handshake (the encrypted handshake and certificate verification) → Write / Read (encrypted sending and receiving of data) → Close. As a server: NewServerContext (loading the certificate and key) → Accept (accepting an incoming connection, which gives a connection handle) → Read/Write/Close on the connection → finally CloseServerContext.
Loading the plugin
plugin "../plugins/print/PrintPlugin"; plugin "../plugins/tls/TlsPlugin";
A typical flow — TLS client
i32 $c;
blob $req[256];
blob $resp[4096];
$c = tls.NewClient("example.com", 443);
tls.Handshake($c);
$req = blob.FromText("GET / HTTP/1.0\r\nHost:
example.com\r\n\r\n");
tls.Write($c, $req);
$resp = tls.Read($c, 4096);
tls.Close($c);What to know about every function (the basics)
NewClient / NewServerContext / Accept return a positive handle; connections are closed with Close, the server context with CloseServerContext.
Handshake / Write / Read / Close, etc. return 0 on success (Write returns the number of bytes written, Read returns a blob); on error they raise a runtime error, and LastError() can be queried for the detail.
Certificate verification is ON by default: with an invalid or untrusted certificate the Handshake fails. SetInsecureSkipVerify turns this off — but ONLY for testing, never in production.
Read returns a 0-length blob when the connection has closed cleanly (EOF). Write returns 0 for an empty blob.
Read's maxBytes parameter must be between 1 and 16 million (1<<24).
Data passes as a blob in both directions (Write takes a blob, Read returns a blob), because network data can contain arbitrary bytes.
How to read the signatures
handle is the identifier of a connection or server context. The type after the -> arrow is the return type. In the Version signature, handle? indicates that the handle argument is optional (without an argument it returns the OpenSSL version, with a handle the connection's TLS version).
Client connection
Connecting to a TLS server, performing the handshake, sending and receiving encrypted data.
tls.NewClient
tls.NewClient(host, port) -> int
Opens a TCP connection to the given server and prepares a TLS client; returns a connection handle.
| Parameter | Type | Description |
|---|---|---|
| host | string | The server's name or IP address. |
| port | int | The port (between 1 and 65535; for HTTPS typically 443). |
The connection handle (a positive integer). A failed connection causes a runtime error.
i32 $c;
$c = tls.NewClient("example.com", 443);
// ... Handshake, Write, Read ...
tls.Close($c);(you continue with the handshake using the handle)
The first step of a TLS connection as a client. After connecting there is NOT yet an encrypted channel — Handshake creates that. Always call Close at the end.
tls.Handshake
tls.Handshake(handle) -> int
Performs the TLS handshake on the connection: creates the encrypted channel and (by default) verifies the server's certificate.
| Parameter | Type | Description |
|---|---|---|
| handle | int | The connection handle returned by NewClient. |
0 on success. A failed handshake or certificate verification causes a runtime error (LastError gives the detail).
i32 $c;
$c = tls.NewClient("example.com", 443);
tls.Handshake($c);
// from here the channel is encrypted
tls.Close($c);(0 on success; otherwise a runtime error)
After NewClient, before the first Write/Read. If the server's certificate is invalid or untrusted, it stops here — this is the protection against a fake server.
tls.Write
tls.Write(handle, data) -> int
Sends the blob's contents encrypted over the connection.
| Parameter | Type | Description |
|---|---|---|
| handle | int | The connection handle (the handshake must already be done). |
| data | blob | The binary data to send. |
The number of bytes sent (0 for an empty blob). On error, a runtime error.
i32 $c;
blob $req[256];
$c = tls.NewClient("example.com", 443);
tls.Handshake($c);
$req = blob.FromText("GET / HTTP/1.0\r\n\r\n");
tls.Write($c, $req);
tls.Close($c);(the number of bytes sent)
To send a request or data over the encrypted channel (for example an HTTP request to the HTTPS server). Pass the data as a blob — blob.FromText turns text into a blob.
tls.Read
tls.Read(handle, maxBytes) -> blob
Reads encrypted data from the connection, up to the given size.
| Parameter | Type | Description |
|---|---|---|
| handle | int | The connection handle (the handshake must already be done). |
| maxBytes | int | The upper limit of bytes to read at once (between 1 and 16777216). |
The read data as a blob; a 0-length blob if the connection has closed cleanly (EOF). On error, a runtime error.
i32 $c;
blob $resp[4096];
$c = tls.NewClient("example.com", 443);
tls.Handshake($c);
// ... Write ...
$resp = tls.Read($c, 4096);
printf("%d bytes\n", $resp.Length);
tls.Close($c);(the read bytes)
To receive the server's response. A single Read does not necessarily return the whole response — repeat until you get an empty (0-length) blob, which marks the end of the connection.
tls.Close
tls.Close(handle) -> int
Closes the TLS connection and frees its resources.
| Parameter | Type | Description |
|---|---|---|
| handle | int | The connection handle to close. |
0.
i32 $c;
$c = tls.NewClient("example.com", 443);
tls.Handshake($c);
tls.Close($c);0
Close every connection when you are done with it, so the socket and the OpenSSL resources are freed.
tls.SetInsecureSkipVerify
tls.SetInsecureSkipVerify(handle, on) -> int
Turns the server's certificate verification on or off for the given connection.
| Parameter | Type | Description |
|---|---|---|
| handle | int | The connection handle. |
| on | int | 1 = TURN OFF verification (insecure), 0 = turn it back on. |
0.
i32 $c;
$c = tls.NewClient("127.0.0.1", 8443);
// FOR TESTING ONLY: accepting a self-signed certificate
tls.SetInsecureSkipVerify($c, 1);
tls.Handshake($c);
tls.Close($c);0
ONLY for testing, for example for a local development server with a self-signed certificate. In production NEVER turn off verification — without it the connection is defenseless against a man-in-the-middle attack.
Server
Accepting encrypted connections as a server: creating a certificate context, accepting a connection, closing the context.
tls.NewServerContext
tls.NewServerContext(certFile, keyFile) -> int
Creates a server context from the given certificate and key files; returns a context handle.
| Parameter | Type | Description |
|---|---|---|
| certFile | string | The path of the server's certificate file (PEM). |
| keyFile | string | The path of the private key file (PEM). |
The server-context handle (a positive integer). On error (for example a missing or bad file), a runtime error.
i32 $ctx;
$ctx = tls.NewServerContext("server.crt", "server.key");
// ... Accept ...
tls.CloseServerContext($ctx);(the context handle with which you accept connections)
The first step of a TLS server: the context holds the certificate and the key with which the server proves itself to clients. Several connections can be accepted on one context.
tls.Accept
tls.Accept(ctxHandle, host, port) -> int
Waits for an incoming TLS connection on the given address and port, and returns a connection handle for the accepted client.
| Parameter | Type | Description |
|---|---|---|
| ctxHandle | int | The context handle returned by NewServerContext. |
| host | string | The address to listen on (for example “0.0.0.0” for all interfaces). |
| port | int | The port to listen on. |
A connection handle for the accepted client. On error, a runtime error.
i32 $ctx;
i32 $c;
blob $data[4096];
$ctx = tls.NewServerContext("server.crt", "server.key");
$c = tls.Accept($ctx, "0.0.0.0", 8443);
$data = tls.Read($c, 4096);
tls.Close($c);
tls.CloseServerContext($ctx);(the connection handle for the accepted client)
To accept clients. The returned connection handle is handled the same way (Read/Write/Close) as a client connection. The handshake happens as part of Accept.
tls.CloseServerContext
tls.CloseServerContext(ctxHandle) -> int
Closes the server context and frees its resources.
| Parameter | Type | Description |
|---|---|---|
| ctxHandle | int | The context handle to close. |
0.
i32 $ctx;
$ctx = tls.NewServerContext("server.crt", "server.key");
// ... Accepts ...
tls.CloseServerContext($ctx);0
When the server shuts down or accepts no more connections. Already-accepted connections must be closed separately with Close; this frees the context itself.
Certificate and trust
Setting the trust store (the CA bundle) and querying the peer's certificate.
tls.SetCaBundle
tls.SetCaBundle(path) -> int
Sets the trust store (CA bundle) used for certificate verification to a file. It is a global setting that affects client connections opened afterwards.
| Parameter | Type | Description |
|---|---|---|
| path | string | The path of the PEM file containing the CA certificates. |
0.
// use a custom trust store
tls.SetCaBundle("/etc/ssl/certs/ca-bundle.crt");0
When you want to use a custom trust store (for example with the certificates of an internal, private certificate authority), not the system default. Without it, the system default trust store applies.
tls.PeerCertSubject
tls.PeerCertSubject(handle) -> string
Returns the subject field of the peer's certificate (received in the handshake) as text.
| Parameter | Type | Description |
|---|---|---|
| handle | int | The connection handle (the handshake must already be done). |
The certificate's subject as text, or an empty string if there is no peer certificate.
i32 $c;
string $subj[512];
$c = tls.NewClient("example.com", 443);
tls.Handshake($c);
$subj = tls.PeerCertSubject($c);
printf("%s\n", $subj);
tls.Close($c);(the certificate's subject, e.g. /CN=example.com)
To check or log the peer's identity after the handshake — for example whether the certificate really belongs to the expected party.
Information
Querying the TLS backend, the version, and the most recent error message.
tls.Backend
tls.Backend() -> string
Tells whether TLS support is running: “openssl” if OpenSSL loaded, “stub” if not.
This function takes no arguments.
“openssl” or “stub”.
printf("%s\n", tls.Backend());openssl
To check at startup whether encryption is available at all. If “stub”, OpenSSL did not load and the network calls would fail — this is a deterministic, platform-independent check.
tls.Version
tls.Version(handle?) -> string
Without an argument it returns the loaded OpenSSL version string; with a connection handle, the negotiated TLS version of that connection.
| Parameter | Type | Description |
|---|---|---|
| handle? | int | An optional connection handle. Given, it returns the connection's TLS version; omitted, the OpenSSL version. |
The OpenSSL version string, or (with a handle) the connection's TLS version (for example “TLSv1.3”).
// the OpenSSL version (without an argument)
printf("%s\n", tls.Version());<version>
For diagnostics: without an argument the library version (for compatibility checks), and with the handle of an active connection, which TLS version the parties agreed on.
tls.LastError
tls.LastError() -> string
Returns the human-readable error message of the most recent TLS operation.
This function takes no arguments.
The most recent error message (an empty string if there has been no error yet).
printf("[%s]\n", tls.LastError());[]
For details after a failed operation (Handshake, Write, Read). Since failed calls raise a runtime error, you typically use this to log the error context or display the error reason.
Practical notes
What the tls plugin is good for
Sending HTTPS requests: connecting as a TLS client to a web server over an encrypted channel.
Building an encrypted service: accepting encrypted connections as a TLS server with your own certificate.
Secure data exchange: sending and receiving arbitrary binary data (blob), protected against eavesdropping.
Certificate verification: confirming the peer's identity based on the trust store.
Client flow
The typical client flow: NewClient (connect) → Handshake (encrypted channel + certificate verification) → Write to send the request → Read repeatedly to receive the response (until you get an empty blob) → Close. Before Handshake the channel is not yet encrypted, so Write/Read can only be used after it.
Server flow
The typical server flow: NewServerContext (loading the certificate + key) → Accept to accept a connection (this gives a connection handle) → Read/Write on the connection → Close on the connection → finally CloseServerContext. Several Accepts can belong to one context one after another.
Safety
Certificate verification is on by default — do not turn it off in production. SetInsecureSkipVerify is for testing only.
For a custom trust store use SetCaBundle; without it the system default CA store applies.
You can check or log the peer's identity after the handshake with PeerCertSubject.
If tls.Backend() is “stub”, OpenSSL is not available — then encryption does not work.
Error handling
A wrong argument count or type, an invalid handle, a failed connection, handshake, or certificate verification, and a missing OpenSSL are reported by the runtime as a runtime error, and the script stops. The error detail is given by LastError(). Successful operations return 0 (or Write the byte count, Read a blob); Backend and Version are deterministic information that can be queried even without a network.
The ffmpeg video-decoding plugin
Opening videos, decoding frames, and audio playback (FFmpeg) — complete function reference