2020-05-14 17:03:09 +02:00
|
|
|
|
|
|
|
# For now, upload and download are sequentials.
|
|
|
|
# In a future version, we will be able to send
|
|
|
|
# arbitrary parts of each file.
|
|
|
|
|
|
|
|
# Who knows, maybe someday we will be on UDP, too.
|
|
|
|
#class SHA256
|
|
|
|
# JSON.mapping({
|
|
|
|
# chunk: Slice(UInt8)
|
|
|
|
# })
|
|
|
|
#end
|
|
|
|
|
2020-10-20 19:15:50 +02:00
|
|
|
module FileStorage
|
2020-05-14 17:03:09 +02:00
|
|
|
|
|
|
|
# 1 MB read buffer, on-disk
|
|
|
|
def self.file_reading_buffer_size
|
|
|
|
1_000_000
|
|
|
|
end
|
|
|
|
|
|
|
|
# 1 KB message data buffer, on-network
|
|
|
|
def self.message_buffer_size
|
|
|
|
1_000
|
|
|
|
end
|
|
|
|
|
|
|
|
# private function
|
|
|
|
def self.data_digest(data : Bytes)
|
2023-02-09 23:28:10 +01:00
|
|
|
digest = OpenSSL::Digest.new "sha256"
|
|
|
|
digest.update data
|
|
|
|
digest.hexfinal
|
2020-05-14 17:03:09 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
# private function
|
|
|
|
def self.file_digest(file : File)
|
|
|
|
# 1M read buffer
|
|
|
|
buffer = Bytes.new(1_000_000)
|
|
|
|
|
|
|
|
io = OpenSSL::DigestIO.new(file, "SHA256")
|
|
|
|
while io.read(buffer) > 0 ; end
|
|
|
|
|
|
|
|
io.digest.hexstring
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class FileStorage::Chunk
|
|
|
|
include JSON::Serializable
|
|
|
|
|
|
|
|
property n : Int32 # chunk's number
|
|
|
|
property on : Int32 # number of chunks
|
|
|
|
property digest : String # digest of the current chunk
|
|
|
|
|
|
|
|
def initialize(@n, @on, data)
|
|
|
|
@digest = FileStorage.data_digest data.to_slice
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# A file has a name, a size and tags.
|
|
|
|
class FileStorage::FileInfo
|
|
|
|
include JSON::Serializable
|
|
|
|
|
|
|
|
property name : String
|
|
|
|
property size : UInt64
|
|
|
|
property nb_chunks : Int32
|
|
|
|
property digest : String
|
|
|
|
|
|
|
|
# list of SHA256, if we are on UDP
|
|
|
|
# chunks: Array(SHA256),
|
|
|
|
property tags : Array(String)
|
|
|
|
|
|
|
|
def initialize(file : File, tags = nil)
|
|
|
|
@name = File.basename file.path
|
|
|
|
@size = file.size
|
|
|
|
@digest = FileStorage.file_digest file
|
|
|
|
@nb_chunks = (@size / FileStorage.message_buffer_size).ceil.to_i
|
|
|
|
@tags = tags || [] of String
|
|
|
|
end
|
|
|
|
end
|