EV-Websockets

 view release on metacpan or  search on metacpan

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

    if (ref $headers_ref eq 'HASH') {
        diag "Client response headers: " . join(', ', sort keys %$headers_ref);
    }
}

# 6. close(code) without reason
{
    my $ctx = EV::Websockets::Context->new();
    my ($cli_close_code, $cli_closed);
    my %keep;

    my $port = $ctx->listen(
        port => 0,
        on_connect => sub { $keep{srv} = $_[0] },
        on_message => sub {
            my ($c) = @_;
            # Server closes with code only, no reason
            $c->close(1001);
        },
        on_close => sub { delete $keep{srv} },
    );

    my $t = EV::timer(0.1, 0, sub {
        $keep{cli} = $ctx->connect(
            url => "ws://127.0.0.1:$port",
            on_connect => sub { $_[0]->send("trigger") },
            on_close => sub {
                my ($c, $code, $reason) = @_;
                $cli_close_code = $code;
                $cli_closed = 1;
                delete $keep{cli};
                my $t; $t = EV::timer(0.3, 0, sub { undef $t; EV::break });
            },
            on_error => sub { delete $keep{cli}; EV::break },
        );
    });

    my $to = EV::timer(10, 0, sub { diag "Timeout!"; EV::break });
    EV::run;

    ok($cli_closed, "client saw close when server calls close(1001) without reason");
    ok(defined $cli_close_code, "client received a close code (got: " . ($cli_close_code // 'undef') . ")");
}

# 7. die inside on_message callback does not crash
{
    my $ctx = EV::Websockets::Context->new();
    my ($msg_after_die, $connection_survived);
    my %keep;

    my $srv_msg_count = 0;
    my $port = $ctx->listen(
        port => 0,
        on_connect => sub { $keep{srv} = $_[0] },
        on_message => sub {
            my ($c, $data) = @_;
            $srv_msg_count++;
            $c->send("echo:$data");
            if ($srv_msg_count == 1) {
                # Send retry immediately — the client's die in on_message
                # is caught by G_EVAL, so the connection stays alive
                $c->send("retry");
            }
        },
        on_close => sub { delete $keep{srv} },
    );

    my $phase = 0;
    $keep{cli} = $ctx->connect(
        url => "ws://127.0.0.1:$port",
        on_connect => sub { $_[0]->send("first") },
        on_message => sub {
            my ($c, $data) = @_;
            if ($phase == 0) {
                $phase = 1;
                die "test exception in on_message";
            } elsif ($phase == 1) {
                $msg_after_die = $data;
                $connection_survived = 1;
                $c->close(1000);
            }
        },
        on_close => sub {
            delete $keep{cli};
            EV::break;
        },
        on_error => sub { delete $keep{cli}; EV::break },
    );

    my $to = EV::timer(10, 0, sub { diag "Timeout!"; EV::break });
    EV::run;

    ok($connection_survived, "connection survived die inside on_message");
    is($msg_after_die, "retry", "received message after die in callback");
}

# 8. Server protocol parameter
{
    my $ctx = EV::Websockets::Context->new();
    my $listen_ok;

    eval {
        my $port = $ctx->listen(
            port     => 0,
            protocol => 'my-protocol',
            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");
}



( run in 0.652 second using v1.01-cache-2.11-cpan-14f38c9f855 )