AnyEvent-WebSocket-Server

 view release on metacpan or  search on metacpan

t/error.t  view on Meta::CPAN

            shutdown $server_fh, 2;
            undef $server_fh;
            $handle->push_shutdown();
            $cv_client_finish->recv;
        }else {
            my $server_handle = AnyEvent::Handle->new(
                fh => $server_fh,
                on_error => sub { fail("server handle error: $_[2]") },
            );
            my $send_response =
                "HTTP/1.1 404 Not Found\r\n" .
                "Connection: close\r\n" .
                "Content-Type: text/plain\r\n" .
                "Content-Length: 9\r\n" .
                "\r\n".
                "Not Found";
            $server_handle->push_write($send_response);
            $server_handle->push_shutdown();
            $cv_client_finish->recv;

            is($got_response, $send_response, "server fh remains intact in this case, so the server can send a valid HTTP response.");
        }
    }
);

establish_error_case(
    label => "client sends a totally irrelevant message, but won't close the connection actively.",
    skip => "because the request parser (external module) is not very strict",
    code => sub {
        my ($cv_finish, $port, $cconfig) = @_;
        my $got_response = "";
        my $cv_client_finish = AnyEvent->condvar;
        my $handle = AnyEvent::Handle->new(
            $cconfig->client_handle_args($port),
            on_error => sub { fail("client handle error: $_[2]") },
            on_connect => sub {
                my ($handle) = @_;
                $handle->push_write("hogehoge");
            },
            on_read => sub {
                my ($handle) = @_;
                $got_response .= $handle->{rbuf};
                $handle->{rbuf} = "";
            },
            on_eof => sub { $cv_client_finish->send },
        );
        my ($server_error, $server_fh) = $cv_finish->recv;
        pass("server establishment should fail");
        
        close($server_fh); ## is it ok just closing the socket even if TLS session is active on it?
        $cv_client_finish->recv;
        is($got_response, "", "server shuts down the connection without sending any data.");
    }
);

## No test for the case "client closes the connection right after
## sending the whole handshake request", because in this case the
## server thinks that the WebSocket connection is established, but
## disconnected immediately.

subtest "After handshake, client disconnects while sending a frame", sub {
    testlib::ConnConfig->for_all_ok_conn_configs(sub {
        my ($cconfig) = @_;
        
        my $server = AnyEvent::WebSocket::Server->new($cconfig->server_args);
        my @got_messages = ();
        my $cv_finish = AnyEvent->condvar;
        my $cv_port = start_server sub {
            my ($fh) = @_;
            $server->establish($fh)->cb(sub {
                my ($conn) = shift->recv;
                $conn->on(each_message => sub {
                    my ($conn, $msg) = @_;
                    push(@got_messages, $msg->body);
                });
                $conn->on(finish => sub {
                    undef $conn;
                    $cv_finish->send;
                });
            });
        };
        my $port = $cv_port->recv;
    
        my $hs = Protocol::WebSocket::Handshake::Client->new(url => $cconfig->connect_url($port, "/"));
        my $client = AnyEvent::Handle->new(
            $cconfig->client_handle_args($port),
            on_error => sub { fail("client handle error: $_[2]") },
            on_connect => sub {
                my ($handle) = @_;
                $handle->push_write($hs->to_string);
            },
            on_read => sub {
                my ($handle) = @_;
                if(!$hs->is_done) {
                    $hs->parse($handle->{rbuf});
                    if($hs->is_done) {
                        $handle->push_write(Protocol::WebSocket::Frame->new("Hello, ")->to_bytes);
                        my $world_frame = Protocol::WebSocket::Frame->new("world!")->to_bytes;
                        $handle->push_write(substr($world_frame, 0, 4)); ## partial message
                        $handle->push_shutdown();
                    }
                    return;
                }
                fail("No server sent frame should be received.");
            },
            on_eof => sub {
                note("client disconnected gracefully");
            },
        );

        $cv_finish->recv;
        is_deeply(\@got_messages, ["Hello, "], "only the first message should be received. the partial message should be discarded.");
    });
};

done_testing;



( run in 1.421 second using v1.01-cache-2.11-cpan-2398b32b56e )