FileStorage::Message is now a class that messages inherit from.

dev
Philippe PITTOLI 2020-01-04 15:07:04 +01:00
parent a2393848af
commit c4fe6e0ec7
5 changed files with 149 additions and 120 deletions

View File

@ -6,8 +6,6 @@ require "base64"
require "../common/filestorage.cr" require "../common/filestorage.cr"
alias FM = FileStorage::Message
# TODO # TODO
# For now, this example only upload files. # For now, this example only upload files.
# In a near future, we should be able to download files, too. # In a near future, we should be able to download files, too.
@ -17,7 +15,7 @@ service_name = "filestorage"
files_and_directories_to_transfer = Array(String).new files_and_directories_to_transfer = Array(String).new
# This is the requests we will send to the server # This is the requests we will send to the server
upload_requests = Array(FM::UploadRequest).new upload_requests = Array(FileStorage::UploadRequest).new
OptionParser.parse do |parser| OptionParser.parse do |parser|
@ -68,7 +66,7 @@ files_and_directories_to_transfer.each do |f|
end end
files_info.values.each do |file_info| files_info.values.each do |file_info|
upload_requests << FM::UploadRequest.new file_info upload_requests << FileStorage::UploadRequest.new file_info
end end
# pp! upload_requests # pp! upload_requests
@ -84,7 +82,7 @@ client = IPC::Client.new service_name
# #
token = FileStorage::Token.new 1002, "karchnu" token = FileStorage::Token.new 1002, "karchnu"
authentication_message = FM::Authentication.new token, upload_requests authentication_message = FileStorage::Authentication.new token, upload_requests
pp! authentication_message pp! authentication_message
client.send FileStorage::MessageType::Authentication.to_u8, authentication_message.to_json client.send FileStorage::MessageType::Authentication.to_u8, authentication_message.to_json
@ -96,7 +94,7 @@ m = client.read
# puts "message received: #{m.to_s}" # puts "message received: #{m.to_s}"
# puts "message received payload: #{String.new m.payload}" # puts "message received payload: #{String.new m.payload}"
response = FM::Response.from_json(String.new m.payload) response = FileStorage::Response.from_json(String.new m.payload)
if response.mid == authentication_message.mid if response.mid == authentication_message.mid
puts "This is a response for the authentication message" puts "This is a response for the authentication message"
@ -118,7 +116,7 @@ def file_transfer(client : IPC::Client, file : File, file_info : FileStorage::Fi
while (size = file.read(buffer)) > 0 while (size = file.read(buffer)) > 0
# transfer message = file_info, chunk count, data (will be base64'd) # transfer message = file_info, chunk count, data (will be base64'd)
transfer_message = FM::Transfer.new file_info, counter, buffer[0 ... size] transfer_message = FileStorage::Transfer.new file_info, counter, buffer[0 ... size]
client.send FileStorage::MessageType::Transfer.to_u8, transfer_message.to_json client.send FileStorage::MessageType::Transfer.to_u8, transfer_message.to_json
counter += 1 counter += 1
@ -134,7 +132,7 @@ def file_transfer(client : IPC::Client, file : File, file_info : FileStorage::Fi
raise "Message received was not expected: #{mtype}" raise "Message received was not expected: #{mtype}"
end end
response = FM::Response.from_json(String.new m.payload) response = FileStorage::Response.from_json(String.new m.payload)
if response.mid != transfer_message.mid if response.mid != transfer_message.mid
raise "Message received has a wrong mid: #{response.mid} != #{transfer_message.mid}" raise "Message received has a wrong mid: #{response.mid} != #{transfer_message.mid}"

View File

@ -90,10 +90,11 @@ module FileStorage
end end
class Message class Message
end
alias Request = UploadRequest | DownloadRequest alias Request = UploadRequest | DownloadRequest
class UploadRequest class UploadRequest < Message
JSON.mapping({ JSON.mapping({
# autogenerated # autogenerated
mid: String, mid: String,
@ -107,7 +108,7 @@ module FileStorage
# WIP # WIP
class DownloadRequest class DownloadRequest < Message
JSON.mapping({ JSON.mapping({
# autogenerated # autogenerated
mid: String, mid: String,
@ -122,7 +123,7 @@ module FileStorage
end end
end end
class Authentication class Authentication < Message
JSON.mapping({ JSON.mapping({
# autogenerated # autogenerated
mid: String, mid: String,
@ -136,7 +137,7 @@ module FileStorage
end end
end end
class Response class Response < Message
JSON.mapping({ JSON.mapping({
mid: String, mid: String,
response: String, response: String,
@ -147,7 +148,7 @@ module FileStorage
end end
end end
class Error class Error < Message
JSON.mapping({ JSON.mapping({
mid: String, mid: String,
# a response for each request # a response for each request
@ -159,7 +160,7 @@ module FileStorage
end end
end end
class Responses class Responses < Message
JSON.mapping({ JSON.mapping({
mid: String, mid: String,
# a response for each request # a response for each request
@ -172,7 +173,7 @@ module FileStorage
end end
end end
class Transfer class Transfer < Message
JSON.mapping({ JSON.mapping({
# autogenerated # autogenerated
mid: String, mid: String,
@ -193,7 +194,6 @@ module FileStorage
@mid = UUID.random.to_s @mid = UUID.random.to_s
end end
end end
end
# private function # private function
def data_digest(data : Bytes) def data_digest(data : Bytes)

View File

@ -4,9 +4,12 @@
class User class User
property uid : Int32 property uid : Int32
property token : FileStorage::Token property token : FileStorage::Token
property requests : Array(FileStorage::Message::Request)? property uploads : Array(FileStorage::UploadRequest)
property downloads : Array(FileStorage::DownloadRequest)
def initialize(@token, @requests = nil) def initialize(@token,
@uploads = Array(FileStorage::UploadRequest).new,
@downloads = Array(FileStorage::DownloadRequest).new)
@uid = token.uid @uid = token.uid
end end
end end

View File

@ -3,63 +3,76 @@ require "dodb"
require "base64" require "base64"
# reception of a file chunk # reception of a file chunk
def hdl_transfer(message : FileStorage::Message::Transfer, def hdl_transfer(message : FileStorage::Transfer,
user : User, user : User,
event : IPC::Event::Message) : FileStorage::Message::Response event : IPC::Event::Message) : FileStorage::Response
puts "receiving a file" puts "receiving a file"
transfer_message = FileStorage::Message::Transfer.from_json( mid = message.mid
String.new event.message.payload mid ||= "no message id"
)
pp! transfer_message # pp! transfer_message
file_info = user.uploads.select do |v|
v.file.digest == message.filedigest
end.first.file
pp! file_info
# TODO: verify the digest
# TODO: store the file
# TODO: register the file, with its tags
# puts "chunk: #{transfer_message.chunk}" # puts "chunk: #{transfer_message.chunk}"
# puts "data: #{Base64.decode transfer_message.data}" # puts "data: #{Base64.decode transfer_message.data}"
FileStorage::Message::Response.new message.mid, "Ok" FileStorage::Response.new mid, "Ok"
rescue e
puts "Error handling transfer: #{e.message}"
FileStorage::Response.new mid.not_nil!, "Not Ok", "Unexpected error: #{e.message}"
end end
# TODO # TODO
# the client sent an upload request # the client sent an upload request
def hdl_upload(request : FileStorage::Message::UploadRequest, def hdl_upload(request : FileStorage::UploadRequest,
user : User, user : User,
event : IPC::Event::Message) : FileStorage::Message::Response event : IPC::Event::Message) : FileStorage::Response
puts "hdl upload: mid=#{request.mid}" puts "hdl upload: mid=#{request.mid}"
pp! request pp! request
FileStorage::Message::Response.new request.mid, "Upload OK" FileStorage::Response.new request.mid, "Upload OK"
end end
# TODO # TODO
# the client sent a download request # the client sent a download request
def hdl_download(request : FileStorage::Message::DownloadRequest, def hdl_download(request : FileStorage::DownloadRequest,
user : User, user : User,
event : IPC::Event::Message) : FileStorage::Message::Response event : IPC::Event::Message) : FileStorage::Response
puts "hdl download: mid=#{request.mid}" puts "hdl download: mid=#{request.mid}"
pp! request pp! request
FileStorage::Message::Response.new request.mid, "Download OK" FileStorage::Response.new request.mid, "Download OK"
end end
# Entry point for request management # Entry point for request management
# Each request should have a response. # Each request should have a response.
# Then, responses are sent in a single message. # Then, responses are sent in a single message.
def hdl_requests(requests : Array(FileStorage::Message::Request), def hdl_requests(requests : Array(FileStorage::Request),
user : User, user : User,
event : IPC::Event::Message) : Array(FileStorage::Message::Response) event : IPC::Event::Message) : Array(FileStorage::Response)
puts "hdl request" puts "hdl request"
responses = Array(FileStorage::Message::Response).new responses = Array(FileStorage::Response).new
requests.each do |request| requests.each do |request|
case request case request
when FileStorage::Message::DownloadRequest when FileStorage::DownloadRequest
responses << hdl_download request, user, event responses << hdl_download request, user, event
when FileStorage::Message::UploadRequest when FileStorage::UploadRequest
responses << hdl_upload request, user, event responses << hdl_upload request, user, event
else else
raise "request not understood" raise "request not understood"
@ -78,7 +91,7 @@ end
def hdl_authentication(event : IPC::Event::Message) def hdl_authentication(event : IPC::Event::Message)
authentication_message = authentication_message =
FileStorage::Message::Authentication.from_json( FileStorage::Authentication.from_json(
String.new event.message.payload String.new event.message.payload
) )
@ -98,7 +111,8 @@ def hdl_authentication(event : IPC::Event::Message)
# AuthenticationMessage includes requests. # AuthenticationMessage includes requests.
new_user = new_user =
User.new authentication_message.token, User.new authentication_message.token,
[ authentication_message.uploads, authentication_message.downloads ].flatten authentication_message.uploads,
authentication_message.downloads
Context.connected_users[event.connection.fd] = userid Context.connected_users[event.connection.fd] = userid
@ -127,7 +141,7 @@ def hdl_authentication(event : IPC::Event::Message)
# Sending a response, containing a response for each request. # Sending a response, containing a response for each request.
# The response is "Ok" when the message is well received and authorized. # The response is "Ok" when the message is well received and authorized.
response = FileStorage::Message::Responses.new authentication_message.mid, "Ok", responses response = FileStorage::Responses.new authentication_message.mid, "Ok", responses
event.connection.send FileStorage::MessageType::Responses.to_u8, response.to_json event.connection.send FileStorage::MessageType::Responses.to_u8, response.to_json
pp! FileStorage::MessageType::Responses.to_u8 pp! FileStorage::MessageType::Responses.to_u8
pp! response pp! response

View File

@ -42,8 +42,8 @@ Context.service.not_nil!.loop do |event|
if ! userid && mtype != FileStorage::MessageType::Authentication if ! userid && mtype != FileStorage::MessageType::Authentication
# TODO: replace this with an Error message? # TODO: replace this with an Error message?
mid = "no message id" mid = "no message id"
response = FileStorage::Message::Response.new mid, "Not OK", "Action on non connected user" response = FileStorage::Response.new mid, "Not OK", "Action on non connected user"
event.connection.send FileStorage::MessageType::Response.to_u8, response.to_json do_response event, response
end end
case mtype case mtype
@ -59,22 +59,20 @@ Context.service.not_nil!.loop do |event|
end end
when .upload_request? when .upload_request?
puts "Upload request" puts "Upload request"
request = FileStorage::Message::UploadRequest.from_json( request = FileStorage::UploadRequest.from_json(
String.new event.message.payload String.new event.message.payload
) )
response = hdl_upload request, Context.users_status[userid], event response = hdl_upload request, Context.users_status[userid], event
event.connection.send FileStorage::MessageType::Response.to_u8, response.to_json do_response event, response
raise "not implemented yet"
when .download_request? when .download_request?
puts "Download request" puts "Download request"
request = FileStorage::Message::DownloadRequest.from_json( request = FileStorage::DownloadRequest.from_json(
String.new event.message.payload String.new event.message.payload
) )
response = hdl_download request, Context.users_status[userid], event response = hdl_download request, Context.users_status[userid], event
event.connection.send FileStorage::MessageType::Response.to_u8, response.to_json do_response event, response
raise "not implemented yet"
when .response? when .response?
puts "Response message" puts "Response message"
raise "not implemented yet" raise "not implemented yet"
@ -90,12 +88,12 @@ Context.service.not_nil!.loop do |event|
raise "The user isn't recorded in the users_status structure" raise "The user isn't recorded in the users_status structure"
end end
transfer = FileStorage::Message::Transfer.from_json( transfer = FileStorage::Transfer.from_json(
String.new event.message.payload String.new event.message.payload
) )
response = hdl_transfer transfer, Context.users_status[userid], event response = hdl_transfer transfer, Context.users_status[userid], event
event.connection.send FileStorage::MessageType::Response.to_u8, response.to_json do_response event, response
end end
else else
raise "Event type not supported." raise "Event type not supported."
@ -103,3 +101,19 @@ Context.service.not_nil!.loop do |event|
rescue e rescue e
puts "A problem occured : #{e.message}" puts "A problem occured : #{e.message}"
end 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