Class: Protocol::WebSocket::Frame

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/protocol/websocket/frame.rb

Overview

Represents a single WebSocket frame as defined by RFC 6455.

Constant Summary collapse

RSV1 =
0b0100
RSV2 =
0b0010
RSV3 =
0b0001
RESERVED =
RSV1 | RSV2 | RSV3
OPCODE =
0

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(finished = true, payload = nil, flags: 0, opcode: self.class::OPCODE, mask: false) ⇒ Frame

Returns a new instance of Frame.



25
26
27
28
29
30
31
32
33
34
35
# File 'lib/protocol/websocket/frame.rb', line 25

def initialize(finished = true, payload = nil, flags: 0, opcode: self.class::OPCODE, mask: false)
	if mask == true
		mask = SecureRandom.bytes(4)
	end
	
	@finished = finished
	@flags = flags
	@opcode = opcode
	@mask = mask
	@payload = payload
end

Instance Attribute Details

#finishedObject

The generic frame header uses the following binary representation:

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

-------------------------——————————-+ |F|R|R|R| opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16/64) | |N|V|V|V| |S| | (if payload len==126/127) | | |1|2|3| |K| | | ------------------------- - - - - - - - - - - - - - - - + | Extended payload length continued, if payload len == 127 | + - - - - - - - - - - - - - - - ------------------------------- | |Masking-key, if MASK set to 1 | -------------------------------——————————-+ | Masking-key (continued) | Payload Data | ——————————– - - - - - - - - - - - - - - - : Payload Data continued … : + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | Payload Data continued … | ---------------------------------------------------------------



101
102
103
# File 'lib/protocol/websocket/frame.rb', line 101

def finished
  @finished
end

#flagsObject

Returns the value of attribute flags.



102
103
104
# File 'lib/protocol/websocket/frame.rb', line 102

def flags
  @flags
end

#maskObject

Returns the value of attribute mask.



104
105
106
# File 'lib/protocol/websocket/frame.rb', line 104

def mask
  @mask
end

#opcodeObject

Returns the value of attribute opcode.



103
104
105
# File 'lib/protocol/websocket/frame.rb', line 103

def opcode
  @opcode
end

#payloadObject

Returns the value of attribute payload.



105
106
107
# File 'lib/protocol/websocket/frame.rb', line 105

def payload
  @payload
end

Instance Method Details

#<=>(other) ⇒ Object

Compare this frame to another frame by their array representation.



47
48
49
# File 'lib/protocol/websocket/frame.rb', line 47

def <=> other
	to_ary <=> other.to_ary
end

#apply(connection) ⇒ Object

Apply this frame to the connection by dispatching it to the appropriate handler.



166
167
168
# File 'lib/protocol/websocket/frame.rb', line 166

def apply(connection)
	connection.receive_frame(self)
end

#continued?Boolean

Check whether this frame is a continuation fragment (FIN bit not set).

Returns:

  • (Boolean)


76
77
78
# File 'lib/protocol/websocket/frame.rb', line 76

def continued?
	@finished == false
end

#control?Boolean

Check whether this is a control frame (opcode has bit 3 set).

Returns:

  • (Boolean)


59
60
61
# File 'lib/protocol/websocket/frame.rb', line 59

def control?
	@opcode & 0x8 != 0
end

#data?Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/protocol/websocket/frame.rb', line 64

def data?
	false
end

#finished?Boolean

Check whether this is the final frame in a message.

Returns:

  • (Boolean)


70
71
72
# File 'lib/protocol/websocket/frame.rb', line 70

def finished?
	@finished == true
end

#flag?(value) ⇒ Boolean

Check whether the specified RSV flag bit is set on this frame.

Returns:

  • (Boolean)


40
41
42
# File 'lib/protocol/websocket/frame.rb', line 40

def flag?(value)
	@flags & value != 0
end

#lengthObject

The byte length of the payload.



109
110
111
# File 'lib/protocol/websocket/frame.rb', line 109

def length
	@payload&.bytesize
end

#pack(data = "") ⇒ Object

Pack the given data into this frame’s payload, applying masking if configured.



140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/protocol/websocket/frame.rb', line 140

def pack(data = "")
	if data.bytesize.bit_length > 63
		raise ProtocolError, "Frame length #{data.bytesize} bigger than allowed maximum!"
	end
	
	if @mask
		@payload = mask_xor(data, @mask)
	else
		@payload = data
	end
	
	return self
end

#to_aryObject

Convert this frame to an array of its fields for comparison or inspection.



53
54
55
# File 'lib/protocol/websocket/frame.rb', line 53

def to_ary
	[@finished, @flags, @opcode, @mask, @payload]
end

#unpackObject

Unpack the raw payload, removing masking if present.



156
157
158
159
160
161
162
# File 'lib/protocol/websocket/frame.rb', line 156

def unpack
	if @mask and !@payload.empty?
		return mask_xor(@payload, @mask)
	else
		return @payload
	end
end