From 8c0a7b1f140cb4868a7fad17995bde904959f569 Mon Sep 17 00:00:00 2001
From: Philippe PITTOLI
Date: Thu, 30 Jan 2020 17:47:56 +0100
Subject: [PATCH] New API
---
src/client/main.cr | 2 +-
src/common/filestorage.cr | 4 +--
src/common/utils.cr | 2 +-
src/server/handlers.cr | 60 ++++++++++++++++++++++++++++-----------
src/server/main-loop.cr | 6 ++--
5 files changed, 50 insertions(+), 24 deletions(-)
diff --git a/src/client/main.cr b/src/client/main.cr
index e975128..abb55ac 100644
--- a/src/client/main.cr
+++ b/src/client/main.cr
@@ -111,7 +111,7 @@ def file_transfer(client : IPC::Client, file : File, file_info : FileStorage::Fi
buffer_size = 1_000
buffer = Bytes.new buffer_size
- counter = 1
+ counter = 0
size = 0
while (size = file.read(buffer)) > 0
diff --git a/src/common/filestorage.cr b/src/common/filestorage.cr
index b115208..4b81e23 100644
--- a/src/common/filestorage.cr
+++ b/src/common/filestorage.cr
@@ -97,7 +97,7 @@ module FileStorage
property mid : String # autogenerated
property file : FileInfo
- def initialize(@file)
+ def initialize(@file : FileInfo)
@mid = UUID.random.to_s
end
end
@@ -177,7 +177,7 @@ module FileStorage
@filedigest = file_info.digest
@data = Base64.encode bindata
- @chunk = FileStorage::Chunk.new count, file_info.nb_chunks, @data
+ @chunk = FileStorage::Chunk.new count, file_info.nb_chunks - 1, @data
@mid = UUID.random.to_s
end
end
diff --git a/src/common/utils.cr b/src/common/utils.cr
index 36b4aa7..8a4b4c4 100644
--- a/src/common/utils.cr
+++ b/src/common/utils.cr
@@ -4,7 +4,7 @@ def remove_chunk_from_db(transfer_info : TransferInfo, chunk_number : Int32)
Context.db_by_filedigest.update transfer_info.file_info.digest, transfer_info
end
-def write_a_chunk(userid : String, file_info : FileInfo, chunk_number : Int32, data : Bytes)
+def write_a_chunk(userid : String, file_info : FileStorage::FileInfo, chunk_number : Int32, data : Bytes)
# storage: Context.storage_directory/userid/fileuuid.bin
dir = "#{Context.storage_directory}/#{userid}"
diff --git a/src/server/handlers.cr b/src/server/handlers.cr
index 4028514..6fcc981 100644
--- a/src/server/handlers.cr
+++ b/src/server/handlers.cr
@@ -20,22 +20,26 @@ def hdl_transfer(message : FileStorage::Transfer, user : User) : FileStorage::Re
# Get the transfer info from the db
transfer_info = Context.db_by_filedigest.get message.filedigest
- # TODO: if we don't have the information
if transfer_info.nil?
- # TODO
+ # The user has to send an upload request before sending anything
+ # If not the case, it should be discarded
+ raise "file not recorded"
end
- # TODO: verify that the chunk sent was really missing
- chunk_number = message.chunk.n - 1
-
- # TODO: verify the digest
+ chunk_number = message.chunk.n
data = Base64.decode message.data
- write_a_chunk user.uid.to_s, transfer_info.file_info, chunk_number, data
- # TODO: register the file with dodb, with its tags
+ # TODO: verify that the chunk sent was really missing
+ if transfer_info.chunks.select(chunk_number).size > 0
+ write_a_chunk user.uid.to_s, transfer_info.file_info, chunk_number, data
+ else
+ raise "non existent chunk or already uploaded"
+ end
- remove_chunk_from_db transfer_info, message.chunk.n
+ remove_chunk_from_db transfer_info, chunk_number
+
+ # TODO: verify the digest, if no more chunks
FileStorage::Response.new mid, "Ok"
@@ -44,23 +48,45 @@ rescue e
FileStorage::Response.new mid.not_nil!, "Not Ok", "Unexpected error: #{e.message}"
end
-# TODO
# the client sent an upload request
-def hdl_upload(request : FileStorage::UploadRequest,
- user : User,
- event : IPC::Event::Message) : FileStorage::Response
+def hdl_upload(request : FileStorage::UploadRequest, user : User) : FileStorage::Response
+
+ mid = request.mid
+ mid ||= "no message id"
puts "hdl upload: mid=#{request.mid}"
pp! request
+ # TODO: verify the rights and quotas of the user
+
+ # First: check if the file already exists
+ transfer_info = Context.db_by_filedigest.get request.file.digest
+ if transfer_info.nil?
+ # In case file informations aren't already registered
+ # which is normal at this point
+ transfer_info = TransferInfo.new user.uid, request.file
+ Context.db << transfer_info
+ else
+ # File information already exists, request may be duplicated
+ # In this case: ignore the upload request
+ end
+
+ # file_info.name
+ # file_info.size
+ # file_info.nb_chunks
+ # file_info.digest
+ # file_info.tags
+
FileStorage::Response.new request.mid, "Upload OK"
+rescue e
+ puts "Error handling transfer: #{e.message}"
+ FileStorage::Response.new mid.not_nil!, "Not Ok", "Unexpected error: #{e.message}"
end
# TODO
# the client sent a download request
def hdl_download(request : FileStorage::DownloadRequest,
- user : User,
- event : IPC::Event::Message) : FileStorage::Response
+ user : User) : FileStorage::Response
puts "hdl download: mid=#{request.mid}"
pp! request
@@ -82,9 +108,9 @@ def hdl_requests(requests : Array(FileStorage::Request),
requests.each do |request|
case request
when FileStorage::DownloadRequest
- responses << hdl_download request, user, event
+ responses << hdl_download request, user
when FileStorage::UploadRequest
- responses << hdl_upload request, user, event
+ responses << hdl_upload request, user
else
raise "request not understood"
end
diff --git a/src/server/main-loop.cr b/src/server/main-loop.cr
index 645a5ff..33bd0f9 100644
--- a/src/server/main-loop.cr
+++ b/src/server/main-loop.cr
@@ -62,7 +62,7 @@ Context.service.not_nil!.loop do |event|
request = FileStorage::UploadRequest.from_json(
String.new event.message.payload
)
- response = hdl_upload request, Context.users_status[userid], event
+ response = hdl_upload request, Context.users_status[userid]
do_response event, response
when .download_request?
@@ -70,7 +70,7 @@ Context.service.not_nil!.loop do |event|
request = FileStorage::DownloadRequest.from_json(
String.new event.message.payload
)
- response = hdl_download request, Context.users_status[userid], event
+ response = hdl_download request, Context.users_status[userid]
do_response event, response
when .response?
@@ -91,7 +91,7 @@ Context.service.not_nil!.loop do |event|
transfer = FileStorage::Transfer.from_json(
String.new event.message.payload
)
- response = hdl_transfer transfer, Context.users_status[userid], event
+ response = hdl_transfer transfer, Context.users_status[userid]
do_response event, response
end