avoid padding in clientPut

Instead truncate when necessary to indicate invalid content was sent.
Very similar to how serveGet handles it.
This commit is contained in:
Joey Hess 2024-07-22 11:47:24 -04:00
parent 726c815a7f
commit efa0efdc44
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
2 changed files with 31 additions and 22 deletions

View file

@ -646,37 +646,44 @@ clientPut clientenv (ProtocolVersion ver) k su cu bypass auth moffset af content
return res return res
where where
stream checkv checkresultv = S.SourceT $ \a -> do stream checkv checkresultv = S.SourceT $ \a -> do
-- TODO seek to offset when requested
bl <- L.readFile contentfile bl <- L.readFile contentfile
v <- newMVar (0, L.toChunks bl) v <- newMVar (0, filter (not . B.null) (L.toChunks bl))
a (go v) a (go v)
where where
go v = S.fromActionStep B.null $ do go v = S.fromActionStep B.null $
res <- modifyMVar v $ pure . \case modifyMVar v $ \case
(n, []) -> ((n, []), (n, Nothing)) (n, (b:[])) -> do
(n, (b:bs)) ->
let !n' = n + B.length b let !n' = n + B.length b
in ((n', bs), (n, Just b)) ifM (checkvalid n)
case res of ( return ((n', []), b)
(_, Just b) -> return b -- The key's content is invalid, but
(n, Nothing) -> do -- the amount of data is the same as the
void $ liftIO $ atomically $ -- DataLengthHeader indicates. Truncate
tryPutTMVar checkv () -- the stream by one byte to indicate
valid <- liftIO $ atomically $ -- to the server that it's not valid.
readTMVar checkresultv , return ((n' - 1, []), B.take (B.length b - 1) b)
if not valid )
then if n == fromIntegral contentfilesize (n, []) -> do
then do void $ checkvalid n
modifyMVar_ v $ \(_n, l) -> return ((n, []), mempty)
pure (n+1, l) (n, (b:bs)) ->
return "X" let !n' = n + B.length b
else return B.empty in return ((n', bs), b)
else return B.empty
checkvalid n = do
void $ liftIO $ atomically $ tryPutTMVar checkv ()
valid <- liftIO $ atomically $ readTMVar checkresultv
if not valid
then return (n /= fromIntegral nlen)
else return True
baf = case af of baf = case af of
AssociatedFile Nothing -> Nothing AssociatedFile Nothing -> Nothing
AssociatedFile (Just f) -> Just (B64FilePath f) AssociatedFile (Just f) -> Just (B64FilePath f)
len = DataLength $ case moffset of len = DataLength nlen
nlen = case moffset of
Nothing -> contentfilesize Nothing -> contentfilesize
Just (Offset o) -> contentfilesize - fromIntegral o Just (Offset o) -> contentfilesize - fromIntegral o

View file

@ -32,6 +32,8 @@ Planned schedule of work:
That should not be necessary, they should always be able to truncate the That should not be necessary, they should always be able to truncate the
data. data.
* clientPut needs to seek to the requested offset in the file.
* Implement: servePutOffset, serveLockContent * Implement: servePutOffset, serveLockContent
* A Locker should expire the lock on its own after 10 minutes initially. * A Locker should expire the lock on its own after 10 minutes initially.