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.

Parameters:

  • the (String)

    string data to feed into the parser.

Returns:

  • (String, nil)

    the websocket message payload, if any, nil otherwise.



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