core: option to receive file inline up to maximum "offered" size (#1232)
* core: option to receive file inline up to maximum "offered" size * comment
This commit is contained in:
committed by
GitHub
parent
9edb54b45c
commit
c4fc8a97b1
@@ -1009,10 +1009,10 @@ processChatCommand = \case
|
||||
processChatCommand . APISendMessage chatRef $ ComposedMessage (Just f) Nothing (MCImage "" fixedImagePreview)
|
||||
ForwardFile chatName fileId -> forwardFile chatName fileId SendFile
|
||||
ForwardImage chatName fileId -> forwardFile chatName fileId SendImage
|
||||
ReceiveFile fileId filePath_ -> withUser $ \user ->
|
||||
ReceiveFile fileId rcvInline_ filePath_ -> withUser $ \user ->
|
||||
withChatLock . procCmd $ do
|
||||
ft <- withStore $ \db -> getRcvFileTransfer db user fileId
|
||||
(CRRcvFileAccepted <$> acceptFileReceive user ft filePath_) `catchError` processError ft
|
||||
(CRRcvFileAccepted <$> acceptFileReceive user ft rcvInline_ filePath_) `catchError` processError ft
|
||||
where
|
||||
processError ft = \case
|
||||
-- TODO AChatItem in Cancelled events
|
||||
@@ -1256,8 +1256,8 @@ toFSFilePath :: ChatMonad m => FilePath -> m FilePath
|
||||
toFSFilePath f =
|
||||
maybe f (<> "/" <> f) <$> (readTVarIO =<< asks filesFolder)
|
||||
|
||||
acceptFileReceive :: forall m. ChatMonad m => User -> RcvFileTransfer -> Maybe FilePath -> m AChatItem
|
||||
acceptFileReceive user@User {userId} RcvFileTransfer {fileId, fileInvitation = FileInvitation {fileName = fName, fileConnReq, fileInline, fileSize}, fileStatus, grpMemberId} filePath_ = do
|
||||
acceptFileReceive :: forall m. ChatMonad m => User -> RcvFileTransfer -> Maybe Bool -> Maybe FilePath -> m AChatItem
|
||||
acceptFileReceive user@User {userId} RcvFileTransfer {fileId, fileInvitation = FileInvitation {fileName = fName, fileConnReq, fileInline, fileSize}, fileStatus, grpMemberId} rcvInline_ filePath_ = do
|
||||
unless (fileStatus == RFSNew) $ case fileStatus of
|
||||
RFSCancelled _ -> throwChatError $ CEFileCancelled fName
|
||||
_ -> throwChatError $ CEFileAlreadyReceiving fName
|
||||
@@ -1290,9 +1290,9 @@ acceptFileReceive user@User {userId} RcvFileTransfer {fileId, fileInvitation = F
|
||||
acceptFile = do
|
||||
sharedMsgId <- withStore $ \db -> getSharedMsgIdByFileId db userId fileId
|
||||
filePath <- getRcvFilePath fileId filePath_ fName
|
||||
ChatConfig {fileChunkSize, inlineFiles} <- asks config
|
||||
inline <- receiveInline
|
||||
if
|
||||
| fileInline == Just IFMOffer && fileSize <= fileChunkSize * receiveChunks inlineFiles -> do
|
||||
| inline -> do
|
||||
-- accepting inline
|
||||
ci <- withStore $ \db -> acceptRcvInlineFT db user fileId filePath
|
||||
pure (XFileAcptInv sharedMsgId Nothing fName, ci)
|
||||
@@ -1302,6 +1302,15 @@ acceptFileReceive user@User {userId} RcvFileTransfer {fileId, fileInvitation = F
|
||||
(agentConnId, fileInvConnReq) <- withAgent $ \a -> createConnection a True SCMInvitation
|
||||
ci <- withStore $ \db -> acceptRcvFileTransfer db user fileId agentConnId ConnNew filePath
|
||||
pure (XFileAcptInv sharedMsgId (Just fileInvConnReq) fName, ci)
|
||||
receiveInline :: m Bool
|
||||
receiveInline = do
|
||||
ChatConfig {fileChunkSize, inlineFiles = InlineFilesConfig {receiveChunks, offerChunks}} <- asks config
|
||||
pure $
|
||||
rcvInline_ /= Just False
|
||||
&& fileInline == Just IFMOffer
|
||||
&& ( fileSize <= fileChunkSize * receiveChunks
|
||||
|| (rcvInline_ == Just True && fileSize <= fileChunkSize * offerChunks)
|
||||
)
|
||||
|
||||
getRcvFilePath :: forall m. ChatMonad m => FileTransferId -> Maybe FilePath -> String -> m FilePath
|
||||
getRcvFilePath fileId fPath_ fn = case fPath_ of
|
||||
@@ -3155,7 +3164,7 @@ chatCommandP =
|
||||
("/image " <|> "/img ") *> (SendImage <$> chatNameP' <* A.space <*> filePath),
|
||||
("/fforward " <|> "/ff ") *> (ForwardFile <$> chatNameP' <* A.space <*> A.decimal),
|
||||
("/image_forward " <|> "/imgf ") *> (ForwardImage <$> chatNameP' <* A.space <*> A.decimal),
|
||||
("/freceive " <|> "/fr ") *> (ReceiveFile <$> A.decimal <*> optional (A.space *> filePath)),
|
||||
("/freceive " <|> "/fr ") *> (ReceiveFile <$> A.decimal <*> optional (" inline=" *> onOffP) <*> optional (A.space *> filePath)),
|
||||
("/fcancel " <|> "/fc ") *> (CancelFile <$> A.decimal),
|
||||
("/fstatus " <|> "/fs ") *> (FileStatus <$> A.decimal),
|
||||
"/simplex" $> ConnectSimplex,
|
||||
|
||||
@@ -84,7 +84,7 @@ data InlineFilesConfig = InlineFilesConfig
|
||||
defaultInlineFilesConfig :: InlineFilesConfig
|
||||
defaultInlineFilesConfig =
|
||||
InlineFilesConfig
|
||||
{ offerChunks = 15, -- max when chunks are offered - limited to 255 on the encoding level
|
||||
{ offerChunks = 15, -- max when chunks are offered / received with the option - limited to 255 on the encoding level
|
||||
sendChunks = 0, -- max per file when chunks will be sent inline without acceptance
|
||||
totalSendChunks = 30, -- max per conversation when chunks will be sent inline without acceptance
|
||||
receiveChunks = 5 -- max when chunks are accepted
|
||||
@@ -233,7 +233,7 @@ data ChatCommand
|
||||
| SendImage ChatName FilePath
|
||||
| ForwardFile ChatName FileTransferId
|
||||
| ForwardImage ChatName FileTransferId
|
||||
| ReceiveFile FileTransferId (Maybe FilePath)
|
||||
| ReceiveFile {fileId :: FileTransferId, fileInline :: Maybe Bool, filePath :: Maybe FilePath}
|
||||
| CancelFile FileTransferId
|
||||
| FileStatus FileTransferId
|
||||
| ShowProfile
|
||||
|
||||
@@ -73,6 +73,7 @@ chatTests = do
|
||||
describe "sending and receiving files" $ do
|
||||
describe "send and receive file" $ fileTestMatrix2 runTestFileTransfer
|
||||
it "send and receive file inline (without accepting)" testInlineFileTransfer
|
||||
it "receive file inline with inline=on option" testReceiveInline
|
||||
describe "send and receive a small file" $ fileTestMatrix2 runTestSmallFileTransfer
|
||||
describe "sender cancelled file transfer before transfer" $ fileTestMatrix2 runTestFileSndCancelBeforeTransfer
|
||||
it "sender cancelled file transfer during transfer" testFileSndCancelDuringTransfer
|
||||
@@ -1417,6 +1418,26 @@ testInlineFileTransfer =
|
||||
where
|
||||
cfg = testCfg {inlineFiles = defaultInlineFilesConfig {offerChunks = 100, sendChunks = 100, receiveChunks = 100}}
|
||||
|
||||
testReceiveInline :: IO ()
|
||||
testReceiveInline =
|
||||
testChatCfg2 cfg aliceProfile bobProfile $ \alice bob -> do
|
||||
connectUsers alice bob
|
||||
alice #> "/f @bob ./tests/fixtures/test.jpg"
|
||||
alice <## "use /fc 1 to cancel sending"
|
||||
bob <# "alice> sends file test.jpg (136.5 KiB / 139737 bytes)"
|
||||
bob <## "use /fr 1 [<dir>/ | <path>] to receive it"
|
||||
bob ##> "/fr 1 inline=on ./tests/tmp"
|
||||
bob <## "saving file 1 from alice to ./tests/tmp/test.jpg"
|
||||
alice <## "started sending file 1 (test.jpg) to bob"
|
||||
alice <## "completed sending file 1 (test.jpg) to bob"
|
||||
bob <## "started receiving file 1 (test.jpg) from alice"
|
||||
bob <## "completed receiving file 1 (test.jpg) from alice"
|
||||
src <- B.readFile "./tests/fixtures/test.jpg"
|
||||
dest <- B.readFile "./tests/tmp/test.jpg"
|
||||
dest `shouldBe` src
|
||||
where
|
||||
cfg = testCfg {inlineFiles = defaultInlineFilesConfig {offerChunks = 10, receiveChunks = 5}}
|
||||
|
||||
runTestSmallFileTransfer :: TestCC -> TestCC -> IO ()
|
||||
runTestSmallFileTransfer alice bob = do
|
||||
connectUsers alice bob
|
||||
|
||||
Reference in New Issue
Block a user