Class: Faye::WebSocket::Protocol8Parser
- Inherits:
-
Object
- Object
- Faye::WebSocket::Protocol8Parser
- Defined in:
- lib/faye/util/web_socket/protocol8_parser.rb
Constant Summary
- GUID =
'258EAFA5-E914-47DA-95CA-C5AB0DC85B11'- FIN =
MASK = 0b10000000
- RSV1 =
0b01000000- RSV2 =
0b00100000- RSV3 =
0b00010000- OPCODE =
0b00001111- LENGTH =
0b01111111- OPCODES =
{ :continuation => 0, :text => 1, :binary => 2, :close => 8, :ping => 9, :pong => 10 }
- ERRORS =
{ :normal_closure => 1000, :going_away => 1001, :protocol_error => 1002, :unacceptable => 1003, :too_large => 1004, :encoding_error => 1007 }
Class Method Summary (collapse)
Instance Method Summary (collapse)
- - (Object) frame(data, type = nil, error_type = nil)
-
- (Protocol8Parser) initialize(web_socket)
constructor
A new instance of Protocol8Parser.
- - (Object) parse(data)
- - (Object) version
Constructor Details
- (Protocol8Parser) initialize(web_socket)
A new instance of Protocol8Parser
48 49 50 51 |
# File 'lib/faye/util/web_socket/protocol8_parser.rb', line 48 def initialize(web_socket) reset @socket = web_socket end |
Class Method Details
+ (Object) handshake(request)
35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/faye/util/web_socket/protocol8_parser.rb', line 35 def self.handshake(request) sec_key = request.env['HTTP_SEC_WEBSOCKET_KEY'] return '' unless String === sec_key accept = Base64.encode64(Digest::SHA1.digest(sec_key + GUID)).strip upgrade = "HTTP/1.1 101 Switching Protocols\r\n" upgrade << "Upgrade: websocket\r\n" upgrade << "Connection: Upgrade\r\n" upgrade << "Sec-WebSocket-Accept: #{accept}\r\n\r\n" upgrade end |
Instance Method Details
- (Object) frame(data, type = nil, error_type = nil)
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/faye/util/web_socket/protocol8_parser.rb', line 121 def frame(data, type = nil, error_type = nil) return nil if @closed if error_type data = [ERRORS[error_type]].pack('n') + data end opcode = OPCODES[type || :text] frame = (FIN | opcode).chr length = data.size case length when 0..125 then frame << length.chr when 126..65535 then frame << 126.chr frame << [length].pack('n') else frame << 127.chr frame << [length >> 32, length & 0xFFFFFFFF].pack('NN') end @socket.encode(frame, 'UTF-8') + @socket.encode(data, 'UTF-8') end |
- (Object) parse(data)
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/faye/util/web_socket/protocol8_parser.rb', line 57 def parse(data) byte0 = getbyte(data, 0) final = (byte0 & FIN) == FIN opcode = (byte0 & OPCODE) return close(:protocol_error) unless OPCODES.values.include?(opcode) reset unless opcode == OPCODES[:continuation] byte1 = getbyte(data, 1) masked = (byte1 & MASK) == MASK length = (byte1 & LENGTH) offset = 0 case length when 126 then length = integer(data, 2, 2) offset = 2 when 127 then length = integer(data, 2, 8) offset = 8 end if masked payload_offset = 2 + offset + 4 mask_octets = (0..3).map { |i| getbyte(data, 2 + offset + i) } else payload_offset = 2 + offset mask_octets = [] end return close(:too_large) if getbyte(data, payload_offset + length) raw_payload = data[payload_offset...(payload_offset + length)] payload = unmask(raw_payload, mask_octets) case opcode when OPCODES[:continuation] then return unless @mode == :text @buffer << payload if final = @buffer * '' reset @socket.receive() end when OPCODES[:text] then if final @socket.receive(payload) else @mode = :text @buffer << payload end when OPCODES[:binary] then close(:unacceptable) when OPCODES[:close] then close(:normal_closure) when OPCODES[:ping] then @socket.send(payload, :pong) end end |
- (Object) version
53 54 55 |
# File 'lib/faye/util/web_socket/protocol8_parser.rb', line 53 def version 'protocol-8' end |