@@ 3,7 3,7 @@
-- | Retrieves documents for a URL, supporting multiple URL schemes that can be
-- disabled at build-time for reduced dependencies.
module Network.URI.Fetch(Session(locale, aboutPages, redirectCount, cachingEnabled), newSession,
- fetchURL, fetchURL', fetchURLs, mimeERR, htmlERR,
+ fetchURL, fetchURL', fetchURLs, submitURL, mimeERR, htmlERR,
dispatchByMIME, appsForMIME, Application(..), dispatchByApp,
saveDownload, downloadToURI,
-- logging API
@@ 79,6 79,8 @@ import Network.URI.PlugIns.Rewriters
data Session = Session {
#ifdef WITH_HTTP_URI
managerHTTP :: HTTP.Manager,
+ globalCookieJar :: MVar HTTP.CookieJar,
+ cookiesPath :: FilePath,
#endif
#ifdef WITH_RAW_CONNECTIONS
connCtxt :: TLS.SSLContext,
@@ 128,6 130,14 @@ newSession' appname = do
TLS.contextSetCADirectory httpsCtxt "/etc/ssl/certs"
TLS.contextSetVerificationMode httpsCtxt $ TLS.VerifyPeer True True Nothing
managerHTTP' <- HTTP.newManager $ TLS.opensslManagerSettings $ return httpsCtxt
+
+ cookiesDir <- getXdgDirectory XdgData "nz.geek.adrian.hurl.cookies"
+ let cookiesPath' = cookiesDir </> appname
+ cookiesExist <- doesFileExist cookiesPath'
+ cookies <- if cookiesExist then readMaybe <$> readFile cookiesPath' else return Nothing
+ now <- getCurrentTime
+ let cookies' = HTTP.createCookieJar $ fromMaybe [] cookies
+ cookieJar <- newMVar $ HTTP.evictExpiredCookies cookies' now
#endif
#ifdef WITH_RAW_CONNECTIONS
connCtxt <- TLS.context
@@ 146,6 156,8 @@ newSession' appname = do
return Session {
#ifdef WITH_HTTP_URI
managerHTTP = managerHTTP',
+ globalCookieJar = cookieJar,
+ cookiesPath = cookiesPath',
#endif
#ifdef WITH_RAW_CONNECTIONS
connCtxt = connCtxt,
@@ 199,10 211,13 @@ htmlERR = "html/x-error\t"
submitURL :: Session -> [String] -> URI -> Text -> String -> IO (URI, String, Either Text ByteString)
#ifdef WITH_HTTP_URI
submitURL session accept uri "POST" query | uriScheme uri `elem` ["http:", "https:"] =
- fetchHTTPCached session accept uri $ \req -> req {
+ fetchHTTPCached session accept uri (\req -> req {
HTTP.method = "POST",
HTTP.requestBody = HTTP.RequestBodyBS $ C8.pack query
- }
+ }) $ \resp -> do
+ let cookies = HTTP.responseCookieJar resp
+ putMVar (globalCookieJar session) cookies
+ writeFile (cookiesPath session) $ show $ HTTP.destroyCookieJar cookies
#endif
submitURL session mimes uri _method query = fetchURL' session mimes uri { uriQuery = '?':query }
@@ 259,7 274,7 @@ fetchURL' Session {aboutPages = pages} _ url@URI {uriScheme = "about:", uriPath
#ifdef WITH_HTTP_URI
fetchURL' session accept uri | uriScheme uri `elem` ["http:", "https:"] =
- fetchHTTPCached session accept uri id
+ fetchHTTPCached session accept uri id (\_ -> return ())
#endif
#ifdef WITH_GEMINI_URI
@@ 361,14 376,15 @@ dispatchByApp _ _ _ _ = return False
#endif
#ifdef WITH_HTTP_URI
-fetchHTTPCached session accept@(defaultMIME:_) uri cb = do
+fetchHTTPCached session accept@(defaultMIME:_) uri cbReq cbResp = do
cached <- if cachingEnabled session then readCacheHTTP uri else return (Nothing, Nothing)
response <- case cached of
(Just (mime, body), Nothing) -> return $ Right (mime, body)
(cached, cachingHeaders) -> do
request <- HTTP.requestFromURI uri
- let request' = cb request {
- HTTP.cookieJar = Nothing, -- Will only be supported by Rhapsode when submitting a form.
+ cookieJar <- readMVar $ globalCookieJar session
+ let request' = cbReq request {
+ HTTP.cookieJar = Just $ cookieJar,
HTTP.requestHeaders = [
("Accept", C8.pack $ intercalate ", " accept),
("Accept-Language", C8.pack $ intercalate ", " $ locale session)
@@ 376,6 392,7 @@ fetchHTTPCached session accept@(defaultMIME:_) uri cb = do
HTTP.redirectCount = 0
}
response <- HTTP.httpLbs request $ managerHTTP session
+ cbResp response
case (
HTTP.responseStatus response,
HTTP.responseBody response,
@@ 406,7 423,7 @@ fetchHTTPCached session accept@(defaultMIME:_) uri cb = do
let mime' = L.map (Txt.unpack . Txt.strip) $ Txt.splitOn ";" mime
in return $ resolveCharset' uri mime' body
`catch` \e -> do return (uri, mimeERR, Left $ Txt.pack $ trans (locale session) $ Http e)
-fetchHTTPCached session [] uri cb =
+fetchHTTPCached session [] uri _ _ =
return (uri, mimeERR, Left $ Txt.pack $ trans (locale session) $ UnsupportedMIME "")
#endif