From f7a8c1d76fa7ee17b7a81db535639ca2be1b77e5 Mon Sep 17 00:00:00 2001 From: Adrian Cochrane Date: Fri, 17 Apr 2020 20:21:03 +1200 Subject: [PATCH] Improve data: URI handling, provide utility to convert other URIs to data: URIs. --- src/Network/URI/Fetch.hs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/Network/URI/Fetch.hs b/src/Network/URI/Fetch.hs index b0cf658..4ba8701 100644 --- a/src/Network/URI/Fetch.hs +++ b/src/Network/URI/Fetch.hs @@ -34,7 +34,7 @@ import Network.Connection #endif #ifdef WITH_DATA_URI -import qualified Data.ByteString.Base64 as B64 +import qualified Data.ByteString.Base64.URL.Lazy as B64 #endif import Network.URI.Locale @@ -196,9 +196,9 @@ fetchURL' _ (defaultMIME:_) uri@URI {uriScheme = "data:"} = in case breakOn ',' $ unEscapeString request of ("", response) -> return (uri, defaultMIME, Left $ Txt.pack response) (mime', response) | '4':'6':'e':'s':'a':'b':';':mime <- reverse mime' -> - return $ case B64.decode $ C8.pack response of - Left str -> (uri, "text/plain", Left $ Txt.pack str) - Right bytes -> (uri, reverse mime, Right $ B.fromStrict bytes) + return $ case B64.decode $ B.fromStrict $ C8.pack response of + Left str -> (uri, "text/plain", Left $ Txt.pack $ unEscapeString str) + Right bytes -> (uri, reverse mime, Right bytes) (mime, response) -> return (uri, mime, Left $ Txt.pack response) #endif @@ -222,6 +222,8 @@ dispatchByMIME Session {locale = l, apps = a} mime uri = do dispatchByMIME _ _ _ = return Nothing #endif +-- Downloads utilities +-- | 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) @@ -240,6 +242,17 @@ unusedFilename path = do exists <- doesFileExist path' if exists then go (n+1) else return path' +-- | Convert a download into a data: URI +downloadToURI :: (URI, String, Either Text ByteString) -> URI +downloadToURI (_, mime, Left txt) = nullURI { + uriScheme = "data:", + uriPath = mime ++ "," ++ escapeURIString isReserved (Txt.unpack txt) + } +downloadToURI (_, mime, Right bytes) = nullURI { + uriScheme = "data:", + uriPath = mime ++ ";base64," ++ C8.unpack (B.toStrict $ B64.encode bytes) + } + -- Utils #ifdef WITH_DATA_URI -- 2.30.2