factor out IncrementalHasher from IncrementalVerifier
This commit is contained in:
parent
9d3ce224e3
commit
8034f2e9bb
9 changed files with 68 additions and 48 deletions
|
@ -656,8 +656,8 @@ downloadUrl listfailedurls k p iv urls file uo =
|
||||||
-- to be used for the other urls.
|
-- to be used for the other urls.
|
||||||
case iv of
|
case iv of
|
||||||
Just iv' ->
|
Just iv' ->
|
||||||
liftIO $ positionIncremental iv' >>= \case
|
liftIO $ positionIncrementalVerifier iv' >>= \case
|
||||||
Just n | n > 0 -> unableIncremental iv'
|
Just n | n > 0 -> unableIncrementalVerifier iv'
|
||||||
_ -> noop
|
_ -> noop
|
||||||
Nothing -> noop
|
Nothing -> noop
|
||||||
go us ((u, err) : errs)
|
go us ((u, err) : errs)
|
||||||
|
|
|
@ -86,7 +86,7 @@ fileCopier _ src dest meterupdate iv = docopy
|
||||||
fileCopier copycowtried src dest meterupdate iv =
|
fileCopier copycowtried src dest meterupdate iv =
|
||||||
ifM (liftIO $ tryCopyCoW copycowtried src dest meterupdate)
|
ifM (liftIO $ tryCopyCoW copycowtried src dest meterupdate)
|
||||||
( do
|
( do
|
||||||
liftIO $ maybe noop unableIncremental iv
|
liftIO $ maybe noop unableIncrementalVerifier iv
|
||||||
return CopiedCoW
|
return CopiedCoW
|
||||||
, docopy
|
, docopy
|
||||||
)
|
)
|
||||||
|
@ -119,7 +119,7 @@ fileCopier copycowtried src dest meterupdate iv =
|
||||||
else do
|
else do
|
||||||
let sofar' = addBytesProcessed sofar (S.length s)
|
let sofar' = addBytesProcessed sofar (S.length s)
|
||||||
S.hPut hdest s
|
S.hPut hdest s
|
||||||
maybe noop (flip updateIncremental s) iv
|
maybe noop (flip updateIncrementalVerifier s) iv
|
||||||
meterupdate sofar'
|
meterupdate sofar'
|
||||||
docopy' hdest hsrc sofar'
|
docopy' hdest hsrc sofar'
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ fileCopier copycowtried src dest meterupdate iv =
|
||||||
s' <- getnoshort (S.length s) hsrc
|
s' <- getnoshort (S.length s) hsrc
|
||||||
if s == s'
|
if s == s'
|
||||||
then do
|
then do
|
||||||
maybe noop (flip updateIncremental s) iv
|
maybe noop (flip updateIncrementalVerifier s) iv
|
||||||
let sofar' = addBytesProcessed sofar (S.length s)
|
let sofar' = addBytesProcessed sofar (S.length s)
|
||||||
meterupdate sofar'
|
meterupdate sofar'
|
||||||
compareexisting hdest hsrc sofar'
|
compareexisting hdest hsrc sofar'
|
||||||
|
|
|
@ -102,7 +102,7 @@ verifyKeyContent' k f =
|
||||||
Just verifier -> verifier k f
|
Just verifier -> verifier k f
|
||||||
|
|
||||||
resumeVerifyKeyContent :: Key -> RawFilePath -> IncrementalVerifier -> Annex Bool
|
resumeVerifyKeyContent :: Key -> RawFilePath -> IncrementalVerifier -> Annex Bool
|
||||||
resumeVerifyKeyContent k f iv = liftIO (positionIncremental iv) >>= \case
|
resumeVerifyKeyContent k f iv = liftIO (positionIncrementalVerifier iv) >>= \case
|
||||||
Nothing -> fallback
|
Nothing -> fallback
|
||||||
Just endpos -> do
|
Just endpos -> do
|
||||||
fsz <- liftIO $ catchDefaultIO 0 $ getFileSize f
|
fsz <- liftIO $ catchDefaultIO 0 $ getFileSize f
|
||||||
|
@ -119,21 +119,21 @@ resumeVerifyKeyContent k f iv = liftIO (positionIncremental iv) >>= \case
|
||||||
go fsz endpos
|
go fsz endpos
|
||||||
| fsz == endpos =
|
| fsz == endpos =
|
||||||
liftIO $ catchDefaultIO (Just False) $
|
liftIO $ catchDefaultIO (Just False) $
|
||||||
finalizeIncremental iv
|
finalizeIncrementalVerifier iv
|
||||||
| otherwise = do
|
| otherwise = do
|
||||||
showAction (descVerify iv)
|
showAction (descIncrementalVerifier iv)
|
||||||
liftIO $ catchDefaultIO (Just False) $
|
liftIO $ catchDefaultIO (Just False) $
|
||||||
withBinaryFile (fromRawFilePath f) ReadMode $ \h -> do
|
withBinaryFile (fromRawFilePath f) ReadMode $ \h -> do
|
||||||
hSeek h AbsoluteSeek endpos
|
hSeek h AbsoluteSeek endpos
|
||||||
feedincremental h
|
feedincremental h
|
||||||
finalizeIncremental iv
|
finalizeIncrementalVerifier iv
|
||||||
|
|
||||||
feedincremental h = do
|
feedincremental h = do
|
||||||
b <- S.hGetSome h chunk
|
b <- S.hGetSome h chunk
|
||||||
if S.null b
|
if S.null b
|
||||||
then return ()
|
then return ()
|
||||||
else do
|
else do
|
||||||
updateIncremental iv b
|
updateIncrementalVerifier iv b
|
||||||
feedincremental h
|
feedincremental h
|
||||||
|
|
||||||
chunk = 65536
|
chunk = 65536
|
||||||
|
@ -174,7 +174,7 @@ finishVerifyKeyContentIncrementally :: Maybe IncrementalVerifier -> Annex (Bool,
|
||||||
finishVerifyKeyContentIncrementally Nothing =
|
finishVerifyKeyContentIncrementally Nothing =
|
||||||
return (True, UnVerified)
|
return (True, UnVerified)
|
||||||
finishVerifyKeyContentIncrementally (Just iv) =
|
finishVerifyKeyContentIncrementally (Just iv) =
|
||||||
liftIO (finalizeIncremental iv) >>= \case
|
liftIO (finalizeIncrementalVerifier iv) >>= \case
|
||||||
Just True -> return (True, Verified)
|
Just True -> return (True, Verified)
|
||||||
Just False -> do
|
Just False -> do
|
||||||
warning "verification of content failed"
|
warning "verification of content failed"
|
||||||
|
@ -224,7 +224,7 @@ tailVerify :: IncrementalVerifier -> RawFilePath -> TMVar () -> IO ()
|
||||||
tailVerify iv f finished =
|
tailVerify iv f finished =
|
||||||
tryNonAsync go >>= \case
|
tryNonAsync go >>= \case
|
||||||
Right r -> return r
|
Right r -> return r
|
||||||
Left _ -> unableIncremental iv
|
Left _ -> unableIncrementalVerifier iv
|
||||||
where
|
where
|
||||||
-- Watch the directory containing the file, and wait for
|
-- Watch the directory containing the file, and wait for
|
||||||
-- the file to be modified. It's possible that the file already
|
-- the file to be modified. It's possible that the file already
|
||||||
|
@ -249,7 +249,7 @@ tailVerify iv f finished =
|
||||||
let cleanup = void . tryNonAsync . INotify.removeWatch
|
let cleanup = void . tryNonAsync . INotify.removeWatch
|
||||||
let stop w = do
|
let stop w = do
|
||||||
cleanup w
|
cleanup w
|
||||||
unableIncremental iv
|
unableIncrementalVerifier iv
|
||||||
waitopen modified >>= \case
|
waitopen modified >>= \case
|
||||||
Nothing -> stop wd
|
Nothing -> stop wd
|
||||||
Just h -> do
|
Just h -> do
|
||||||
|
@ -301,12 +301,12 @@ tailVerify iv f finished =
|
||||||
<$> takeTMVar finished)
|
<$> takeTMVar finished)
|
||||||
cont
|
cont
|
||||||
else do
|
else do
|
||||||
updateIncremental iv b
|
updateIncrementalVerifier iv b
|
||||||
atomically (tryTakeTMVar finished) >>= \case
|
atomically (tryTakeTMVar finished) >>= \case
|
||||||
Nothing -> follow h modified
|
Nothing -> follow h modified
|
||||||
Just () -> return ()
|
Just () -> return ()
|
||||||
|
|
||||||
chunk = 65536
|
chunk = 65536
|
||||||
#else
|
#else
|
||||||
tailVerify iv _ _ = unableIncremental iv
|
tailVerify iv _ _ = unableIncrementalVerifier iv
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -178,7 +178,7 @@ runLocal runst runner a = case a of
|
||||||
then defaultChunkSize
|
then defaultChunkSize
|
||||||
else fromIntegral n
|
else fromIntegral n
|
||||||
b <- S.hGet h c
|
b <- S.hGet h c
|
||||||
updateIncremental iv b
|
updateIncrementalVerifier iv b
|
||||||
unless (b == S.empty) $
|
unless (b == S.empty) $
|
||||||
go iv (n - fromIntegral (S.length b))
|
go iv (n - fromIntegral (S.length b))
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ runLocal runst runner a = case a of
|
||||||
Nothing -> \c -> S.hPut h c
|
Nothing -> \c -> S.hPut h c
|
||||||
Just iv -> \c -> do
|
Just iv -> \c -> do
|
||||||
S.hPut h c
|
S.hPut h c
|
||||||
updateIncremental iv c
|
updateIncrementalVerifier iv c
|
||||||
meteredWrite p' writechunk b
|
meteredWrite p' writechunk b
|
||||||
indicatetransferred ti
|
indicatetransferred ti
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ runLocal runst runner a = case a of
|
||||||
runner validitycheck >>= \case
|
runner validitycheck >>= \case
|
||||||
Right (Just Valid) -> case incrementalverifier of
|
Right (Just Valid) -> case incrementalverifier of
|
||||||
Just iv
|
Just iv
|
||||||
| rightsize -> liftIO (finalizeIncremental iv) >>= \case
|
| rightsize -> liftIO (finalizeIncrementalVerifier iv) >>= \case
|
||||||
Nothing -> return (True, UnVerified)
|
Nothing -> return (True, UnVerified)
|
||||||
Just True -> return (True, Verified)
|
Just True -> return (True, Verified)
|
||||||
Just False -> return (False, UnVerified)
|
Just False -> return (False, UnVerified)
|
||||||
|
|
|
@ -372,7 +372,7 @@ retrieveChunks retriever u vc chunkconfig encryptor basek dest basep enc encc
|
||||||
|
|
||||||
finalize (Right Nothing) = return UnVerified
|
finalize (Right Nothing) = return UnVerified
|
||||||
finalize (Right (Just iv)) =
|
finalize (Right (Just iv)) =
|
||||||
liftIO (finalizeIncremental iv) >>= \case
|
liftIO (finalizeIncrementalVerifier iv) >>= \case
|
||||||
Just True -> return Verified
|
Just True -> return Verified
|
||||||
_ -> return UnVerified
|
_ -> return UnVerified
|
||||||
finalize (Left v) = return v
|
finalize (Left v) = return v
|
||||||
|
@ -426,7 +426,7 @@ writeRetrievedContent dest enc encc mh mp content miv = case (enc, mh, content)
|
||||||
Just p ->
|
Just p ->
|
||||||
let writer = case miv of
|
let writer = case miv of
|
||||||
Just iv -> \s -> do
|
Just iv -> \s -> do
|
||||||
updateIncremental iv s
|
updateIncrementalVerifier iv s
|
||||||
S.hPut h s
|
S.hPut h s
|
||||||
Nothing -> S.hPut h
|
Nothing -> S.hPut h
|
||||||
in meteredWrite p writer b
|
in meteredWrite p writer b
|
||||||
|
|
|
@ -83,5 +83,5 @@ httpBodyRetriever dest meterupdate iv resp
|
||||||
let sofar' = addBytesProcessed sofar $ S.length b
|
let sofar' = addBytesProcessed sofar $ S.length b
|
||||||
S.hPut h b
|
S.hPut h b
|
||||||
meterupdate sofar'
|
meterupdate sofar'
|
||||||
maybe noop (flip updateIncremental b) iv
|
maybe noop (flip updateIncrementalVerifier b) iv
|
||||||
go sofar' h
|
go sofar' h
|
||||||
|
|
|
@ -173,7 +173,7 @@ retrieve hv cc = fileRetriever' $ \d k p iv ->
|
||||||
withDavHandle hv $ \dav -> case cc of
|
withDavHandle hv $ \dav -> case cc of
|
||||||
LegacyChunks _ -> do
|
LegacyChunks _ -> do
|
||||||
-- Not doing incremental verification for chunks.
|
-- Not doing incremental verification for chunks.
|
||||||
liftIO $ maybe noop unableIncremental iv
|
liftIO $ maybe noop unableIncrementalVerifier iv
|
||||||
retrieveLegacyChunked (fromRawFilePath d) k p dav
|
retrieveLegacyChunked (fromRawFilePath d) k p dav
|
||||||
_ -> liftIO $ goDAV dav $
|
_ -> liftIO $ goDAV dav $
|
||||||
retrieveHelper (keyLocation k) (fromRawFilePath d) p iv
|
retrieveHelper (keyLocation k) (fromRawFilePath d) p iv
|
||||||
|
|
|
@ -64,6 +64,8 @@ module Utility.Hash (
|
||||||
Mac(..),
|
Mac(..),
|
||||||
calcMac,
|
calcMac,
|
||||||
props_macs_stable,
|
props_macs_stable,
|
||||||
|
IncrementalHasher(..),
|
||||||
|
mkIncrementalHasher,
|
||||||
IncrementalVerifier(..),
|
IncrementalVerifier(..),
|
||||||
mkIncrementalVerifier,
|
mkIncrementalVerifier,
|
||||||
) where
|
) where
|
||||||
|
@ -280,44 +282,62 @@ props_macs_stable = map (\(desc, mac, result) -> (desc ++ " stable", calcMac mac
|
||||||
key = T.encodeUtf8 $ T.pack "foo"
|
key = T.encodeUtf8 $ T.pack "foo"
|
||||||
msg = T.encodeUtf8 $ T.pack "bar"
|
msg = T.encodeUtf8 $ T.pack "bar"
|
||||||
|
|
||||||
data IncrementalVerifier = IncrementalVerifier
|
data IncrementalHasher = IncrementalHasher
|
||||||
{ updateIncremental :: S.ByteString -> IO ()
|
{ updateIncrementalHasher :: S.ByteString -> IO ()
|
||||||
-- ^ Called repeatedly on each peice of the content.
|
-- ^ Called repeatedly on each peice of the content.
|
||||||
, finalizeIncremental :: IO (Maybe Bool)
|
, finalizeIncrementalHasher :: IO (Maybe String)
|
||||||
-- ^ Called once the full content has been sent, returns True
|
-- ^ Called once the full content has been sent, returns
|
||||||
-- if the hash verified, False if it did not, and Nothing if
|
-- the hash. (Nothing if unableIncremental was called.)
|
||||||
-- incremental verification was unable to be done.
|
, unableIncrementalHasher :: IO ()
|
||||||
, unableIncremental :: IO ()
|
-- ^ Call if the incremental hashing is unable to be done.
|
||||||
-- ^ Call if the incremental verification is unable to be done.
|
, positionIncrementalHasher :: IO (Maybe Integer)
|
||||||
, positionIncremental :: IO (Maybe Integer)
|
|
||||||
-- ^ Returns the number of bytes that have been fed to this
|
-- ^ Returns the number of bytes that have been fed to this
|
||||||
-- incremental verifier so far. (Nothing if unableIncremental was
|
-- incremental hasher so far. (Nothing if unableIncremental was
|
||||||
-- called.)
|
-- called.)
|
||||||
, descVerify :: String
|
, descIncrementalHasher :: String
|
||||||
-- ^ A description of what is done to verify the content.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mkIncrementalVerifier :: HashAlgorithm h => Context h -> String -> (String -> Bool) -> IO IncrementalVerifier
|
mkIncrementalHasher :: HashAlgorithm h => Context h -> String -> IO IncrementalHasher
|
||||||
mkIncrementalVerifier ctx descverify samechecksum = do
|
mkIncrementalHasher ctx desc = do
|
||||||
v <- newIORef (Just (ctx, 0))
|
v <- newIORef (Just (ctx, 0))
|
||||||
return $ IncrementalVerifier
|
return $ IncrementalHasher
|
||||||
{ updateIncremental = \b ->
|
{ updateIncrementalHasher = \b ->
|
||||||
modifyIORef' v $ \case
|
modifyIORef' v $ \case
|
||||||
(Just (ctx', n)) ->
|
(Just (ctx', n)) ->
|
||||||
let !ctx'' = hashUpdate ctx' b
|
let !ctx'' = hashUpdate ctx' b
|
||||||
!n' = n + fromIntegral (S.length b)
|
!n' = n + fromIntegral (S.length b)
|
||||||
in (Just (ctx'', n'))
|
in (Just (ctx'', n'))
|
||||||
Nothing -> Nothing
|
Nothing -> Nothing
|
||||||
, finalizeIncremental =
|
, finalizeIncrementalHasher =
|
||||||
readIORef v >>= \case
|
readIORef v >>= \case
|
||||||
(Just (ctx', _)) -> do
|
(Just (ctx', _)) -> do
|
||||||
let digest = hashFinalize ctx'
|
let digest = hashFinalize ctx'
|
||||||
return $ Just $
|
return $ Just $ show digest
|
||||||
samechecksum (show digest)
|
|
||||||
Nothing -> return Nothing
|
Nothing -> return Nothing
|
||||||
, unableIncremental = writeIORef v Nothing
|
, unableIncrementalHasher = writeIORef v Nothing
|
||||||
, positionIncremental = readIORef v >>= \case
|
, positionIncrementalHasher = readIORef v >>= \case
|
||||||
Just (_, n) -> return (Just n)
|
Just (_, n) -> return (Just n)
|
||||||
Nothing -> return Nothing
|
Nothing -> return Nothing
|
||||||
, descVerify = descverify
|
, descIncrementalHasher = desc
|
||||||
|
}
|
||||||
|
|
||||||
|
data IncrementalVerifier = IncrementalVerifier
|
||||||
|
{ updateIncrementalVerifier :: S.ByteString -> IO ()
|
||||||
|
, finalizeIncrementalVerifier :: IO (Maybe Bool)
|
||||||
|
, unableIncrementalVerifier :: IO ()
|
||||||
|
, positionIncrementalVerifier :: IO (Maybe Integer)
|
||||||
|
, descIncrementalVerifier :: String
|
||||||
|
}
|
||||||
|
|
||||||
|
mkIncrementalVerifier :: HashAlgorithm h => Context h -> String -> (String -> Bool) -> IO IncrementalVerifier
|
||||||
|
mkIncrementalVerifier ctx desc samechecksum = do
|
||||||
|
hasher <- mkIncrementalHasher ctx desc
|
||||||
|
return $ IncrementalVerifier
|
||||||
|
{ updateIncrementalVerifier = updateIncrementalHasher hasher
|
||||||
|
, finalizeIncrementalVerifier =
|
||||||
|
maybe Nothing (Just . samechecksum)
|
||||||
|
<$> finalizeIncrementalHasher hasher
|
||||||
|
, unableIncrementalVerifier = unableIncrementalHasher hasher
|
||||||
|
, positionIncrementalVerifier = positionIncrementalHasher hasher
|
||||||
|
, descIncrementalVerifier = descIncrementalHasher hasher
|
||||||
}
|
}
|
||||||
|
|
|
@ -451,7 +451,7 @@ download' nocurlerror meterupdate iv url file uo =
|
||||||
Nothing -> throwIO ex
|
Nothing -> throwIO ex
|
||||||
followredir _ ex = throwIO ex
|
followredir _ ex = throwIO ex
|
||||||
|
|
||||||
noverification = maybe noop unableIncremental iv
|
noverification = maybe noop unableIncrementalVerifier iv
|
||||||
|
|
||||||
{- Download a perhaps large file using conduit, with auto-resume
|
{- Download a perhaps large file using conduit, with auto-resume
|
||||||
- of incomplete downloads.
|
- of incomplete downloads.
|
||||||
|
@ -554,7 +554,7 @@ downloadConduit meterupdate iv req file uo =
|
||||||
() <- signalsuccess False
|
() <- signalsuccess False
|
||||||
throwM e
|
throwM e
|
||||||
|
|
||||||
noverification = maybe noop unableIncremental iv
|
noverification = maybe noop unableIncrementalVerifier iv
|
||||||
|
|
||||||
{- Sinks a Response's body to a file. The file can either be appended to
|
{- Sinks a Response's body to a file. The file can either be appended to
|
||||||
- (AppendMode), or written from the start of the response (WriteMode).
|
- (AppendMode), or written from the start of the response (WriteMode).
|
||||||
|
@ -575,9 +575,9 @@ sinkResponseFile
|
||||||
sinkResponseFile meterupdate iv initialp file mode resp = do
|
sinkResponseFile meterupdate iv initialp file mode resp = do
|
||||||
ui <- case (iv, mode) of
|
ui <- case (iv, mode) of
|
||||||
(Just iv', AppendMode) -> do
|
(Just iv', AppendMode) -> do
|
||||||
liftIO $ unableIncremental iv'
|
liftIO $ unableIncrementalVerifier iv'
|
||||||
return (const noop)
|
return (const noop)
|
||||||
(Just iv', _) -> return (updateIncremental iv')
|
(Just iv', _) -> return (updateIncrementalVerifier iv')
|
||||||
(Nothing, _) -> return (const noop)
|
(Nothing, _) -> return (const noop)
|
||||||
(fr, fh) <- allocate (openBinaryFile file mode) hClose
|
(fr, fh) <- allocate (openBinaryFile file mode) hClose
|
||||||
runConduit $ responseBody resp .| go ui initialp fh
|
runConduit $ responseBody resp .| go ui initialp fh
|
||||||
|
|
Loading…
Reference in a new issue