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