EV-Websockets

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

        - on_handshake: server callback for per-connection response headers
          and connection rejection (403)
        - send_fragment: streaming fragmented writes (NO_FIN/CONTINUATION)
        - stash: per-connection metadata hashref
        - on_drain: callback when send queue empties
        - send_queue_size: query pending send bytes
        - connect_timeout: deadline for WebSocket handshake
        - Server protocol parameter on listen()
        - Broader client response header capture (Sec-WebSocket-Protocol,
          Location, WWW-Authenticate)
        - Server-side X-Forwarded-For in on_connect headers
        - O(1) fd watcher lookup (flat array indexed by fd)
        - Single-alloc send queue nodes (FAM)
        - adopt() holds IO handle reference (prevents premature fd closure)
        - TLS listener support (LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)

0.01    2026-02-20
        - Initial release.

README  view on Meta::CPAN

            on_error    => sub { my ($conn, $err) = @_; ... },
            on_pong     => sub { my ($conn, $payload) = @_; ... },
            on_drain    => sub { my ($conn) = @_; ... },
        );

    "protocol" sets the WebSocket subprotocol name advertised by the server
    vhost. The vhost name "default" is reserved and will croak if used.

    $headers in "on_connect" is a hashref of client request headers (Path,
    Host, Origin, Cookie, Authorization, Sec-WebSocket-Protocol, User-Agent,
    X-Forwarded-For). "Path" is the request URI (e.g., "/chat").

    "headers" is an optional hashref of headers to inject into the HTTP
    upgrade response (e.g., "Set-Cookie").

    "on_handshake" fires before the 101 response is sent (at
    "LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION"). It receives a hashref of
    request headers (same keys as "on_connect"). Return a hashref to inject
    per-connection response headers into the upgrade response. Return a
    false value ("undef", 0, "") to reject the connection (the client
    receives a 403).

Websockets.xs  view on Meta::CPAN

typedef struct { enum lws_token_indexes tok; const char *name; STRLEN nlen; } header_def_t;

static const header_def_t request_hdrs[] = {
    { WSI_TOKEN_GET_URI, "Path", 4 },
    { WSI_TOKEN_HOST, "Host", 4 },
    { WSI_TOKEN_ORIGIN, "Origin", 6 },
    { WSI_TOKEN_HTTP_COOKIE, "Cookie", 6 },
    { WSI_TOKEN_HTTP_AUTHORIZATION, "Authorization", 13 },
    { WSI_TOKEN_PROTOCOL, "Sec-WebSocket-Protocol", 22 },
    { WSI_TOKEN_HTTP_USER_AGENT, "User-Agent", 10 },
    { WSI_TOKEN_X_FORWARDED_FOR, "X-Forwarded-For", 15 },
};
#define N_REQUEST_HDRS (int)(sizeof(request_hdrs)/sizeof(request_hdrs[0]))

static void capture_request_headers(struct lws *wsi, HV *hv) {
    int i;
    for (i = 0; i < N_REQUEST_HDRS; i++)
        capture_header(wsi, hv, request_hdrs[i].tok,
                       request_hdrs[i].name, request_hdrs[i].nlen);
}

lib/EV/Websockets.pm  view on Meta::CPAN

        on_error    => sub { my ($conn, $err) = @_; ... },
        on_pong     => sub { my ($conn, $payload) = @_; ... },
        on_drain    => sub { my ($conn) = @_; ... },
    );

C<protocol> sets the WebSocket subprotocol name advertised by the server vhost.
The vhost name C<default> is reserved and will croak if used.

C<$headers> in C<on_connect> is a hashref of client request headers
(Path, Host, Origin, Cookie, Authorization, Sec-WebSocket-Protocol,
User-Agent, X-Forwarded-For).
C<Path> is the request URI (e.g., C</chat>).

C<headers> is an optional hashref of headers to inject into the HTTP upgrade
response (e.g., C<Set-Cookie>).

C<on_handshake> fires before the 101 response is sent
(at C<LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION>). It receives a hashref of
request headers (same keys as C<on_connect>). Return a hashref to inject
per-connection response headers into the upgrade response. Return a false
value (C<undef>, C<0>, C<"">) to reject the connection (the client receives

t/18-new-features.t  view on Meta::CPAN

            on_connect => sub { },
            on_message => sub { },
        );
        $listen_ok = $port > 0;
    };

    ok($listen_ok, "listen() with protocol parameter succeeds");
    ok(!$@, "no error setting protocol on listen()");
}

# 9. X-Forwarded-For -- requires proxy, skip
SKIP: {
    skip "X-Forwarded-For test requires proxy setup", 1;
    ok(0, "placeholder");
}

done_testing;

POSIX::_exit(Test::More->builder->is_passing ? 0 : 1);



( run in 1.030 second using v1.01-cache-2.11-cpan-13bb782fe5a )