Class: WebSocket::Extensions
- Inherits:
-
Object
- Object
- WebSocket::Extensions
- Defined in:
- lib/websocket/extensions.rb,
lib/websocket/extensions/parser.rb
Defined Under Namespace
Constant Summary collapse
- ExtensionError =
Class.new(ArgumentError)
- MESSAGE_OPCODES =
[1, 2]
Instance Method Summary collapse
- #activate(header) ⇒ Object
- #add(ext) ⇒ Object
- #close ⇒ Object
- #generate_offer ⇒ Object
- #generate_response(header) ⇒ Object
-
#initialize ⇒ Extensions
constructor
A new instance of Extensions.
- #process_incoming_message(message) ⇒ Object
- #process_outgoing_message(message) ⇒ Object
- #valid_frame_rsv(frame) ⇒ Object (also: #valid_frame_rsv?)
Constructor Details
#initialize ⇒ Extensions
Returns a new instance of Extensions.
10 11 12 13 14 15 16 17 |
# File 'lib/websocket/extensions.rb', line 10 def initialize @rsv1 = @rsv2 = @rsv3 = nil @by_name = {} @in_order = [] @sessions = [] @index = {} end |
Instance Method Details
#activate(header) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/websocket/extensions.rb', line 75 def activate(header) responses = Parser.parse_header(header) @sessions = [] responses.each_offer do |name, params| unless record = @index[name] raise ExtensionError, %Q{Server sent am extension response for unknown extension "#{ name } } end ext, session = *record if reserved = reserved?(ext) raise ExtensionError, %Q{Server sent two extension responses that use the RSV#{ reserved[0] }} + %Q{bit: "#{ reserved[1] }" and "#{ ext.name }"} end unless session.activate(params) == true raise ExtensionError, %Q{Server send unacceptable extension parameters: #{ Parser.serialize_params(name, params) }} end reserve(ext) @sessions.push(record) end end |
#add(ext) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/websocket/extensions.rb', line 19 def add(ext) unless ext.respond_to?(:name) and ext.name.is_a?(String) raise TypeError, 'extension.name must be a string' end unless ext.respond_to?(:type) and ext.type == 'permessage' raise TypeError, 'extension.type must be "permessage"' end unless ext.respond_to?(:rsv1) and [true, false].include?(ext.rsv1) raise TypeError, 'extension.rsv1 must be true or false' end unless ext.respond_to?(:rsv2) and [true, false].include?(ext.rsv2) raise TypeError, 'extension.rsv2 must be true or false' end unless ext.respond_to?(:rsv3) and [true, false].include?(ext.rsv3) raise TypeError, 'extension.rsv3 must be true or false' end if @by_name.has_key?(ext.name) raise TypeError, %Q{An extension with name "#{ ext.name }" is already registered} end @by_name[ext.name] = ext @in_order.push(ext) end |
#close ⇒ Object
157 158 159 160 161 162 163 |
# File 'lib/websocket/extensions.rb', line 157 def close return unless @sessions @sessions.each do |ext, session| session.close rescue nil end end |
#generate_offer ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/websocket/extensions.rb', line 48 def generate_offer sessions = [] offer = [] index = {} @in_order.each do |ext| session = ext.create_client_session next unless session record = [ext, session] sessions.push(record) index[ext.name] = record offers = session.generate_offer offers = offers ? [offers].flatten : [] offers.each do |off| offer.push(Parser.serialize_params(ext.name, off)) end end @sessions = sessions @index = index offer.size > 0 ? offer.join(', ') : nil end |
#generate_response(header) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/websocket/extensions.rb', line 100 def generate_response(header) sessions = [] response = [] offers = Parser.parse_header(header) @in_order.each do |ext| offer = offers.by_name(ext.name) next if offer.empty? or reserved?(ext) next unless session = ext.create_server_session(offer) reserve(ext) sessions.push([ext, session]) response.push(Parser.serialize_params(ext.name, session.generate_response)) end @sessions = sessions response.size > 0 ? response.join(', ') : nil end |
#process_incoming_message(message) ⇒ Object
137 138 139 140 141 142 143 144 145 |
# File 'lib/websocket/extensions.rb', line 137 def () @sessions.reverse.inject() do |msg, (ext, session)| begin session.(msg) rescue => error raise ExtensionError, [ext.name, error.].join(': ') end end end |
#process_outgoing_message(message) ⇒ Object
147 148 149 150 151 152 153 154 155 |
# File 'lib/websocket/extensions.rb', line 147 def () @sessions.inject() do |msg, (ext, session)| begin session.(msg) rescue => error raise ExtensionError, [ext.name, error.].join(': ') end end end |
#valid_frame_rsv(frame) ⇒ Object Also known as: valid_frame_rsv?
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/websocket/extensions.rb', line 120 def valid_frame_rsv(frame) allowed = { :rsv1 => false, :rsv2 => false, :rsv3 => false } if MESSAGE_OPCODES.include?(frame.opcode) @sessions.each do |ext, session| allowed[:rsv1] ||= ext.rsv1 allowed[:rsv2] ||= ext.rsv2 allowed[:rsv3] ||= ext.rsv3 end end (allowed[:rsv1] || !frame.rsv1) && (allowed[:rsv2] || !frame.rsv2) && (allowed[:rsv3] || !frame.rsv3) end |