FileStorage::Message is now a class that messages inherit from.
parent
a2393848af
commit
c4fe6e0ec7
|
@ -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}"
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue