Function readSmallMessage [src]

Reads the next message from the WebSocket stream, failing if the message does not fit into recv_buffer.

Prototype

pub fn readSmallMessage(ws: *WebSocket) ReadSmallTextMessageError!SmallMessage

Parameters

ws: *WebSocket

Possible Errors

AccessDenied ReadError

In WASI, this error occurs when the file descriptor does not hold the required rights to read from it.

BrokenPipe ReadError
Canceled ReadError

reading a timerfd with CANCEL_ON_SET will lead to this error when the clock goes through a discontinuous change

ConnectionClose
ConnectionResetByPeer ReadError
ConnectionTimedOut ReadError
EndOfStream RecvError
HttpChunkInvalid ReadError
HttpHeadersOversize ReadError
InputOutput ReadError
IsDir ReadError
LockViolation ReadError

Unable to read file due to lock.

MessageTooBig
MissingMaskBit
NotOpenForReading ReadError
OperationAborted ReadError
ProcessNotFound ReadError

This error occurs in Linux if the process to be read from no longer exists.

SocketNotConnected ReadError
SystemResources ReadError
Unexpected UnexpectedError

The Operating System returned an undocumented error code.

This error is in theory not possible, but it would be better to handle this error than to invoke undefined behavior.

When this error code is observed, it usually means the Zig Standard Library needs a small patch to add the error code to the error set for the respective function.

UnexpectedOpCode
WouldBlock ReadError

This error occurs when no global event loop is configured, and reading from the file descriptor would block.

Source

pub fn readSmallMessage(ws: *WebSocket) ReadSmallTextMessageError!SmallMessage { while (true) { const header_bytes = (try recv(ws, 2))[0..2]; const h0: Header0 = @bitCast(header_bytes[0]); const h1: Header1 = @bitCast(header_bytes[1]); switch (h0.opcode) { .text, .binary, .pong, .ping => {}, .connection_close => return error.ConnectionClose, .continuation => return error.UnexpectedOpCode, _ => return error.UnexpectedOpCode, } if (!h0.fin) return error.MessageTooBig; if (!h1.mask) return error.MissingMaskBit; const len: usize = switch (h1.payload_len) { .len16 => try recvReadInt(ws, u16), .len64 => std.math.cast(usize, try recvReadInt(ws, u64)) orelse return error.MessageTooBig, else => @intFromEnum(h1.payload_len), }; if (len > ws.recv_fifo.buf.len) return error.MessageTooBig; const mask: u32 = @bitCast((try recv(ws, 4))[0..4].*); const payload = try recv(ws, len); // Skip pongs. if (h0.opcode == .pong) continue; // The last item may contain a partial word of unused data. const floored_len = (payload.len / 4) * 4; const u32_payload: []align(1) u32 = @alignCast(std.mem.bytesAsSlice(u32, payload[0..floored_len])); for (u32_payload) |*elem| elem.* ^= mask; const mask_bytes = std.mem.asBytes(&mask)[0 .. payload.len - floored_len]; for (payload[floored_len..], mask_bytes) |*leftover, m| leftover.* ^= m; return .{ .opcode = h0.opcode, .data = payload, }; } }