Skip to content

Commit b1fa05f

Browse files
committed
Better hash check exceptions
1 parent a6b2b7a commit b1fa05f

File tree

1 file changed

+26
-18
lines changed

1 file changed

+26
-18
lines changed

src/Network/HTTP/Download/Verified.hs

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -72,29 +72,35 @@ type LengthCheck = Int
7272
-- | An exception regarding verification of a download.
7373
data VerifiedDownloadException
7474
= WrongContentLength
75+
Request
7576
Int -- expected
7677
ByteString -- actual (as listed in the header)
7778
| WrongStreamLength
79+
Request
7880
Int -- expected
7981
Int -- actual
8082
| WrongDigest
83+
Request
8184
String -- algorithm
8285
CheckHexDigest -- expected
8386
String -- actual (shown)
8487
deriving (Typeable)
8588
instance Show VerifiedDownloadException where
86-
show (WrongContentLength expected actual) =
89+
show (WrongContentLength req expected actual) =
8790
"Download expectation failure: ContentLength header\n"
8891
++ "Expected: " ++ show expected ++ "\n"
89-
++ "Actual: " ++ displayByteString actual
90-
show (WrongStreamLength expected actual) =
92+
++ "Actual: " ++ displayByteString actual ++ "\n"
93+
++ "For: " ++ show (getUri req)
94+
show (WrongStreamLength req expected actual) =
9195
"Download expectation failure: download size\n"
9296
++ "Expected: " ++ show expected ++ "\n"
93-
++ "Actual: " ++ show actual
94-
show (WrongDigest algo expected actual) =
97+
++ "Actual: " ++ show actual ++ "\n"
98+
++ "For: " ++ show (getUri req)
99+
show (WrongDigest req algo expected actual) =
95100
"Download expectation failure: content hash (" ++ algo ++ ")\n"
96101
++ "Expected: " ++ displayCheckHexDigest expected ++ "\n"
97-
++ "Actual: " ++ actual
102+
++ "Actual: " ++ actual ++ "\n"
103+
++ "For: " ++ show (getUri req)
98104

99105
instance Exception VerifiedDownloadException
100106

@@ -125,9 +131,10 @@ displayCheckHexDigest (CheckHexDigestHeader h) =
125131
--
126132
-- Throws WrongDigest (VerifiedDownloadException)
127133
sinkCheckHash :: MonadThrow m
128-
=> HashCheck
134+
=> Request
135+
-> HashCheck
129136
-> Consumer ByteString m ()
130-
sinkCheckHash HashCheck{..} = do
137+
sinkCheckHash req HashCheck{..} = do
131138
digest <- sinkHashUsing hashCheckAlgorithm
132139
let actualDigestString = show digest
133140
let actualDigestHexByteString = digestToHexByteString digest
@@ -142,23 +149,24 @@ sinkCheckHash HashCheck{..} = do
142149
|| b == actualDigestHexByteString
143150

144151
when (not passedCheck) $
145-
throwM $ WrongDigest (show hashCheckAlgorithm) hashCheckHexDigest actualDigestString
152+
throwM $ WrongDigest req (show hashCheckAlgorithm) hashCheckHexDigest actualDigestString
146153

147154
assertLengthSink :: MonadThrow m
148-
=> LengthCheck
155+
=> Request
156+
-> LengthCheck
149157
-> ZipSink ByteString m ()
150-
assertLengthSink expectedStreamLength = ZipSink $ do
158+
assertLengthSink req expectedStreamLength = ZipSink $ do
151159
Sum actualStreamLength <- CL.foldMap (Sum . ByteString.length)
152160
when (actualStreamLength /= expectedStreamLength) $
153-
throwM $ WrongStreamLength expectedStreamLength actualStreamLength
161+
throwM $ WrongStreamLength req expectedStreamLength actualStreamLength
154162

155163
-- | A more explicitly type-guided sinkHash.
156164
sinkHashUsing :: (Monad m, HashAlgorithm a) => a -> Consumer ByteString m (Digest a)
157165
sinkHashUsing _ = sinkHash
158166

159167
-- | Turns a list of hash checks into a ZipSink that checks all of them.
160-
hashChecksToZipSink :: MonadThrow m => [HashCheck] -> ZipSink ByteString m ()
161-
hashChecksToZipSink = traverse_ (ZipSink . sinkCheckHash)
168+
hashChecksToZipSink :: MonadThrow m => Request -> [HashCheck] -> ZipSink ByteString m ()
169+
hashChecksToZipSink req = traverse_ (ZipSink . sinkCheckHash req)
162170

163171
-- | Copied and extended version of Network.HTTP.Download.download.
164172
--
@@ -215,7 +223,7 @@ verifiedDownload DownloadRequest{..} destpath progressSink = do
215223

216224
checkExpectations = bracket (openFile fp ReadMode) hClose $ \h -> do
217225
whenJust drLengthCheck $ checkFileSizeExpectations h
218-
sourceHandle h $$ getZipSink (hashChecksToZipSink drHashChecks)
226+
sourceHandle h $$ getZipSink (hashChecksToZipSink drRequest drHashChecks)
219227

220228
-- doesn't move the handle
221229
checkFileSizeExpectations h expectedFileSize = do
@@ -231,7 +239,7 @@ verifiedDownload DownloadRequest{..} destpath progressSink = do
231239
Just lengthBS -> do
232240
let lengthStr = displayByteString lengthBS
233241
when (lengthStr /= show expectedContentLength) $
234-
throwM $ WrongContentLength expectedContentLength lengthBS
242+
throwM $ WrongContentLength drRequest expectedContentLength lengthBS
235243
_ -> return ()
236244

237245
go h res = do
@@ -250,7 +258,7 @@ verifiedDownload DownloadRequest{..} destpath progressSink = do
250258
responseBody res
251259
$= maybe (awaitForever yield) CB.isolate drLengthCheck
252260
$$ getZipSink
253-
( hashChecksToZipSink hashChecks
254-
*> maybe (pure ()) assertLengthSink drLengthCheck
261+
( hashChecksToZipSink drRequest hashChecks
262+
*> maybe (pure ()) (assertLengthSink drRequest) drLengthCheck
255263
*> ZipSink (sinkHandle h)
256264
*> ZipSink progressSink)

0 commit comments

Comments
 (0)