Web sockets fragments are supported (silly implementation).

master
Karchnu 2020-09-01 02:32:46 +02:00
parent af1c7e1875
commit b1ac2dacee
2 changed files with 35 additions and 5 deletions

View File

@ -38,7 +38,14 @@ class HTTP::WebSocket
record Pong
record Close
record Error
record NotFinal
# record NotFinal
struct NotFinal
property message : String
property info : Protocol::PacketInfo
def initialize(@message, @info)
end
end
# :nodoc:
def run_once : Bytes | String | Close | Ping | Pong | NotFinal | Error
@ -73,6 +80,8 @@ class HTTP::WebSocket
@on_message.try &.call(@current_message.to_s)
@current_message.clear
return String.new message
else
return NotFinal.new String.new(message), info
end
when Protocol::Opcode::BINARY
message = @buffer[0, info.size]
@ -93,7 +102,7 @@ class HTTP::WebSocket
end
end
return NotFinal.new
raise "what the fuck?"
end
# Returns the websocket instance.

View File

@ -290,15 +290,21 @@ def websocket_connection_procedure (requested_service : String, clientfd : Int32
end
end
class FragmentBuffer
property buffer : String = String.new
end
def websocket_switching_procedure (activefd : Int)
begin
Baguette::Log.title "activefd is #{activefd}"
if Context.context.is_client[activefd]
Baguette::Log.title "activefd #{activefd} is a client"
# Baguette::Log.title "activefd #{activefd} is a client"
# The client is a WebSocket on top of a TCP connection
client = Context.context.fd_to_tcpsocket[activefd]
wsclient = Context.context.fd_to_websocket[activefd]
fb = FragmentBuffer.new
loop do
begin
message = wsclient.run_once
@ -358,14 +364,18 @@ def websocket_switching_procedure (activefd : Int)
next
end
break
when WebSocket::NotFinal
Baguette::Log.warning "Received only part of a message (not supported)"
pp!
Baguette::Log.warning "Received only part of a message"
# TODO: check if the message is OK when multiplexing
# pp! message
fb.buffer = fb.buffer + message.message
if still_something_to_read
Baguette::Log.debug "Still something to read"
next
end
break
when Bytes
# TODO: when receiving a binary message
# we should test the format and maybe its content
@ -376,6 +386,17 @@ def websocket_switching_procedure (activefd : Int)
end
end
# In case there was a previous messagee within a fragment.
if fb.buffer.size > 0
Baguette::Log.warning "SHOULD reconstitute the message!!"
end
if message.is_a?(String) && fb.buffer.size > 0
Baguette::Log.warning "Reconstitute the message!!"
message = fb.buffer + message
fb.buffer = String.new
end
if Context.context.is_json[activefd] && message.is_a?(String)
if Context.print_messages
j = JSON.parse message