299 lines
7.9 KiB
Ruby
299 lines
7.9 KiB
Ruby
# encoding: BINARY
|
|
|
|
require 'helper'
|
|
|
|
describe EM::WebSocket::Framing03 do
|
|
class FramingContainer
|
|
include EM::WebSocket::Framing03
|
|
|
|
def initialize
|
|
@connection = Object.new
|
|
def @connection.max_frame_size
|
|
1000000
|
|
end
|
|
end
|
|
|
|
def <<(data)
|
|
@data << data
|
|
process_data
|
|
end
|
|
|
|
def debug(*args); end
|
|
end
|
|
|
|
before :each do
|
|
@f = FramingContainer.new
|
|
@f.initialize_framing
|
|
end
|
|
|
|
describe "basic examples" do
|
|
it "connection close" do
|
|
@f.should_receive(:message).with(:close, '', '')
|
|
@f << 0b00000001
|
|
@f << 0b00000000
|
|
end
|
|
|
|
it "ping" do
|
|
@f.should_receive(:message).with(:ping, '', '')
|
|
@f << 0b00000010
|
|
@f << 0b00000000
|
|
end
|
|
|
|
it "pong" do
|
|
@f.should_receive(:message).with(:pong, '', '')
|
|
@f << 0b00000011
|
|
@f << 0b00000000
|
|
end
|
|
|
|
it "text" do
|
|
@f.should_receive(:message).with(:text, '', 'foo')
|
|
@f << 0b00000100
|
|
@f << 0b00000011
|
|
@f << 'foo'
|
|
end
|
|
|
|
it "Text in two frames" do
|
|
@f.should_receive(:message).with(:text, '', 'hello world')
|
|
@f << 0b10000100
|
|
@f << 0b00000110
|
|
@f << "hello "
|
|
@f << 0b00000000
|
|
@f << 0b00000101
|
|
@f << "world"
|
|
end
|
|
|
|
it "2 byte extended payload length text frame" do
|
|
data = 'a' * 256
|
|
@f.should_receive(:message).with(:text, '', data)
|
|
@f << 0b00000100 # Single frame, text
|
|
@f << 0b01111110 # Length 126 (so read 2 bytes)
|
|
@f << 0b00000001 # Two bytes in network byte order (256)
|
|
@f << 0b00000000
|
|
@f << data
|
|
end
|
|
end
|
|
|
|
# These examples are straight from the spec
|
|
# http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-03#section-4.6
|
|
describe "examples from the spec" do
|
|
it "a single-frame text message" do
|
|
@f.should_receive(:message).with(:text, '', 'Hello')
|
|
@f << "\x04\x05Hello"
|
|
end
|
|
|
|
it "a fragmented text message" do
|
|
@f.should_receive(:message).with(:text, '', 'Hello')
|
|
@f << "\x84\x03Hel"
|
|
@f << "\x00\x02lo"
|
|
end
|
|
|
|
it "Ping request and response" do
|
|
@f.should_receive(:message).with(:ping, '', 'Hello')
|
|
@f << "\x02\x05Hello"
|
|
end
|
|
|
|
it "256 bytes binary message in a single frame" do
|
|
data = "a"*256
|
|
@f.should_receive(:message).with(:binary, '', data)
|
|
@f << "\x05\x7E\x01\x00" + data
|
|
end
|
|
|
|
it "64KiB binary message in a single frame" do
|
|
data = "a"*65536
|
|
@f.should_receive(:message).with(:binary, '', data)
|
|
@f << "\x05\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + data
|
|
end
|
|
end
|
|
|
|
describe "other tests" do
|
|
it "should accept a fragmented unmasked text message in 3 frames" do
|
|
@f.should_receive(:message).with(:text, '', 'Hello world')
|
|
@f << "\x84\x03Hel"
|
|
@f << "\x80\x02lo"
|
|
@f << "\x00\x06 world"
|
|
end
|
|
end
|
|
|
|
describe "error cases" do
|
|
it "should raise an exception on continuation frame without preceeding more frame" do
|
|
lambda {
|
|
@f << 0b00000000 # Single frame, continuation
|
|
@f << 0b00000001 # Length 1
|
|
@f << 'f'
|
|
}.should raise_error(EM::WebSocket::WebSocketError, 'Continuation frame not expected')
|
|
end
|
|
end
|
|
end
|
|
|
|
# These examples are straight from the spec
|
|
# http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-03#section-4.6
|
|
describe EM::WebSocket::Framing04 do
|
|
class FramingContainer04
|
|
include EM::WebSocket::Framing04
|
|
|
|
def initialize
|
|
@connection = Object.new
|
|
def @connection.max_frame_size
|
|
1000000
|
|
end
|
|
end
|
|
|
|
def <<(data)
|
|
@data << data
|
|
process_data
|
|
end
|
|
|
|
def debug(*args); end
|
|
end
|
|
|
|
before :each do
|
|
@f = FramingContainer04.new
|
|
@f.initialize_framing
|
|
end
|
|
|
|
describe "examples from the spec" do
|
|
it "a single-frame text message" do
|
|
@f.should_receive(:message).with(:text, '', 'Hello')
|
|
@f << "\x84\x05\x48\x65\x6c\x6c\x6f" # "\x84\x05Hello"
|
|
end
|
|
|
|
it "a fragmented text message" do
|
|
@f.should_receive(:message).with(:text, '', 'Hello')
|
|
@f << "\x04\x03Hel"
|
|
@f << "\x80\x02lo"
|
|
end
|
|
|
|
it "Ping request" do
|
|
@f.should_receive(:message).with(:ping, '', 'Hello')
|
|
@f << "\x82\x05Hello"
|
|
end
|
|
|
|
it "a pong response" do
|
|
@f.should_receive(:message).with(:pong, '', 'Hello')
|
|
@f << "\x83\x05Hello"
|
|
end
|
|
|
|
it "256 bytes binary message in a single frame" do
|
|
data = "a"*256
|
|
@f.should_receive(:message).with(:binary, '', data)
|
|
@f << "\x85\x7E\x01\x00" + data
|
|
end
|
|
|
|
it "64KiB binary message in a single frame" do
|
|
data = "a"*65536
|
|
@f.should_receive(:message).with(:binary, '', data)
|
|
@f << "\x85\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + data
|
|
end
|
|
end
|
|
|
|
describe "other tests" do
|
|
it "should accept a fragmented unmasked text message in 3 frames" do
|
|
@f.should_receive(:message).with(:text, '', 'Hello world')
|
|
@f << "\x04\x03Hel"
|
|
@f << "\x00\x02lo"
|
|
@f << "\x80\x06 world"
|
|
end
|
|
end
|
|
end
|
|
|
|
describe EM::WebSocket::Framing07 do
|
|
class FramingContainer07
|
|
include EM::WebSocket::Framing07
|
|
|
|
def initialize
|
|
@connection = Object.new
|
|
def @connection.max_frame_size
|
|
1000000
|
|
end
|
|
end
|
|
|
|
def <<(data)
|
|
@data << data
|
|
process_data
|
|
end
|
|
|
|
def debug(*args); end
|
|
end
|
|
|
|
before :each do
|
|
@f = FramingContainer07.new
|
|
@f.initialize_framing
|
|
end
|
|
|
|
# These examples are straight from the spec
|
|
# http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-07#section-4.6
|
|
describe "examples from the spec" do
|
|
it "a single-frame unmakedtext message" do
|
|
@f.should_receive(:message).with(:text, '', 'Hello')
|
|
@f << "\x81\x05\x48\x65\x6c\x6c\x6f" # "\x84\x05Hello"
|
|
end
|
|
|
|
it "a single-frame masked text message" do
|
|
@f.should_receive(:message).with(:text, '', 'Hello')
|
|
@f << "\x81\x85\x37\xfa\x21\x3d\x7f\x9f\x4d\x51\x58" # "\x84\x05Hello"
|
|
end
|
|
|
|
it "a fragmented unmasked text message" do
|
|
@f.should_receive(:message).with(:text, '', 'Hello')
|
|
@f << "\x01\x03Hel"
|
|
@f << "\x80\x02lo"
|
|
end
|
|
|
|
it "Ping request" do
|
|
@f.should_receive(:message).with(:ping, '', 'Hello')
|
|
@f << "\x89\x05Hello"
|
|
end
|
|
|
|
it "a pong response" do
|
|
@f.should_receive(:message).with(:pong, '', 'Hello')
|
|
@f << "\x8a\x05Hello"
|
|
end
|
|
|
|
it "256 bytes binary message in a single unmasked frame" do
|
|
data = "a"*256
|
|
@f.should_receive(:message).with(:binary, '', data)
|
|
@f << "\x82\x7E\x01\x00" + data
|
|
end
|
|
|
|
it "64KiB binary message in a single unmasked frame" do
|
|
data = "a"*65536
|
|
@f.should_receive(:message).with(:binary, '', data)
|
|
@f << "\x82\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + data
|
|
end
|
|
end
|
|
|
|
describe "other tests" do
|
|
it "should raise a WSProtocolError if an invalid frame type is requested" do
|
|
lambda {
|
|
# Opcode 3 is not supported by this draft
|
|
@f << "\x83\x05Hello"
|
|
}.should raise_error(EventMachine::WebSocket::WSProtocolError, "Unknown opcode 3")
|
|
end
|
|
|
|
it "should accept a fragmented unmasked text message in 3 frames" do
|
|
@f.should_receive(:message).with(:text, '', 'Hello world')
|
|
@f << "\x01\x03Hel"
|
|
@f << "\x00\x02lo"
|
|
@f << "\x80\x06 world"
|
|
end
|
|
|
|
it "should raise if non-fin frame is followed by a non-continuation data frame (continuation frame would be expected)" do
|
|
lambda {
|
|
@f << 0b00000001 # Not fin, text
|
|
@f << 0b00000001 # Length 1
|
|
@f << 'f'
|
|
@f << 0b10000001 # fin, text (continutation expected)
|
|
@f << 0b00000001 # Length 1
|
|
@f << 'b'
|
|
}.should raise_error(EM::WebSocket::WebSocketError, 'Continuation frame expected')
|
|
end
|
|
|
|
it "should raise on non-fin control frames (control frames must not be fragmented)" do
|
|
lambda {
|
|
@f << 0b00001010 # Not fin, pong (opcode 10)
|
|
@f << 0b00000000 # Length 1
|
|
}.should raise_error(EM::WebSocket::WebSocketError, 'Control frames must not be fragmented')
|
|
end
|
|
end
|
|
end
|