diff --git a/src/Simplex/FileTransfer/Agent.hs b/src/Simplex/FileTransfer/Agent.hs index 5666b63ff..f2138d840 100644 --- a/src/Simplex/FileTransfer/Agent.hs +++ b/src/Simplex/FileTransfer/Agent.hs @@ -389,16 +389,20 @@ runXFTPSndPrepareWorker c Worker {doWork} = do where AgentConfig {xftpMaxRecipientsPerRequest = maxRecipients, messageRetryInterval = ri} = cfg encryptFileForUpload :: SndFile -> FilePath -> m (FileDigest, [(XFTPChunkSpec, FileDigest)]) - encryptFileForUpload SndFile {key, nonce, srcFile} fsEncPath = do + encryptFileForUpload SndFile {key, nonce, srcFile, redirect} fsEncPath = do let CryptoFile {filePath} = srcFile fileName = takeFileName filePath fileSize <- liftIO $ fromInteger <$> CF.getFileContentsSize srcFile when (fileSize > maxFileSizeHard) $ throwError $ INTERNAL "max file size exceeded" let fileHdr = smpEncode FileHeader {fileName, fileExtra = Nothing} fileSize' = fromIntegral (B.length fileHdr) + fileSize - chunkSizes = prepareChunkSizes $ fileSize' + fileSizeLen + authTagSize - chunkSizes' = map fromIntegral chunkSizes - encSize = sum chunkSizes' + payloadSize = fileSize' + fileSizeLen + authTagSize + chunkSizes <- case redirect of + Nothing -> pure $ prepareChunkSizes payloadSize + Just _ -> case singleChunkSize payloadSize of + Nothing -> throwError $ INTERNAL "max file size exceeded for redirect" + Just chunkSize -> pure [chunkSize] + let encSize = sum $ map fromIntegral chunkSizes void $ liftError (INTERNAL . show) $ encryptFile srcFile fileHdr key nonce fileSize' encSize fsEncPath digest <- liftIO $ LC.sha512Hash <$> LB.readFile fsEncPath let chunkSpecs = prepareChunkSpecs fsEncPath chunkSizes diff --git a/src/Simplex/FileTransfer/Client/Main.hs b/src/Simplex/FileTransfer/Client/Main.hs index d0c867b27..90348099a 100644 --- a/src/Simplex/FileTransfer/Client/Main.hs +++ b/src/Simplex/FileTransfer/Client/Main.hs @@ -16,6 +16,7 @@ module Simplex.FileTransfer.Client.Main xftpClientCLI, cliSendFile, cliSendFileOpts, + singleChunkSize, prepareChunkSizes, prepareChunkSpecs, maxFileSize, @@ -42,7 +43,7 @@ import Data.List.NonEmpty (NonEmpty (..), nonEmpty) import qualified Data.List.NonEmpty as L import Data.Map (Map) import qualified Data.Map as M -import Data.Maybe (fromMaybe) +import Data.Maybe (fromMaybe, listToMaybe) import qualified Data.Text as T import Data.Word (Word32) import GHC.Records (HasField (getField)) @@ -528,6 +529,12 @@ getFileDescription' path = getFileDescription path >>= \case AVFD fd -> either (throwError . CLIError) pure $ checkParty fd +singleChunkSize :: Int64 -> Maybe Word32 +singleChunkSize size' = + listToMaybe $ dropWhile (< chunkSize) serverChunkSizes + where + chunkSize = fromIntegral size' + prepareChunkSizes :: Int64 -> [Word32] prepareChunkSizes size' = prepareSizes size' where