websocketd bugfix: removing the right fd.

master
Karchnu 2020-08-31 03:58:20 +02:00
parent 8ede5bea3d
commit fca1b29a47
1 changed files with 53 additions and 27 deletions

View File

@ -82,19 +82,23 @@ class InstanceStorage
def remove_fd (fdclient : Int32)
Baguette::Log.info "closing the client:#{CRESET} #{fdclient}"
# 1. closing both the client and the service
begin
tcpfdc = @fd_to_tcpsocket[fdclient]
if fdclient == -1
raise "fdclient is -1, nothing to do with it"
end
# 2. closing the TCP connections
tcpfdc.close unless tcpfdc.closed?
begin
# 1. closing both the client and the service
tcpfdc = @fd_to_tcpsocket[fdclient]
# 2. closing the TCP connections
tcpfdc.close unless tcpfdc.closed?
rescue e
Baguette::Log.error "remove_fd: 1 #{e}"
end
# 3. removing the client and the service fds from the loop check
begin
@service.remove_fd (fdclient)
@service.remove_fd (fdclient)
rescue e
Baguette::Log.error "remove_fd: 2 #{e}"
end
@ -117,8 +121,9 @@ class InstanceStorage
if fdservice.nil?
Baguette::Log.debug "client #{fdclient} aleady has its service removed"
else
service = @fd_to_ipcclient[fdservice]
@service.remove_fd (fdservice)
service = @fd_to_ipcclient[fdservice]
@fd_to_ipcclient = @fd_to_ipcclient.select do |k, v|
k != fdservice
end
@ -243,6 +248,7 @@ def websocket_client_connection(client)
end
def closing_client (fdclient : Int)
Baguette::Log.warning "Closing client #{fdclient}"
Context.context.remove_fd fdclient
end
@ -273,22 +279,25 @@ def websocket_connection_procedure (requested_service : String, clientfd : Int32
Context.context.is_client[clientfd] = true
Context.context.is_client[new_service_fd] = false
rescue e
puts "#{CRED}Exception during connection to the service:#{CRESET} #{e}"
Baguette::Log.error "Exception during connection to the service: #{e}"
Context.context.remove_fd clientfd
end
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"
# 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]
loop do
begin
message = wsclient.run_once
rescue e
puts "#{CRED}Exception (receiving a message)#{CRESET} #{e}"
Baguette::Log.error "Exception (receiving a message) #{e}"
Context.context.remove_fd activefd
return
end
@ -297,42 +306,59 @@ def websocket_switching_procedure (activefd : Int)
still_something_to_read = ! wsclient.ws.io.empty?
if wsclient.closed?
# puts "#{CBLUE}client is closed#{CRESET}"
Context.context.remove_fd client.fd
Baguette::Log.error "client #{activefd} is closed"
Context.context.remove_fd activefd
return
end
if message.nil?
puts "#{CRED}message is nil#{CRESET}"
Context.context.remove_fd client.fd
Baguette::Log.error "message received from #{activefd} is nil"
Context.context.remove_fd activefd
return
end
case message
when WebSocket::Error
puts "#{CRED}An error occured#{CRESET}"
Context.context.remove_fd client.fd
Baguette::Log.error "An error occured with client #{activefd}"
Context.context.remove_fd activefd
return
when WebSocket::Ping
# puts "#{CBLUE}Received a ping message#{CRESET}"
next if still_something_to_read
Baguette::Log.warning "Received a ping message"
if still_something_to_read
Baguette::Log.info "Still something to read"
next
end
break
when WebSocket::Pong
# puts "#{CBLUE}Received a pong message#{CRESET}"
next if still_something_to_read
Baguette::Log.warning "Received a pong message"
if still_something_to_read
Baguette::Log.info "Still something to read"
next
end
break
when WebSocket::Close
# puts "#{CBLUE}Received a close message#{CRESET}"
Context.context.remove_fd client.fd
Baguette::Log.warning "Received a close message"
Context.context.remove_fd activefd
if still_something_to_read
Baguette::Log.info "Still something to read"
next
end
return
when WebSocket::NotFinal
# puts "#{CBLUE}Received only part of a message#{CRESET}"
next if still_something_to_read
Baguette::Log.warning "Received only part of a message"
if still_something_to_read
Baguette::Log.info "Still something to read"
next
end
break
when Bytes
# TODO: when receiving a binary message
# we should test the format and maybe its content
# puts "#{CBLUE}Received a binary message#{CRESET}"
Baguette::Log.warning "Received a binary message"
if still_something_to_read
Baguette::Log.info "Still something to read"
next
end
end
if Context.context.is_json[activefd] && message.is_a?(String)
@ -379,7 +405,7 @@ def websocket_switching_procedure (activefd : Int)
wsclient.send buf
end
rescue e
puts "#{CRED}Exception during message transfer:#{CRESET} #{e}"
Baguette::Log.error "Exception during message transfer: #{e}"
if Context.context.is_client[activefd]
closing_client activefd
else
@ -394,11 +420,11 @@ def sending_ping_messages
begin
ws.ping "hello from #{fd}"
rescue e
puts "#{CRED}Exception: #{e}#{CRESET}, already closed client #{fd}"
Baguette::Log.error "#{CRED}Exception: #{e}#{CRESET}, already closed client #{fd}"
begin
Context.context.remove_fd fd
rescue e
puts "#{CRED}Cannot remove #{fd} from clients: #{e}#{CRESET}"
Baguette::Log.error "#{CRED}Cannot remove #{fd} from clients: #{e}#{CRESET}"
end
end
end