Server fixes, and client is working.

This commit is contained in:
Karchnu 2020-06-08 04:49:55 +02:00
parent 761c12a0ba
commit 60b9d9fa01
5 changed files with 134 additions and 139 deletions

14
src/client/authd_api.cr Normal file
View File

@ -0,0 +1,14 @@
def authd_get_token(key_file : String? = nil, login : String? = nil, pass : String? = nil)
authd = AuthD::Client.new
key_file.try do |file| # FIXME: fail if missing?
authd.key = File.read(file).chomp
end
token = authd.get_token? login, pass
raise "cannot get a token" if token.nil?
authd.close
token
end

View File

@ -1,10 +1,16 @@
require "option_parser"
require "authd"
require "ipc"
require "json"
require "base64"
require "../common/filestorage.cr"
require "./authd_api.cr"
require "../server/network.cr"
require "../server/storage.cr"
require "../server/storage/*"
require "../common/*"
require "../common/requests/*"
# TODO
# For now, this example only upload files.
@ -14,9 +20,8 @@ service_name = "filestorage"
files_and_directories_to_transfer = Array(String).new
# This is the requests we will send to the server
upload_requests = Array(FileStorage::UploadRequest).new
authd_login : String = "test"
authd_pass : String = "test"
OptionParser.parse do |parser|
parser.on "-s service-name",
@ -25,6 +30,18 @@ OptionParser.parse do |parser|
service_name = name
end
parser.on "-l login",
"--login login-name",
"Login name for authd." do |name|
authd_login = name
end
parser.on "-p pass",
"--pass pass",
"Password for authd." do |pass|
authd_pass = pass
end
parser.unknown_args do |arg|
files_and_directories_to_transfer = arg
end
@ -32,18 +49,16 @@ OptionParser.parse do |parser|
parser.on "-h", "--help", "Show this help" do
puts parser
puts "program [OPTIONS] <files-to-upload>"
exit 0
exit -1
end
end
#
# Get informations about files to transfer
# For now, we only want to upload files, so we create an UploadRequest
# Verify we can read files
#
files_info = Hash(String, FileStorage::FileInfo).new
files = [] of String
puts "files and directories to transfer"
files_and_directories_to_transfer.each do |f|
@ -51,9 +66,7 @@ files_and_directories_to_transfer.each do |f|
# TODO
puts "Directories not supported, for now"
elsif File.file?(f) && File.readable? f
File.open(f) do |file|
files_info[file.path] = FileStorage::FileInfo.new file
end
files << f
else
if ! File.exists? f
puts "#{f} does not exist"
@ -65,101 +78,24 @@ files_and_directories_to_transfer.each do |f|
end
end
files_info.values.each do |file_info|
upload_requests << FileStorage::UploadRequest.new file_info
end
# pp! upload_requests
#
# Connection to the service
#
client = IPC::Client.new service_name
# Authentication.
pp! authd_login
pp! authd_pass
token = authd_get_token login: authd_login, pass: authd_pass
#
# Sending the authentication message, including files info
#
token = FileStorage::Token.new 1002, "karchnu"
authentication_message = FileStorage::Authentication.new token, upload_requests
pp! authentication_message
client.send FileStorage::MessageType::Authentication.to_u8, authentication_message.to_json
#
# Receiving a response
#
m = client.read
# puts "message received: #{m.to_s}"
# puts "message received payload: #{String.new m.payload}"
response = FileStorage::Response.from_json(String.new m.payload)
if response.mid == authentication_message.mid
puts "This is a response for the authentication message"
pp! response
else
raise "Message IDs from authentication message and its response differ"
end
#
# file transfer
#
def file_transfer(client : IPC::Client, file : File, file_info : FileStorage::FileInfo)
buffer_size = 1_000
buffer = Bytes.new buffer_size
counter = 0
size = 0
while (size = file.read(buffer)) > 0
# transfer message = file_info, chunk count, data (will be base64'd)
transfer_message = FileStorage::Transfer.new file_info, counter, buffer[0 ... size]
client.send FileStorage::MessageType::Transfer.to_u8, transfer_message.to_json
counter += 1
buffer = Bytes.new buffer_size
# Check for the response
m = client.read
mtype = FileStorage::MessageType.new m.utype.to_i32
if mtype != FileStorage::MessageType::Response
pp! m
raise "Message received was not expected: #{mtype}"
end
response = FileStorage::Response.from_json(String.new m.payload)
if response.mid != transfer_message.mid
raise "Message received has a wrong mid: #{response.mid} != #{transfer_message.mid}"
else
pp! response
end
end
end
# Connection and authentication to filestoraged.
client = FileStorage::Client.new token, service_name
client.login
files.each do |file|
puts "upload: #{file}"
pp! client.upload file
puts "transfer"
files_info.keys.each do |file_path|
puts "- #{file_path}"
File.open(file_path) do |file|
file_transfer client, file, files_info[file_path]
end
client.transfer file
end
client.close
#client.loop do |event|
# case event
# when IPC::Event::Message
# puts "\033[32mthere is a message\033[00m"
# puts event.message.to_s
# client.close
# exit
# end
#end

View File

@ -1,64 +1,106 @@
require "ipc"
class FileStorage::Client
class FileStorage::Client < IPC::Client
property auth_token : String
def login(token : String)
request = FileStorage::Request::Login.new token
def initialize(@auth_token, service_name = "filestorage")
super service_name
end
def login
request = FileStorage::Request::Login.new auth_token
send request
response = parse_message [ FileStorage::Response::Login, FileStorage::Response::Error ], read
response = parse_message [
FileStorage::Response::Login,
FileStorage::Errors::GenericError
], read
case response
when FileStorage::Response::Login
# Received favorites, likes, etc.
when FileStorage::Response::Error
raise "user was not logged in: #{response.reason}"
if response.responds_to? :mid
if request.mid != response.mid
raise "mid from response != request"
end
else
raise "response doen't even have mid"
end
response
end
def transfer(file_info : FileInfo, count, bindata)
request = FileStorage::Request::PutChunk.new file_info, count, bindata
send request
response = parse_message [ FileStorage::Response::PutChunk, FileStorage::Response::Error ], read
case response
when FileStorage::Response::PutChunk
when FileStorage::Response::Error
raise "File chunk was not transfered: #{response.reason}"
def get_file_info(file_path : String)
file_info : FileStorage::FileInfo
file = File.open(file_path)
file_info = FileStorage::FileInfo.new file
file.close
file_info.not_nil!
end
response
def transfer(file_path : String)
file_info = get_file_info file_path
File.open(file_path) do |file|
buffer_size = FileStorage.message_buffer_size
buffer = Bytes.new buffer_size
counter = 0
size = 0
while (size = file.read(buffer)) > 0
puts "loop !!!"
# transfer message = file_info, chunk count, data (will be base64'd)
transfer_message = FileStorage::Request::PutChunk.new file_info,
counter,
buffer[0 ... size]
send transfer_message
counter += 1
buffer = Bytes.new buffer_size
# Check for the response
response = parse_message [
FileStorage::Response::PutChunk,
FileStorage::Errors::GenericError
], read
if response.responds_to? :mid
if response.mid != transfer_message.mid
raise "request and response mid !=: #{response.mid} != #{transfer_message.mid}"
else
pp! response
end
else
raise "response doesn't have mid"
end
end
end
end
def download(filedigest = nil, name = nil, tags = nil)
request = FileStorage::Request::Download.new filedigest, name, tags
send request
response = parse_message [ FileStorage::Response::Download, FileStorage::Response::Error ], read
case response
when FileStorage::Response::Download
when FileStorage::Response::Error
raise "Download request denied: #{response.reason}"
end
response = parse_message [
FileStorage::Response::Download,
FileStorage::Errors::GenericError
], read
response
end
def upload(token : String)
request = FileStorage::Request::Upload.new token
def upload(file : String)
file_info : FileStorage::FileInfo
File.open(file) do |f|
file_info = FileStorage::FileInfo.new f
request = FileStorage::Request::Upload.new file_info
send request
response = parse_message [ FileStorage::Response::Upload, FileStorage::Response::Error ], read
case response
when FileStorage::Response::Upload
when FileStorage::Response::Error
raise "Upload request failed: #{response.reason}"
end
response = parse_message [
FileStorage::Response::Upload,
FileStorage::Errors::GenericError
], read
response
end
end

View File

@ -46,7 +46,7 @@ class FileStorage::Storage
# - users/ : DODB UserData (for later use: quotas, rights)
def initialize(@root)
@db = DODB::DataBase(TransferInfo).new "'#{@root}/meta"
@db = DODB::DataBase(TransferInfo).new "#{@root}/meta"
# Where to store uploaded files.
FileUtils.mkdir_p "#{@root}/files"

View File

@ -19,6 +19,8 @@ class FileStorage::FileInfo
nb_chunks : Int32
digest : String
tags : Array(String)
initialize(file : File, tags = nil)
end
class TransferInfo
@ -35,7 +37,8 @@ class FileStorage::UserData
property uploads : Array(Upload) # NOT USED.
property downloads : Array(Download) # NOT USED.
initialize(@uid, @uploads = Array(Upload).new, @downloads = Array(Download).new)
initialize(@uid, @uploads = Array(Upload).new,
@downloads = Array(Download).new)
end
root/