DoxigAlpha

respondWebSocket

The header is not guaranteed to be sent until WebSocket.flush is called on the returned struct.

Function parameters

Parameters

#
request:*Request

Type definitions in this namespace

Types

#
WebSocket
See https://tools.ietf.org/html/rfc6455

Initialize an HTTP server that can respond to multiple requests on the same

Functions

#
init
Initialize an HTTP server that can respond to multiple requests on the same

Error sets in this namespace

Error Sets

#

Source

Implementation

#
pub fn respondWebSocket(request: *Request, options: WebSocketOptions) ExpectContinueError!WebSocket {
    if (request.head.expect != null) return error.HttpExpectationFailed;

    const out = request.server.out;
    const version: http.Version = .@"HTTP/1.1";
    const status: http.Status = .switching_protocols;
    const phrase = options.reason orelse status.phrase() orelse "";

    assert(request.head.version == version);
    assert(request.head.method == .GET);

    var sha1 = std.crypto.hash.Sha1.init(.{});
    sha1.update(options.key);
    sha1.update("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
    var digest: [std.crypto.hash.Sha1.digest_length]u8 = undefined;
    sha1.final(&digest);
    try out.print("{s} {d} {s}\r\n", .{ @tagName(version), @intFromEnum(status), phrase });
    try out.writeAll("connection: upgrade\r\nupgrade: websocket\r\nsec-websocket-accept: ");
    const base64_digest = try out.writableArray(28);
    assert(std.base64.standard.Encoder.encode(base64_digest, &digest).len == base64_digest.len);
    try out.writeAll("\r\n");

    for (options.extra_headers) |header| {
        assert(header.name.len != 0);
        var bufs: [4][]const u8 = .{ header.name, ": ", header.value, "\r\n" };
        try out.writeVecAll(&bufs);
    }

    try out.writeAll("\r\n");

    return .{
        .input = request.server.reader.in,
        .output = request.server.out,
        .key = options.key,
    };
}