diff --git a/Main.hs b/Main.hs
--- a/Main.hs
+++ b/Main.hs
@@ -7,13 +7,20 @@
 import Data.Maybe (catMaybes)
 -- Where to save files
 import System.Directory (getCurrentDirectory)
+import Network.MIME.Info (mimeInfo)
 
 main :: IO ()
 main = do
     urls <- getArgs
+    print $ queryMIMEs urls
     let urls' = catMaybes $ map parseURI urls
     session <- newSession
     dir <- getCurrentDirectory
 
     res <- fetchURLs session ["*/*"] urls' $ saveDownload nullURI dir
     putStrLn $ show res
+
+queryMIMEs [] = []
+queryMIMEs (mime:mimes)
+    | ':' `notElem` mime && '/' `elem` mime = mimeInfo mime : queryMIMEs mimes
+    | otherwise = queryMIMEs mimes
diff --git a/hurl.cabal b/hurl.cabal
--- a/hurl.cabal
+++ b/hurl.cabal
@@ -10,7 +10,7 @@
 -- PVP summary:      +-+------- breaking API changes
 --                   | | +----- non-breaking API additions
 --                   | | | +--- code changes with no API change
-version:             2.0.0.0
+version:             2.1.0.0
 
 -- A short (one-line) description of the package.
 synopsis:            Haskell URL resolver
@@ -78,6 +78,11 @@
   Default:		True
   Manual: 		True
 
+Flag executables
+  Description:  Support executable plugins exposing a `ext:` URI scheme.
+  Default:      True
+  Manual:       True
+
 source-repository head
     type: git
     location: https://git.adrian.geek.nz/hurl.git
@@ -121,7 +126,7 @@
     build-depends: base64-bytestring >=1.0 && <2.0
   if flag(freedesktop)
     CPP-options:   -DWITH_XDG
-    build-depends: process >= 1.2 && <2.0, xml-conduit >=1.8, zlib >= 0.6 && < 0.7, containers
+    build-depends: xml-conduit >=1.8, zlib >= 0.6 && < 0.7, containers
     other-modules: Network.URI.XDG.Ini, Network.URI.XDG.MimeApps,
         Network.URI.XDG.DesktopEntry, Network.URI.XDG.MimeInfo, Network.URI.XDG,
         Network.URI.XDG.AppStream, Network.URI.XDG.AppStreamOutput
@@ -129,6 +134,9 @@
     CPP-options:   -DWITH_PLUGIN_REWRITES
     build-depends: regex, regex-tdfa >= 1.2 && < 1.4
     other-modules: Network.URI.PlugIns.Rewriters
+  if flag(executables)
+    CPP-options:   -DWITH_PLUGIN_EXEC
+    build-depends: process >= 1.2 && <2.0
 
 executable hurl
   -- .hs file containing the Main module
diff --git a/src/Network/MIME/Info.hs b/src/Network/MIME/Info.hs
--- a/src/Network/MIME/Info.hs
+++ b/src/Network/MIME/Info.hs
@@ -8,7 +8,7 @@
 import Network.URI.Types (Application(..))
 
 import qualified Data.Map as M
-import Control.Concurrent.MVar (MVar, newMVar, readMVar, putMVar)
+import Control.Concurrent.MVar (MVar, newMVar, readMVar, modifyMVar_)
 import System.IO.Unsafe (unsafePerformIO)
 import Data.Char (toLower)
 
@@ -25,7 +25,7 @@
     inner mime _ _ cache | Just val <- mime `M.lookup` cache = return val
     inner mime locales cache' cache = do
         ret <- readMimeInfo locales mime
-        putMVar cache' $ M.insert mime ret cache
+        modifyMVar_ cache' $ return . M.insert mime ret
         return ret
 
 #ifndef WITH_XDG
diff --git a/src/Network/URI/Fetch.hs b/src/Network/URI/Fetch.hs
--- a/src/Network/URI/Fetch.hs
+++ b/src/Network/URI/Fetch.hs
@@ -206,6 +206,7 @@
     | Just uri' <- applyRewriter (rewriter session) uri = fetchURL' session mimes uri'
 #endif
 
+#ifdef WITH_PLUGIN_EXEC
 fetchURL' session@Session { appName = appname, locale = l } mimes
         uri@(URI "ext:" Nothing path query _) = do
     dir <- getXdgDirectory XdgData "nz.geek.adrian.hurl"
@@ -236,6 +237,7 @@
     strip = dropWhile isSpace . dropWhileEnd isSpace
     isSuccess ExitSuccess = True
     isSuccess _ = False
+#endif
 
 fetchURL' session mimes uri@(URI {uriScheme = "about:", uriPath = ""}) =
     fetchURL' session mimes $ uri {uriPath = "version"}
diff --git a/src/Network/URI/Types.hs b/src/Network/URI/Types.hs
--- a/src/Network/URI/Types.hs
+++ b/src/Network/URI/Types.hs
@@ -7,4 +7,4 @@
     icon :: URI,
     description :: String,
     appId :: String -- internal
-}
+} deriving (Show)
diff --git a/src/Network/URI/XDG/MimeInfo.hs b/src/Network/URI/XDG/MimeInfo.hs
--- a/src/Network/URI/XDG/MimeInfo.hs
+++ b/src/Network/URI/XDG/MimeInfo.hs
@@ -16,15 +16,18 @@
 import Control.Exception (catch)
 import Data.Maybe (catMaybes, maybeToList, fromMaybe, mapMaybe)
 
+import System.Directory (getHomeDirectory)
+
 readMimeInfo :: [String] -> String -> IO Application
 readMimeInfo locales mime = do
     dirs <- lookupEnv "XDG_DATA_DIRS"
     homedir <- lookupEnv "XDG_DATA_HOME"
-    let dirs' = fromMaybe' "~/.local/share/" homedir :
+    cwd <- getHomeDirectory
+    let dirs' = fromMaybe' (cwd </> ".local/share/") homedir :
             split ':' (fromMaybe' "/usr/local/share/:/usr/share/" dirs)
 
     files <- forM dirs' $ \dir -> do
-        let file = dir </> mime <.> "xml"
+        let file = dir </> "mime" </> mime <.> "xml"
         exists <- doesFileExist file
         if exists then (Just <$> XML.readFile def file) `catch` handleBadXML else return Nothing
 
@@ -49,7 +52,7 @@
     }
   where
     readEl key attr fallback
-        | (val:_) <- [v | l <- locales ++ [""], v <- maybeToList $ lookup key els] = unpack val
+        | (val:_) <- [v | l <- locales ++ [""], v <- maybeToList $ lookup l els] = unpack val
         | otherwise = fallback
       where els = readEl' (pack key) attr $ elementNodes el
     readEl' key Nothing (NodeElement (Element name attrs childs):sibs)
