@@ 9,11 9,13 @@ module Network.URI.Fetch(Session, locale, newSession,
import qualified Data.Text as Txt
import Data.Text (Text)
import Network.URI
+import qualified Data.ByteString as Strict
import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Lazy as B
import qualified Data.ByteString.Char8 as C8
import Network.URI.Charset
import Control.Exception
+import System.IO.Error (isEOFError)
import Control.Concurrent.Async (forConcurrently)
-- for about: URIs & port parsing, all standard lib
@@ 170,7 172,8 @@ fetchURL' sess@Session {connCtxt = ctxt, locale = l} mimes uri@URI {
"</label><input id='input' /></form>"
])
('2', _, mime) -> do
- chunks <- mWhile (connectionWaitForInput conn 60000) $ connectionGetChunk conn
+ chunks <- mWhile (connectionWaitForInput conn 60000 `catch` (return . not . isEOFError)) $
+ (connectionGetChunk conn `catch` handleIOErr)
let mime' = map (Txt.unpack . Txt.strip) $ Txt.splitOn ";" mime
return $ resolveCharset' uri mime' $ B.fromChunks chunks
('3', _, redirect) | Just redirect' <- parseURIReference $ Txt.unpack redirect ->
@@ 185,6 188,8 @@ fetchURL' sess@Session {connCtxt = ctxt, locale = l} mimes uri@URI {
| Just (major, header') <- Txt.uncons $ convertCharset "utf-8" header,
Just (minor, meta) <- Txt.uncons header' = (major, minor, Txt.strip meta)
| otherwise = ('4', '1', Txt.pack $ trans l MalformedResponse)
+ handleIOErr :: IOError -> IO Strict.ByteString
+ handleIOErr _ = return ""
#endif
#ifdef WITH_FILE_URI
@@ 232,12 237,14 @@ dispatchByMIME _ _ _ = return Nothing
-- | write download to a file in the given directory.
saveDownload :: URI -> FilePath -> (URI, String, Either Text ByteString) -> IO URI
saveDownload baseURI dir (URI {uriPath = path}, mime, resp) = do
- dest <- unusedFilename (dir </> takeFileName path)
+ dest <- unusedFilename (dir </> takeFileName' path)
case resp of
Left txt -> writeFile dest $ Txt.unpack txt
Right bytes -> B.writeFile dest bytes
-- TODO set user.mime file attribute.
return $ baseURI {uriPath = dest}
+ where
+ takeFileName' s = case takeFileName s of { "" -> "index"; f -> f}
unusedFilename path = do
exists <- doesFileExist path