Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
slightly more consistent style
  • Loading branch information
kraih committed Jan 9, 2016
1 parent 3a4cc39 commit 71516d1
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 95 deletions.
16 changes: 1 addition & 15 deletions lib/Mojo/Transaction/WebSocket.pm
Expand Up @@ -2,18 +2,11 @@ package Mojo::Transaction::WebSocket;
use Mojo::Base 'Mojo::Transaction';

use Compress::Raw::Zlib 'Z_SYNC_FLUSH';
use Config;
use List::Util 'first';
use Mojo::JSON qw(encode_json j);
use Mojo::Transaction::HTTP;
use Mojo::Util qw(decode encode trim);
use Mojo::WebSocket qw(build_frame);

use constant DEBUG => $ENV{MOJO_WEBSOCKET_DEBUG} || 0;

# Perl with support for quads
use constant MODERN =>
(($Config{use64bitint} // '') eq 'define' || $Config{longsize} >= 8);
use Mojo::WebSocket 'build_frame';

# Opcodes
use constant {
Expand Down Expand Up @@ -498,13 +491,6 @@ Negotiate C<permessage-deflate> extension for this WebSocket connection.
Negotiate subprotocol for this WebSocket connection.
=head1 DEBUGGING
You can set the C<MOJO_WEBSOCKET_DEBUG> environment variable to get some
advanced diagnostics information printed to C<STDERR>.
MOJO_WEBSOCKET_DEBUG=1
=head1 SEE ALSO
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicious.org>.
Expand Down
14 changes: 7 additions & 7 deletions lib/Mojo/WebSocket.pm
@@ -1,22 +1,22 @@
package Mojo::WebSocket;
use Mojo::Base -strict;

use Exporter 'import';
use Config;
use Exporter 'import';
use Mojo::Util qw(b64_encode sha1_bytes xor_encode);

our @EXPORT_OK
= qw(build_frame challenge client_handshake parse_frame server_handshake);
use constant DEBUG => $ENV{MOJO_WEBSOCKET_DEBUG} || 0;

# Unique value from RFC 6455
use constant GUID => '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';

use constant DEBUG => $ENV{MOJO_WEBSOCKET_DEBUG} || 0;

# Perl with support for quads
use constant MODERN =>
(($Config{use64bitint} // '') eq 'define' || $Config{longsize} >= 8);

our @EXPORT_OK
= qw(build_frame challenge client_handshake parse_frame server_handshake);

sub build_frame {
my ($masked, $fin, $rsv1, $rsv2, $rsv3, $op, $payload) = @_;
warn "-- Building frame ($fin, $rsv1, $rsv2, $rsv3, $op)\n" if DEBUG;
Expand Down Expand Up @@ -86,7 +86,7 @@ sub client_handshake {
}

sub parse_frame {
my ($buffer, $max_websocket_size) = @_;
my ($buffer, $max) = @_;

# Head
return undef unless length $$buffer >= 2;
Expand Down Expand Up @@ -126,7 +126,7 @@ sub parse_frame {
}

# Check message size
return 1 if $len > $max_websocket_size;
return 1 if $len > $max;

# Check if whole packet has arrived
$len += 4 if my $masked = $second & 0b10000000;
Expand Down
120 changes: 47 additions & 73 deletions t/mojo/websocket_frames.t
Expand Up @@ -5,107 +5,92 @@ use Mojo::Transaction::WebSocket;
use Mojo::WebSocket qw(build_frame parse_frame);

# Simple text frame roundtrip
my $ws = Mojo::Transaction::WebSocket->new;
my $bytes = build_frame $ws->masked, 1, 0, 0, 0, 1, 'whatever';
my $bytes = build_frame 0, 1, 0, 0, 0, 1, 'whatever';
is $bytes, "\x81\x08\x77\x68\x61\x74\x65\x76\x65\x72", 'right frame';
my $frame = parse_frame \(my $dummy = $bytes), $ws->max_websocket_size;
my $frame = parse_frame \(my $dummy = $bytes), 262144;
is $frame->[0], 1, 'fin flag is set';
is $frame->[1], 0, 'rsv1 flag is not set';
is $frame->[2], 0, 'rsv2 flag is not set';
is $frame->[3], 0, 'rsv3 flag is not set';
is $frame->[4], 1, 'text frame';
is $frame->[5], 'whatever', 'right payload';
is build_frame($ws->masked, 1, 0, 0, 0, 1, 'whatever'), $bytes,
'frames are equal';
is build_frame(0, 1, 0, 0, 0, 1, 'whatever'), $bytes, 'frames are equal';

# Simple text frame roundtrip with all flags set
$ws = Mojo::Transaction::WebSocket->new;
$bytes = build_frame $ws->masked, 1, 1, 1, 1, 1, 'whatever';
$bytes = build_frame 0, 1, 1, 1, 1, 1, 'whatever';
is $bytes, "\xf1\x08\x77\x68\x61\x74\x65\x76\x65\x72", 'right frame';
$frame = parse_frame \($dummy = $bytes), $ws->max_websocket_size;
$frame = parse_frame \($dummy = $bytes), 262144;
is $frame->[0], 1, 'fin flag is set';
is $frame->[1], 1, 'rsv1 flag is set';
is $frame->[2], 1, 'rsv2 flag is set';
is $frame->[3], 1, 'rsv3 flag is set';
is $frame->[4], 1, 'text frame';
is $frame->[5], 'whatever', 'right payload';
is build_frame($ws->masked, 1, 1, 1, 1, 1, 'whatever'), $bytes,
'frames are equal';
is build_frame(0, 1, 1, 1, 1, 1, 'whatever'), $bytes, 'frames are equal';

# Simple text frame roundtrip without FIN bit
$ws = Mojo::Transaction::WebSocket->new;
$bytes = build_frame $ws->masked, 0, 0, 0, 0, 1, 'whatever';
$bytes = build_frame 0, 0, 0, 0, 0, 1, 'whatever';
is $bytes, "\x01\x08\x77\x68\x61\x74\x65\x76\x65\x72", 'right frame';
$frame = parse_frame \($dummy = $bytes), $ws->max_websocket_size;
$frame = parse_frame \($dummy = $bytes), 262144;
is $frame->[0], 0, 'fin flag is not set';
is $frame->[1], 0, 'rsv1 flag is not set';
is $frame->[2], 0, 'rsv2 flag is not set';
is $frame->[3], 0, 'rsv3 flag is not set';
is $frame->[4], 1, 'text frame';
is $frame->[5], 'whatever', 'right payload';
is build_frame($ws->masked, 0, 0, 0, 0, 1, 'whatever'), $bytes,
'frames are equal';
is build_frame(0, 0, 0, 0, 0, 1, 'whatever'), $bytes, 'frames are equal';

# Simple text frame roundtrip with RSV1 flags set
$ws = Mojo::Transaction::WebSocket->new;
$bytes = build_frame($ws->masked, 1, 1, 0, 0, 1, 'whatever');
$bytes = build_frame(0, 1, 1, 0, 0, 1, 'whatever');
is $bytes, "\xc1\x08\x77\x68\x61\x74\x65\x76\x65\x72", 'right frame';
$frame = parse_frame \($dummy = $bytes), $ws->max_websocket_size;
$frame = parse_frame \($dummy = $bytes), 262144;
is $frame->[0], 1, 'fin flag is set';
is $frame->[1], 1, 'rsv1 flag is set';
is $frame->[2], 0, 'rsv2 flag is not set';
is $frame->[3], 0, 'rsv3 flag is not set';
is $frame->[4], 1, 'text frame';
is $frame->[5], 'whatever', 'right payload';
is build_frame($ws->masked, 1, 1, 0, 0, 1, 'whatever'), $bytes,
'frames are equal';
is build_frame(0, 1, 1, 0, 0, 1, 'whatever'), $bytes, 'frames are equal';

# Simple text frame roundtrip with RSV2 flags set
$ws = Mojo::Transaction::WebSocket->new;
$bytes = build_frame($ws->masked, 1, 0, 1, 0, 1, 'whatever');
$bytes = build_frame(0, 1, 0, 1, 0, 1, 'whatever');
is $bytes, "\xa1\x08\x77\x68\x61\x74\x65\x76\x65\x72", 'right frame';
$frame = parse_frame \($dummy = $bytes), $ws->max_websocket_size;
$frame = parse_frame \($dummy = $bytes), 262144;
is $frame->[0], 1, 'fin flag is set';
is $frame->[1], 0, 'rsv1 flag is not set';
is $frame->[2], 1, 'rsv2 flag is set';
is $frame->[3], 0, 'rsv3 flag is not set';
is $frame->[4], 1, 'text frame';
is $frame->[5], 'whatever', 'right payload';
is build_frame($ws->masked, 1, 0, 1, 0, 1, 'whatever'), $bytes,
'frames are equal';
is build_frame(0, 1, 0, 1, 0, 1, 'whatever'), $bytes, 'frames are equal';

# Simple text frame roundtrip with RSV3 flags set
$ws = Mojo::Transaction::WebSocket->new;
$bytes = build_frame($ws->masked, 1, 0, 0, 1, 1, 'whatever');
$bytes = build_frame(0, 1, 0, 0, 1, 1, 'whatever');
is $bytes, "\x91\x08\x77\x68\x61\x74\x65\x76\x65\x72", 'right frame';
$frame = parse_frame \($dummy = $bytes), $ws->max_websocket_size;
$frame = parse_frame \($dummy = $bytes), 262144;
is $frame->[0], 1, 'fin flag is set';
is $frame->[1], 0, 'rsv1 flag is not set';
is $frame->[2], 0, 'rsv2 flag is not set';
is $frame->[3], 1, 'rsv3 flag is set';
is $frame->[4], 1, 'text frame';
is $frame->[5], 'whatever', 'right payload';
is build_frame($ws->masked, 1, 0, 0, 1, 1, 'whatever'), $bytes,
'frames are equal';
is build_frame(0, 1, 0, 0, 1, 1, 'whatever'), $bytes, 'frames are equal';

# Simple binary frame roundtrip
$ws = Mojo::Transaction::WebSocket->new;
$bytes = build_frame($ws->masked, 1, 0, 0, 0, 2, 'works');
$bytes = build_frame(0, 1, 0, 0, 0, 2, 'works');
is $bytes, "\x82\x05\x77\x6f\x72\x6b\x73", 'right frame';
$frame = parse_frame \($dummy = $bytes), $ws->max_websocket_size;
$frame = parse_frame \($dummy = $bytes), 262144;
is $frame->[0], 1, 'fin flag is set';
is $frame->[1], 0, 'rsv1 flag is not set';
is $frame->[2], 0, 'rsv2 flag is not set';
is $frame->[3], 0, 'rsv3 flag is not set';
is $frame->[4], 2, 'binary frame';
is $frame->[5], 'works', 'right payload';
is $bytes = build_frame($ws->masked, 1, 0, 0, 0, 2, 'works'), $bytes,
'frames are equal';
is $bytes = build_frame(0, 1, 0, 0, 0, 2, 'works'), $bytes, 'frames are equal';

# Masked text frame roundtrip
$ws = Mojo::Transaction::WebSocket->new(masked => 1);
$bytes = build_frame $ws->masked, 1, 0, 0, 0, 1, 'also works';
$frame = parse_frame \($dummy = $bytes), $ws->max_websocket_size;
$bytes = build_frame 1, 1, 0, 0, 0, 1, 'also works';
$frame = parse_frame \($dummy = $bytes), 262144;
is $frame->[0], 1, 'fin flag is set';
is $frame->[1], 0, 'rsv1 flag is not set';
is $frame->[2], 0, 'rsv2 flag is not set';
Expand All @@ -116,9 +101,8 @@ isnt(build_frame(0, 1, 0, 0, 0, 2, 'also works'),
$bytes, 'frames are not equal');

# Masked binary frame roundtrip
$ws = Mojo::Transaction::WebSocket->new(masked => 1);
$bytes = build_frame($ws->masked, 1, 0, 0, 0, 2, 'just works');
$frame = parse_frame \($dummy = $bytes), $ws->max_websocket_size;
$bytes = build_frame(1, 1, 0, 0, 0, 2, 'just works');
$frame = parse_frame \($dummy = $bytes), 262144;
is $frame->[0], 1, 'fin flag is set';
is $frame->[1], 0, 'rsv1 flag is not set';
is $frame->[2], 0, 'rsv2 flag is not set';
Expand All @@ -129,91 +113,81 @@ isnt(build_frame(0, 1, 0, 0, 0, 2, 'just works'),
$bytes, 'frames are not equal');

# One-character text frame roundtrip
$ws = Mojo::Transaction::WebSocket->new;
$bytes = build_frame($ws->masked, 1, 0, 0, 0, 1, 'a');
$bytes = build_frame(0, 1, 0, 0, 0, 1, 'a');
is $bytes, "\x81\x01\x61", 'right frame';
$frame = parse_frame \($dummy = $bytes), $ws->max_websocket_size;
$frame = parse_frame \($dummy = $bytes), 262144;
is $frame->[0], 1, 'fin flag is set';
is $frame->[1], 0, 'rsv1 flag is not set';
is $frame->[2], 0, 'rsv2 flag is not set';
is $frame->[3], 0, 'rsv3 flag is not set';
is $frame->[4], 1, 'text frame';
is $frame->[5], 'a', 'right payload';
is build_frame($ws->masked, 1, 0, 0, 0, 1, 'a'), $bytes, 'frames are equal';
is build_frame(0, 1, 0, 0, 0, 1, 'a'), $bytes, 'frames are equal';

# One-byte binary frame roundtrip
$ws = Mojo::Transaction::WebSocket->new;
$bytes = build_frame($ws->masked, 1, 0, 0, 0, 2, 'a');
$bytes = build_frame(0, 1, 0, 0, 0, 2, 'a');
is $bytes, "\x82\x01\x61", 'right frame';
$frame = parse_frame \($dummy = $bytes), $ws->max_websocket_size;
$frame = parse_frame \($dummy = $bytes), 262144;
is $frame->[0], 1, 'fin flag is set';
is $frame->[1], 0, 'rsv1 flag is not set';
is $frame->[2], 0, 'rsv2 flag is not set';
is $frame->[3], 0, 'rsv3 flag is not set';
is $frame->[4], 2, 'binary frame';
is $frame->[5], 'a', 'right payload';
is $bytes = build_frame($ws->masked, 1, 0, 0, 0, 2, 'a'), $bytes,
'frames are equal';
is $bytes = build_frame(0, 1, 0, 0, 0, 2, 'a'), $bytes, 'frames are equal';

# 16-bit text frame roundtrip
$ws = Mojo::Transaction::WebSocket->new;
$bytes = build_frame($ws->masked, 1, 0, 0, 0, 1, 'hi' x 10000);
$bytes = build_frame(0, 1, 0, 0, 0, 1, 'hi' x 10000);
is $bytes, "\x81\x7e\x4e\x20" . ("\x68\x69" x 10000), 'right frame';
$frame = parse_frame \($dummy = $bytes), $ws->max_websocket_size;
$frame = parse_frame \($dummy = $bytes), 262144;
is $frame->[0], 1, 'fin flag is set';
is $frame->[1], 0, 'rsv1 flag is not set';
is $frame->[2], 0, 'rsv2 flag is not set';
is $frame->[3], 0, 'rsv3 flag is not set';
is $frame->[4], 1, 'text frame';
is $frame->[5], 'hi' x 10000, 'right payload';
is build_frame($ws->masked, 1, 0, 0, 0, 1, 'hi' x 10000), $bytes,
'frames are equal';
is build_frame(0, 1, 0, 0, 0, 1, 'hi' x 10000), $bytes, 'frames are equal';

# 64-bit text frame roundtrip
$ws = Mojo::Transaction::WebSocket->new(max_websocket_size => 500000);
$bytes = build_frame($ws->masked, 1, 0, 0, 0, 1, 'hi' x 200000);
$bytes = build_frame(0, 1, 0, 0, 0, 1, 'hi' x 200000);
is $bytes, "\x81\x7f\x00\x00\x00\x00\x00\x06\x1a\x80" . ("\x68\x69" x 200000),
'right frame';
$frame = parse_frame \($dummy = $bytes), $ws->max_websocket_size;
$frame = parse_frame \($dummy = $bytes), 500000;
is $frame->[0], 1, 'fin flag is set';
is $frame->[1], 0, 'rsv1 flag is not set';
is $frame->[2], 0, 'rsv2 flag is not set';
is $frame->[3], 0, 'rsv3 flag is not set';
is $frame->[4], 1, 'text frame';
is $frame->[5], 'hi' x 200000, 'right payload';
is build_frame($ws->masked, 1, 0, 0, 0, 1, 'hi' x 200000), $bytes,
'frames are equal';
is build_frame(0, 1, 0, 0, 0, 1, 'hi' x 200000), $bytes, 'frames are equal';

# Empty text frame roundtrip
$ws = Mojo::Transaction::WebSocket->new;
$bytes = build_frame($ws->masked, 1, 0, 0, 0, 1, '');
$bytes = build_frame(0, 1, 0, 0, 0, 1, '');
is $bytes, "\x81\x00", 'right frame';
$frame = parse_frame \($dummy = $bytes), $ws->max_websocket_size;
$frame = parse_frame \($dummy = $bytes), 262144;
is $frame->[0], 1, 'fin flag is set';
is $frame->[1], 0, 'rsv1 flag is not set';
is $frame->[2], 0, 'rsv2 flag is not set';
is $frame->[3], 0, 'rsv3 flag is not set';
is $frame->[4], 1, 'text frame';
is $frame->[5], '', 'no payload';
is build_frame($ws->masked, 1, 0, 0, 0, 1, ''), $bytes, 'frames are equal';
is build_frame(0, 1, 0, 0, 0, 1, ''), $bytes, 'frames are equal';

# Empty close frame roundtrip
$ws = Mojo::Transaction::WebSocket->new;
$bytes = build_frame($ws->masked, 1, 0, 0, 0, 8, '');
$bytes = build_frame(0, 1, 0, 0, 0, 8, '');
is $bytes, "\x88\x00", 'right frame';
$frame = parse_frame \($dummy = $bytes), $ws->max_websocket_size;
$frame = parse_frame \($dummy = $bytes), 262144;
is $frame->[0], 1, 'fin flag is set';
is $frame->[1], 0, 'rsv1 flag is not set';
is $frame->[2], 0, 'rsv2 flag is not set';
is $frame->[3], 0, 'rsv3 flag is not set';
is $frame->[4], 8, 'close frame';
is $frame->[5], '', 'no payload';
is build_frame($ws->masked, 1, 0, 0, 0, 8, ''), $bytes, 'frames are equal';
is build_frame(0, 1, 0, 0, 0, 8, ''), $bytes, 'frames are equal';

# Masked empty binary frame roundtrip
$ws = Mojo::Transaction::WebSocket->new(masked => 1);
$bytes = build_frame($ws->masked, 1, 0, 0, 0, 2, '');
$frame = parse_frame \($dummy = $bytes), $ws->max_websocket_size;
$bytes = build_frame(1, 1, 0, 0, 0, 2, '');
$frame = parse_frame \($dummy = $bytes), 262144;
is $frame->[0], 1, 'fin flag is set';
is $frame->[1], 0, 'rsv1 flag is not set';
is $frame->[2], 0, 'rsv2 flag is not set';
Expand All @@ -223,9 +197,9 @@ is $frame->[5], '', 'no payload';
isnt(build_frame(0, 1, 0, 0, 0, 2, ''), $bytes, 'frames are not equal');

# Compressed binary message roundtrip
$ws = Mojo::Transaction::WebSocket->new({compressed => 1});
my $ws = Mojo::Transaction::WebSocket->new({compressed => 1});
$bytes = $ws->build_message({binary => 'just works'});
$frame = parse_frame \($dummy = $bytes), $ws->max_websocket_size;
$frame = parse_frame \($dummy = $bytes), 262144;
is $frame->[0], 1, 'fin flag is set';
is $frame->[1], 1, 'rsv1 flag is set';
is $frame->[2], 0, 'rsv2 flag is not set';
Expand Down

0 comments on commit 71516d1

Please sign in to comment.