AnyEvent-WebSocket-Server

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

0.08    2016-08-11
        - No functional change from 0.07.
        - TLS tests are now optional. They are run when Net::SSLeay and AnyEvent::TLS are installed.

0.071   2016-08-07
        No functional change from 0.07.
        CPAN somehow failed to publish 0.07. So I just bumped the version and uploaded it again.

0.07    2016-08-06
        [ENHANCEMENT]
        - Add "ssl_key_file" and "ssl_cert_file" options.
          Now this module officially supports TLS (gh #2 by izarraga)
          
        [PACKAGING]
        - Require AnyEvent::WebSocket::Client 0.35. It has a bug fix for TLS mode.

0.06    2015-10-27
        [ENHANCEMENT]
        - add "handshake" option. (gh#1 by mephinet)

0.05    2014-08-17

MANIFEST  view on Meta::CPAN

Build.PL
Changes
cpanfile
lib/AnyEvent/WebSocket/Server.pm
MANIFEST			This list of files
t/00-load.t
t/connetion_active_close.t
t/data/ssl_test.combined.key
t/data/ssl_test.crt
t/data/ssl_test.key
t/echo.t
t/error.t
t/handshake.t
t/max_payload_size.t
t/multiple_connections.t
t/psgi_corona.t
t/psgi_twiggy.t
t/support_script/gen_ssl_keys.sh
t/testlib/ConnConfig.pm
t/testlib/PSGI.pm
t/testlib/Util.pm
t/tls_error.t
t/validator.t
TODO
xt/browser.t
xt/handshake_example.t
xt/js/browser.html
xt/manifest.t

lib/AnyEvent/WebSocket/Server.pm  view on Meta::CPAN

        croak "validator parameter must be a code-ref";
    }
    my $handshake = defined($args{handshake}) ? $args{handshake}
        : defined($validator) ? sub { my ($req, $res) = @_; return ($res, $validator->($req)); }
        : sub { $_[1] };
    if(ref($handshake) ne "CODE") {
        croak "handshake parameter must be a code-ref";
    }
    my $self = bless {
        handshake => $handshake,
        map { ($_ => $args{$_}) } qw(ssl_key_file ssl_cert_file max_payload_size),
    }, $class;
    return $self;
}

sub _create_on_error {
    my ($cv) = @_;
    return sub {
        my ($handle, $fatal, $message) = @_;
        if($fatal) {
            $cv->croak("connection error: $message");
        }else {
            warn $message;
        }
    };
}

sub _handle_args_tls {
    my ($self) = @_;
    if(!defined($self->{ssl_key_file}) && !defined($self->{ssl_cert_file})) {
        return ();
    }
    if(!defined($self->{ssl_cert_file})) {
        croak "Only ssl_key_file is specified. You need to specify ssl_cert_file, too.";
    }
    return (
        tls => "accept",
        tls_ctx => {
            cert_file => $self->{ssl_cert_file},
            defined($self->{ssl_key_file}) ? (key_file => $self->{ssl_key_file}) : ()
        }
    );
}

sub _do_handshake {
    my ($self, $cv_connection, $fh, $handshake) = @_;
    my $handshake_code = $self->{handshake};
    my $handle = AnyEvent::Handle->new(
        $self->_handle_args_tls,
        fh => $fh, on_error => _create_on_error($cv_connection)

lib/AnyEvent/WebSocket/Server.pm  view on Meta::CPAN


    @other_results = $validator->($request)

where C<$request> is a L<Protocol::WebSocket::Request> object.

If you reject the C<$request>, throw an exception.

If you accept the C<$request>, don't throw any exception.
The return values of the C<$validator> are sent to the condition variable of C<establish()> method.

=item C<ssl_key_file> => FILE_PATH (optional)

A string of the filepath to the SSL/TLS private key file in PEM format.
If you set this option, you have to set C<ssl_cert_file> option, too.

If this option or C<ssl_cert_file> option is set, L<AnyEvent::WebSocket::Server> encrypts the WebSocket streams with SSL/TLS.

=item C<ssl_cert_file> => FILE_PATH (optional)

A string of the filepath to the SSL/TLS certificate file in PEM format.

The file may contain both the certificate and corresponding private key. In that case, C<ssl_key_file> may be omitted.

If this option is set, L<AnyEvent::WebSocket::Server> encrypts the WebSocket streams with SSL/TLS.

=item C<max_payload_size> => INT (optional)

The maximum payload size for received frames. Currently defaults to whatever L<Protocol::WebSocket> defaults to.
Note that payload size for sent frames are not limited.

=back

t/support_script/gen_ssl_keys.sh  view on Meta::CPAN

#!/bin/sh

this_dir=`dirname $0`

keybase="$1"

if [ "x$keybase" = "x" ]; then
    keybase="ssl_test"
fi

if [ -r "$keybase.key" ]; then
    echo "$keybase.key already exists. abort."
    exit 1
fi

if [ -r "$keybase.crt" ]; then
    echo "$keybase.crt already exists. abort."
    exit 1
fi

config_file="$this_dir/cert_config"

echo "Generating $keybase.key"
openssl genrsa 3072 > $keybase.key

csrC=JP
csrST=Kanagawa
csrO=Acme
csrCN="127.0.0.1"
echo "Generating $keybase.crt"
openssl req -new -key $keybase.key \
        -subj "/C=$csrC/ST=$csrST/L=/O=$csrO/OU=/CN=$csrCN/emailAddress=" \
    | openssl x509 -days 100000 -req -signkey $keybase.key > $keybase.crt

echo "Generating $keybase.combined.key"
cat $keybase.key $keybase.crt > $keybase.combined.key

t/testlib/ConnConfig.pm  view on Meta::CPAN

            client_args => [],
            client_handle_base => [],
            scheme => "ws",
            address => "127.0.0.1"
        ),
        
        $class->_new(
            label => "conn:wss, separate",
            is_ok => 1,
            server_args => [
                ssl_key_file => "t/data/ssl_test.key",
                ssl_cert_file => "t/data/ssl_test.crt"
            ],
            client_args => [
                ssl_ca_file => "t/data/ssl_test.crt"
            ],
            client_handle_base => [
                tls => "connect",
                tls_ctx => {
                    ca_file => "t/data/ssl_test.crt"
                }
            ],
            scheme => "wss",
            address => "127.0.0.1",
        ),
        
        $class->_new(
            label => "conn:wss, combined",
            is_ok => 1,
            server_args => [
                ssl_cert_file => "t/data/ssl_test.combined.key",
            ],
            client_args => [
                ssl_ca_file => "t/data/ssl_test.crt"
            ],
            client_handle_base => [
                tls => "connect",
                tls_ctx => {
                    ca_file => "t/data/ssl_test.crt"
                }
            ],
            scheme => "wss",
            address => "127.0.0.1"
        ),

        $class->_new(
            label => "client: tls, server: plain",
            is_ok => 0,
            server_args => [],
            client_args => [
                ssl_ca_file => "t/data/ssl_test.crt"
            ],
            client_handle_base => [
                tls => "connect",
                tls_ctx => {
                    ca_file => "t/data/ssl_test.crt"
                }
            ],
            scheme => "wss",
            address => "127.0.0.1",
        ),

        $class->_new(
            label => "client: plain, server: tls",
            is_ok => 0,
            server_args => [
                ssl_cert_file => "t/data/ssl_test.combined.key",
            ],
            client_args => [],
            client_handle_base => [],
            scheme => "ws",
            address => "127.0.0.1"
        ),
    );
}

my $optional_module_diaged = 0;

t/testlib/ConnConfig.pm  view on Meta::CPAN

sub connect_url {
    my ($self, $port, $path) = @_;
    my $port_str = defined($port) ? ":$port" : "";
    my $path_str = defined($path) ? $path : "";
    return qq{$self->{scheme}://$self->{address}$port_str$path_str};
}

sub is_plain_socket_transport {
    my ($self) = @_;
    my %server_args = $self->server_args;
    return ($self->{scheme} eq "ws" && !defined($server_args{ssl_cert_file}) && !defined($server_args{ssl_key_file}));
}

1;



( run in 1.059 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )