filestoraged/src/server/main-loop.cr

120 lines
3.8 KiB
Crystal
Raw Normal View History

2020-01-02 09:21:11 +01:00
Context.service = IPC::Service.new Context.service_name
Context.service.not_nil!.loop do |event|
case event
when IPC::Event::Timer
puts "#{CORANGE}IPC::Event::Timer#{CRESET}"
when IPC::Event::Connection
puts "#{CBLUE}IPC::Event::Connection: #{event.connection.fd}#{CRESET}"
when IPC::Event::Disconnection
puts "#{CBLUE}IPC::Event::Disconnection: #{event.connection.fd}#{CRESET}"
Context.connected_users.select! do |fd, uid|
fd != event.connection.fd
end
when IPC::Event::ExtraSocket
puts "#{CRED}IPC::Event::ExtraSocket: should not happen in this service#{CRESET}"
when IPC::Event::Switch
puts "#{CRED}IPC::Event::Switch: should not happen in this service#{CRESET}"
# IPC::Event::Message has to be the last entry
# because ExtraSocket and Switch inherit from Message class
when IPC::Event::Message
puts "#{CBLUE}IPC::Event::Message#{CRESET}: #{event.connection.fd}"
# The first message sent to the server has to be the AuthenticationMessage.
# Users sent their token (JWT) to authenticate themselves.
# The token contains the user id, its login and a few other parameters.
# (see the authd documentation).
# TODO: for now, the token is replaced by a hardcoded one, for debugging
mtype = FileStorage::MessageType.new event.message.type.to_i32
# First, the user has to be authenticated unless we are receiving its first message
userid = Context.connected_users[event.connection.fd]?
2020-01-04 10:45:39 +01:00
# if the user is not yet connected but does not try to perform authentication
if ! userid && mtype != FileStorage::MessageType::Authentication
# TODO: replace this with an Error message?
mid = "no message id"
response = FileStorage::Response.new mid, "Not OK", "Action on non connected user"
do_response event, response
2020-01-02 09:21:11 +01:00
end
case mtype
when .authentication?
puts "Receiving an authentication message"
# 1. test if the client is already authenticated
if userid
user = Context.users_status[userid]
raise "Authentication message while the user was already connected: this should not happen"
else
puts "User is not currently connected"
hdl_authentication event
end
when .upload_request?
puts "Upload request"
request = FileStorage::UploadRequest.from_json(
2020-01-02 09:21:11 +01:00
String.new event.message.payload
)
response = hdl_upload request, Context.users_status[userid], event
do_response event, response
2020-01-02 09:21:11 +01:00
when .download_request?
puts "Download request"
request = FileStorage::DownloadRequest.from_json(
2020-01-02 09:21:11 +01:00
String.new event.message.payload
)
response = hdl_download request, Context.users_status[userid], event
do_response event, response
2020-01-02 09:21:11 +01:00
when .response?
puts "Response message"
raise "not implemented yet"
when .responses?
puts "Responses message"
raise "not implemented yet"
when .error?
puts "Error message"
raise "not implemented yet"
when .transfer?
# throw an error if the user isn't recorded
unless user = Context.users_status[userid]?
raise "The user isn't recorded in the users_status structure"
end
transfer = FileStorage::Transfer.from_json(
2020-01-02 09:21:11 +01:00
String.new event.message.payload
)
response = hdl_transfer transfer, Context.users_status[userid], event
do_response event, response
2020-01-02 09:21:11 +01:00
end
else
raise "Event type not supported."
end
2020-01-04 10:45:39 +01:00
rescue e
puts "A problem occured : #{e.message}"
2020-01-02 09:21:11 +01:00
end
def do_response(event : IPC::Event::Message,
response : FileStorage::Message)
case response
when FileStorage::Response
event.connection.send FileStorage::MessageType::Response.to_u8, response.to_json
when FileStorage::Responses
event.connection.send FileStorage::MessageType::Responses.to_u8, response.to_json
when FileStorage::Error
event.connection.send FileStorage::MessageType::Error.to_u8, response.to_json
else
puts "response should not happen: #{response}"
pp! response
end
end