Class: FTW::WebSocket::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/ftw/websocket/parser.rb

Overview

This class implements a parser for WebSocket messages over a stream.

Protocol diagram copied from RFC6455

 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 ...                |
+---------------------------------------------------------------+

Example use:

socket = FTW::Connection.new("example.com:80")
parser = FTW::WebSocket::Parser.new
# ... do HTTP Upgrade request to websockets
loop do
  data = socket.sysread(4096)
  payload = parser.feed(data)
  if payload
    # We got a full websocket frame, print the payload.
    p :payload => payload
  end
end

Constant Summary collapse

STATES =

States are based on the minimal unit of ‘byte’

[ :flags_and_opcode, :mask_and_payload_init, :payload_length, :payload ]

Instance Method Summary collapse

Instance Method Details

#feed(data) ⇒ String?

Feed data to this parser.

Currently, it will return the raw payload of websocket messages. Otherwise, it returns nil if no complete message has yet been consumed.



77
78
79
80
81
82
83
84
85
# File 'lib/ftw/websocket/parser.rb', line 77

def feed(data)
  @buffer << data
  while have?(@need)
    value = send(@state)
    # Return if our state yields a value.
    yield value if !value.nil? and block_given?
  end
  return nil
end