88{-# LANGUAGE RankNTypes #-}
99{-# LANGUAGE GADTs #-}
1010{-# LANGUAGE StandaloneDeriving #-}
11+ {-# LANGUAGE TemplateHaskell #-}
1112module Network.HTTP.Download.Verified
1213 ( verifiedDownload
1314 , recoveringHttp
@@ -19,38 +20,41 @@ module Network.HTTP.Download.Verified
1920 , VerifiedDownloadException (.. )
2021 ) where
2122
22- import qualified Data.List as List
23- import qualified Data.ByteString as ByteString
24- import qualified Data.ByteString.Base64 as B64
25- import qualified Data.Conduit.Binary as CB
26- import qualified Data.Conduit.List as CL
27- import qualified Data.Text as Text
28- import qualified Data.Text.Encoding as Text
23+ import qualified Data.List as List
24+ import qualified Data.ByteString as ByteString
25+ import qualified Data.ByteString.Base64 as B64
26+ import qualified Data.Conduit.Binary as CB
27+ import qualified Data.Conduit.List as CL
28+ import qualified Data.Text as Text
29+ import qualified Data.Text.Encoding as Text
2930
30- import Control.Monad
31- import Control.Monad.Catch
32- import Control.Monad.IO.Class
33- import Control.Monad.Reader
34- import Control.Retry (recovering ,limitRetries ,RetryPolicy ,constantDelay )
35- import Control.Applicative
31+ import Control.Applicative
32+ import Control.Monad
33+ import Control.Monad.Catch
34+ import Control.Monad.IO.Class
35+ import Control.Monad.Logger (logDebug , MonadLogger )
36+ import Control.Monad.Reader
37+ import Control.Retry (recovering ,limitRetries ,RetryPolicy ,constantDelay )
3638import "cryptohash" Crypto.Hash
37- import Crypto.Hash.Conduit (sinkHash )
38- import Data.ByteString (ByteString )
39- import Data.ByteString.Char8 (readInteger )
40- import Data.Conduit
41- import Data.Conduit.Binary (sourceHandle , sinkHandle )
42- import Data.Foldable (traverse_ ,for_ )
43- import Data.Monoid
44- import Data.String
45- import Data.Typeable (Typeable )
46- import GHC.IO.Exception (IOException (.. ),IOErrorType (.. ))
47- import Network.HTTP.Client.Conduit
48- import Network.HTTP.Types.Header (hContentLength , hContentMD5 )
49- import Path
50- import Prelude -- Fix AMP warning
51- import System.FilePath ((<.>) )
52- import System.Directory
53- import System.IO
39+ import Crypto.Hash.Conduit (sinkHash )
40+ import Data.ByteString (ByteString )
41+ import Data.ByteString.Char8 (readInteger )
42+ import Data.Conduit
43+ import Data.Conduit.Binary (sourceHandle , sinkHandle )
44+ import Data.Foldable (traverse_ ,for_ )
45+ import Data.Monoid
46+ import Data.String
47+ import Data.Text.Encoding (decodeUtf8With )
48+ import Data.Text.Encoding.Error (lenientDecode )
49+ import Data.Typeable (Typeable )
50+ import GHC.IO.Exception (IOException (.. ),IOErrorType (.. ))
51+ import Network.HTTP.Client.Conduit
52+ import Network.HTTP.Types.Header (hContentLength , hContentMD5 )
53+ import Path
54+ import Prelude -- Fix AMP warning
55+ import System.Directory
56+ import System.FilePath ((<.>) )
57+ import System.IO
5458
5559-- | A request together with some checks to perform.
5660data DownloadRequest = DownloadRequest
@@ -215,21 +219,23 @@ recoveringHttp retryPolicy =
215219-- Throws VerifiedDownloadException.
216220-- Throws IOExceptions related to file system operations.
217221-- Throws HttpException.
218- verifiedDownload :: (MonadReader env m , HasHttpManager env , MonadIO m )
222+ verifiedDownload :: (MonadReader env m , HasHttpManager env , MonadIO m , MonadLogger m )
219223 => DownloadRequest
220224 -> Path Abs File -- ^ destination
221225 -> (Maybe Integer -> Sink ByteString (ReaderT env IO ) () ) -- ^ custom hook to observe progress
222226 -> m Bool -- ^ Whether a download was performed
223227verifiedDownload DownloadRequest {.. } destpath progressSink = do
224228 let req = drRequest
225229 env <- ask
226- liftIO $ whenM' getShouldDownload $ do
227- createDirectoryIfMissing True dir
228- withBinaryFile fptmp WriteMode $ \ h ->
229- recoveringHttp drRetryPolicy $
230- flip runReaderT env $
231- withResponse req (go h)
232- renameFile fptmp fp
230+ whenM' (liftIO getShouldDownload) $ do
231+ $ logDebug $ " Downloading " <> decodeUtf8With lenientDecode (path req)
232+ liftIO $ do
233+ createDirectoryIfMissing True dir
234+ withBinaryFile fptmp WriteMode $ \ h ->
235+ recoveringHttp drRetryPolicy $
236+ flip runReaderT env $
237+ withResponse req (go h)
238+ renameFile fptmp fp
233239 where
234240 whenM' mp m = do
235241 p <- mp
0 commit comments