Server fixes, and client is working.
This commit is contained in:
parent
761c12a0ba
commit
60b9d9fa01
14
src/client/authd_api.cr
Normal file
14
src/client/authd_api.cr
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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/
|
||||
|
Loading…
Reference in New Issue
Block a user