diff options
| author | Benjamin Sanders <ben@Benjamins-MacBook-Pro.local> | 2025-10-11 10:34:24 -0400 |
|---|---|---|
| committer | Benjamin Sanders <ben@Benjamins-MacBook-Pro.local> | 2025-10-11 10:34:24 -0400 |
| commit | 5571dc766e2143e39762ff0b47c41d1c2e154f4c (patch) | |
| tree | f4f124d314a7e76c04484515aa0fd1f2e271a601 /vendor/bundle/ruby/3.4.0/gems/em-websocket-0.5.3/lib/em-websocket/framing76.rb | |
| parent | 359f3309c97fc894b63e0a295c76ab298504d635 (diff) | |
Vendor bundled gems for deployment
Diffstat (limited to 'vendor/bundle/ruby/3.4.0/gems/em-websocket-0.5.3/lib/em-websocket/framing76.rb')
| -rw-r--r-- | vendor/bundle/ruby/3.4.0/gems/em-websocket-0.5.3/lib/em-websocket/framing76.rb | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/vendor/bundle/ruby/3.4.0/gems/em-websocket-0.5.3/lib/em-websocket/framing76.rb b/vendor/bundle/ruby/3.4.0/gems/em-websocket-0.5.3/lib/em-websocket/framing76.rb new file mode 100644 index 0000000..55982ff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/em-websocket-0.5.3/lib/em-websocket/framing76.rb @@ -0,0 +1,105 @@ +# encoding: BINARY + +module EventMachine + module WebSocket + module Framing76 + def initialize_framing + @data = '' + end + + def process_data + debug [:message, @data] + + # This algorithm comes straight from the spec + # http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76#section-5.3 + + error = false + + while !error + return if @data.size == 0 + + pointer = 0 + frame_type = @data.getbyte(pointer) + pointer += 1 + + if (frame_type & 0x80) == 0x80 + # If the high-order bit of the /frame type/ byte is set + length = 0 + + loop do + return false if !@data.getbyte(pointer) + b = @data.getbyte(pointer) + pointer += 1 + b_v = b & 0x7F + length = length * 128 + b_v + break unless (b & 0x80) == 0x80 + end + + if length > @connection.max_frame_size + raise WSMessageTooBigError, "Frame length too long (#{length} bytes)" + end + + if @data.getbyte(pointer+length-1) == nil + debug [:buffer_incomplete, @data] + # Incomplete data - leave @data to accumulate + error = true + else + # Straight from spec - I'm sure this isn't crazy... + # 6. Read /length/ bytes. + # 7. Discard the read bytes. + @data = @data[(pointer+length)..-1] + + # If the /frame type/ is 0xFF and the /length/ was 0, then close + if length == 0 + @connection.send_data("\xff\x00") + @state = :closing + @connection.close_connection_after_writing + else + error = true + end + end + else + # If the high-order bit of the /frame type/ byte is _not_ set + + if @data.getbyte(0) != 0x00 + # Close the connection since this buffer can never match + raise WSProtocolError, "Invalid frame received" + end + + # Addition to the spec to protect against malicious requests + if @data.size > @connection.max_frame_size + raise WSMessageTooBigError, "Frame length too long (#{@data.size} bytes)" + end + + msg = @data.slice!(/\A\x00[^\xff]*\xff/) + if msg + msg.gsub!(/\A\x00|\xff\z/, '') + if @state == :closing + debug [:ignored_message, msg] + else + msg.force_encoding('UTF-8') if msg.respond_to?(:force_encoding) + @connection.trigger_on_message(msg) + end + else + error = true + end + end + end + + false + end + + # frames need to start with 0x00-0x7f byte and end with + # an 0xFF byte. Per spec, we can also set the first + # byte to a value betweent 0x80 and 0xFF, followed by + # a leading length indicator + def send_text_frame(data) + debug [:sending_text_frame, data] + ary = ["\x00", data, "\xff"] + ary.collect{ |s| s.force_encoding('UTF-8') if s.respond_to?(:force_encoding) } + @connection.send_data(ary.join) + end + + end + end +end
\ No newline at end of file |
