Commit9feb5873Recorded7 May 2026Repositorysigil-irc

Make IRC WebSocket frames spec-compliant

Message

Send one IRC message per WebSocket frame without appending CRLF, matching IRCv3 WebSocket framing and Enclave's listener semantics.

Update the WASM IRC WebSocket smoke expectations to assert the frame payloads without line terminators.

Verification:

  • sh test/integration/test-wasm-irc-websocket.sh
  • /home/daviwil/Projects/Code/sigil/sigil/build/dev/bin/sigil test --redirects ./dev-redirects.sgl
Changed
 packages/sigil-irc-websocket/src/sigil/irc/websocket.sgl | 20 +++++---------------
 test/integration/test-wasm-irc-websocket.mjs             |  6 +++---
 2 files changed, 8 insertions(+), 18 deletions(-)
Diff
packages/sigil-irc-websocket/src/sigil/irc/websocket.sglmodified
@@ -1,9 +1,10 @@
1
;;; (sigil irc websocket) - IRC-over-WebSocket client/session helper
2
;;;
3
;;; This module composes the public `(sigil websocket)` client API with the
4
;;; protocol-only `(sigil irc message)` layer. It intentionally does not import
5
;;; the native IRC connection, socket, TLS, crypto, or SASL modules, so browser
6
;;; WASM builds can use it as a small Enclave-facing transport adapter.
+4
;;; protocol-only `(sigil irc message)` layer. IRCv3 WebSocket transports carry
+5
;;; one IRC line per frame without CRLF. This module intentionally does not
+6
;;; import the native IRC connection, socket, TLS, crypto, or SASL modules, so
+7
;;; browser WASM builds can use it as a small Enclave-facing transport adapter.
8
9
(define-library (sigil irc websocket)
10
(import (sigil core)
@@ -63,11 +64,6 @@
64
user: (or user nick)
65
realname: (if (and nick (string=? realname "")) nick realname)))
66
66
(define (line-ended? text)
67
(let ((len (string-length text)))
68
(and (> len 0)
69
(char=? (string-ref text (- len 1)) #\newline))))
70
67
(define (strip-line-ending line)
68
(let ((len (string-length line)))
69
(cond
@@ -80,11 +76,6 @@
76
(substring line 0 end))))
77
(else line))))
78
83
(define (append-line-ending line)
84
(if (line-ended? line)
85
line
86
(string-append line "\r\n")))
87
79
(define (contains-line-ending? text)
80
(if (string-index text (lambda (c) (char=? c #\newline)))
81
#t
@@ -175,8 +166,7 @@
166
(: irc-ws-session? string? -> void?)
167
(unless (irc-ws-connected? session)
168
(error "irc-ws-send: session is not connected"))
178
(ws-send (irc-ws-session-websocket session)
179
(append-line-ending line)))
+169
(ws-send (irc-ws-session-websocket session) line))
170
171
(define (irc-ws-command session command . args)
172
(: irc-ws-session? string? string? ... -> void?)
test/integration/test-wasm-irc-websocket.mjsmodified
@@ -200,10 +200,10 @@ async function main() {
200
201
await new Promise((resolve) => setTimeout(resolve, 300));
202
203
if (!messages.includes("NICK wasm-irc\r\n")) {
+203
if (!messages.includes("NICK wasm-irc")) {
204
throw new Error(`echo server did not receive NICK registration; saw ${JSON.stringify(messages)}`);
205
}
206
if (!messages.includes("USER wasm-irc 0 * wasm-irc\r\n")) {
+206
if (!messages.includes("USER wasm-irc 0 * wasm-irc")) {
207
throw new Error(`echo server did not receive USER registration; saw ${JSON.stringify(messages)}`);
208
}
209
@@ -227,7 +227,7 @@ async function main() {
227
(irc-ws-close session)
228
`);
229
230
if (!messages.includes("PRIVMSG #sigil :hello from wasm irc\r\n")) {
+230
if (!messages.includes("PRIVMSG #sigil :hello from wasm irc")) {
231
throw new Error(`echo server did not receive IRC PRIVMSG; saw ${JSON.stringify(messages)}`);
232
}
233
console.log("irc-websocket-wasm-ok");