{-# LANGUAGE ForeignFunctionInterface #-}
module Network.Curl.Info
( Info(..)
, InfoValue(..)
, getInfo
) where
import Network.Curl.Types
import Network.Curl.Code
import Control.Monad
import Foreign.Ptr
import Foreign.Marshal.Alloc
import Foreign.Storable
import Foreign.C
data Info
= EffectiveUrl
| ResponseCode
| TotalTime
| NameLookupTime
| ConnectTime
| PreTransferTime
| SizeUpload
| SizeDownload
| SpeedDownload
| SpeedUpload
|
| RequestSize
| SslVerifyResult
| Filetime
| ContentLengthDownload
| ContentLengthUpload
| StartTransferTime
| ContentType
| RedirectTime
| RedirectCount
| Private
| HttpConnectCode
| HttpAuthAvail
| ProxyAuthAvail
| OSErrno
| NumConnects
| SslEngines
| CookieList
| LastSocket
| FtpEntryPath
deriving (Int -> Info -> ShowS
[Info] -> ShowS
Info -> String
(Int -> Info -> ShowS)
-> (Info -> String) -> ([Info] -> ShowS) -> Show Info
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Info] -> ShowS
$cshowList :: [Info] -> ShowS
show :: Info -> String
$cshow :: Info -> String
showsPrec :: Int -> Info -> ShowS
$cshowsPrec :: Int -> Info -> ShowS
Show,Int -> Info
Info -> Int
Info -> [Info]
Info -> Info
Info -> Info -> [Info]
Info -> Info -> Info -> [Info]
(Info -> Info)
-> (Info -> Info)
-> (Int -> Info)
-> (Info -> Int)
-> (Info -> [Info])
-> (Info -> Info -> [Info])
-> (Info -> Info -> [Info])
-> (Info -> Info -> Info -> [Info])
-> Enum Info
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Info -> Info -> Info -> [Info]
$cenumFromThenTo :: Info -> Info -> Info -> [Info]
enumFromTo :: Info -> Info -> [Info]
$cenumFromTo :: Info -> Info -> [Info]
enumFromThen :: Info -> Info -> [Info]
$cenumFromThen :: Info -> Info -> [Info]
enumFrom :: Info -> [Info]
$cenumFrom :: Info -> [Info]
fromEnum :: Info -> Int
$cfromEnum :: Info -> Int
toEnum :: Int -> Info
$ctoEnum :: Int -> Info
pred :: Info -> Info
$cpred :: Info -> Info
succ :: Info -> Info
$csucc :: Info -> Info
Enum,Info
Info -> Info -> Bounded Info
forall a. a -> a -> Bounded a
maxBound :: Info
$cmaxBound :: Info
minBound :: Info
$cminBound :: Info
Bounded)
data InfoValue
= IString String
| ILong Long
| IDouble Double
| IList [String]
instance Show InfoValue where
show :: InfoValue -> String
show k :: InfoValue
k =
case InfoValue
k of
IString s :: String
s -> String
s
ILong l :: Long
l -> Long -> String
forall a. Show a => a -> String
show Long
l
IDouble d :: Double
d -> Double -> String
forall a. Show a => a -> String
show Double
d
IList ss :: [String]
ss -> [String] -> String
forall a. Show a => a -> String
show [String]
ss
getInfo :: Curl -> Info -> IO InfoValue
getInfo :: Curl -> Info -> IO InfoValue
getInfo h :: Curl
h i :: Info
i = do
case Info
i of
EffectiveUrl -> Curl -> String -> Long -> IO InfoValue
getInfoStr Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 1
ResponseCode -> Curl -> String -> Long -> IO InfoValue
getInfoLong Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 2
TotalTime -> Curl -> String -> Long -> IO InfoValue
getInfoDouble Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 3
NameLookupTime -> Curl -> String -> Long -> IO InfoValue
getInfoDouble Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 4
ConnectTime -> Curl -> String -> Long -> IO InfoValue
getInfoDouble Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 5
PreTransferTime -> Curl -> String -> Long -> IO InfoValue
getInfoDouble Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 6
SizeUpload -> Curl -> String -> Long -> IO InfoValue
getInfoDouble Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 7
SizeDownload -> Curl -> String -> Long -> IO InfoValue
getInfoDouble Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 8
SpeedDownload -> Curl -> String -> Long -> IO InfoValue
getInfoDouble Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 9
SpeedUpload -> Curl -> String -> Long -> IO InfoValue
getInfoDouble Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 10
HeaderSize -> Curl -> String -> Long -> IO InfoValue
getInfoLong Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 11
RequestSize -> Curl -> String -> Long -> IO InfoValue
getInfoLong Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 12
SslVerifyResult -> Curl -> String -> Long -> IO InfoValue
getInfoLong Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 13
Filetime -> Curl -> String -> Long -> IO InfoValue
getInfoLong Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 14
ContentLengthDownload -> Curl -> String -> Long -> IO InfoValue
getInfoDouble Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 15
ContentLengthUpload -> Curl -> String -> Long -> IO InfoValue
getInfoDouble Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 16
StartTransferTime -> Curl -> String -> Long -> IO InfoValue
getInfoDouble Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 17
ContentType -> Curl -> String -> Long -> IO InfoValue
getInfoStr Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 18
RedirectTime -> Curl -> String -> Long -> IO InfoValue
getInfoDouble Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 19
RedirectCount -> Curl -> String -> Long -> IO InfoValue
getInfoLong Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 20
Private -> Curl -> String -> Long -> IO InfoValue
getInfoStr Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 21
HttpConnectCode -> Curl -> String -> Long -> IO InfoValue
getInfoLong Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 22
HttpAuthAvail -> Curl -> String -> Long -> IO InfoValue
getInfoLong Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 23
ProxyAuthAvail -> Curl -> String -> Long -> IO InfoValue
getInfoLong Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 24
OSErrno -> Curl -> String -> Long -> IO InfoValue
getInfoLong Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 25
NumConnects -> Curl -> String -> Long -> IO InfoValue
getInfoLong Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 26
SslEngines -> Curl -> String -> Long -> IO InfoValue
getInfoSList Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 27
CookieList -> Curl -> String -> Long -> IO InfoValue
getInfoSList Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 28
LastSocket -> Curl -> String -> Long -> IO InfoValue
getInfoLong Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 29
FtpEntryPath -> Curl -> String -> Long -> IO InfoValue
getInfoStr Curl
h (Info -> String
forall a. Show a => a -> String
show Info
i) 30
getInfoStr :: Curl -> String -> Long -> IO InfoValue
getInfoStr :: Curl -> String -> Long -> IO InfoValue
getInfoStr h :: Curl
h loc :: String
loc tg :: Long
tg =
(Ptr CString -> IO InfoValue) -> IO InfoValue
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CString -> IO InfoValue) -> IO InfoValue)
-> (Ptr CString -> IO InfoValue) -> IO InfoValue
forall a b. (a -> b) -> a -> b
$ \ ps :: Ptr CString
ps -> do
CInt
rc <- Curl -> (IORef OptionMap -> CurlH -> IO CInt) -> IO CInt
forall a. Curl -> (IORef OptionMap -> CurlH -> IO a) -> IO a
curlPrim Curl
h ((IORef OptionMap -> CurlH -> IO CInt) -> IO CInt)
-> (IORef OptionMap -> CurlH -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \_ p :: CurlH
p -> CurlH -> Long -> Ptr CString -> IO CInt
easy_getinfo_str CurlH
p Long
tg Ptr CString
ps
case CInt
rc of
0 -> do
CString
s <- Ptr CString -> IO CString
forall a. Storable a => Ptr a -> IO a
peek Ptr CString
ps
if CString
s CString -> CString -> Bool
forall a. Eq a => a -> a -> Bool
== CString
forall a. Ptr a
nullPtr
then InfoValue -> IO InfoValue
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> InfoValue
IString "")
else (String -> InfoValue) -> IO String -> IO InfoValue
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM String -> InfoValue
IString (IO String -> IO InfoValue) -> IO String -> IO InfoValue
forall a b. (a -> b) -> a -> b
$ CString -> IO String
peekCString CString
s
_ -> String -> IO InfoValue
forall (m :: * -> *) a. MonadFail m => String -> m a
fail ("getInfo{"String -> ShowS
forall a. [a] -> [a] -> [a]
++String
loc String -> ShowS
forall a. [a] -> [a] -> [a]
++ "}: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ CurlCode -> String
forall a. Show a => a -> String
show (CInt -> CurlCode
toCode CInt
rc))
getInfoLong :: Curl -> String -> Long -> IO InfoValue
getInfoLong :: Curl -> String -> Long -> IO InfoValue
getInfoLong h :: Curl
h loc :: String
loc tg :: Long
tg =
(Ptr Long -> IO InfoValue) -> IO InfoValue
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Long -> IO InfoValue) -> IO InfoValue)
-> (Ptr Long -> IO InfoValue) -> IO InfoValue
forall a b. (a -> b) -> a -> b
$ \ pl :: Ptr Long
pl -> do
CInt
rc <- Curl -> (IORef OptionMap -> CurlH -> IO CInt) -> IO CInt
forall a. Curl -> (IORef OptionMap -> CurlH -> IO a) -> IO a
curlPrim Curl
h ((IORef OptionMap -> CurlH -> IO CInt) -> IO CInt)
-> (IORef OptionMap -> CurlH -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \_ p :: CurlH
p -> CurlH -> Long -> Ptr Long -> IO CInt
easy_getinfo_long CurlH
p Long
tg Ptr Long
pl
case CInt
rc of
0 -> do
Long
l <- Ptr Long -> IO Long
forall a. Storable a => Ptr a -> IO a
peek Ptr Long
pl
InfoValue -> IO InfoValue
forall (m :: * -> *) a. Monad m => a -> m a
return (Long -> InfoValue
ILong Long
l)
_ -> String -> IO InfoValue
forall (m :: * -> *) a. MonadFail m => String -> m a
fail ("getInfo{"String -> ShowS
forall a. [a] -> [a] -> [a]
++String
loc String -> ShowS
forall a. [a] -> [a] -> [a]
++ "}: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ CurlCode -> String
forall a. Show a => a -> String
show (CInt -> CurlCode
toCode CInt
rc))
getInfoDouble :: Curl -> String -> Long -> IO InfoValue
getInfoDouble :: Curl -> String -> Long -> IO InfoValue
getInfoDouble h :: Curl
h loc :: String
loc tg :: Long
tg =
(Ptr Double -> IO InfoValue) -> IO InfoValue
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Double -> IO InfoValue) -> IO InfoValue)
-> (Ptr Double -> IO InfoValue) -> IO InfoValue
forall a b. (a -> b) -> a -> b
$ \ pd :: Ptr Double
pd -> do
CInt
rc <- Curl -> (IORef OptionMap -> CurlH -> IO CInt) -> IO CInt
forall a. Curl -> (IORef OptionMap -> CurlH -> IO a) -> IO a
curlPrim Curl
h ((IORef OptionMap -> CurlH -> IO CInt) -> IO CInt)
-> (IORef OptionMap -> CurlH -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \_ p :: CurlH
p -> CurlH -> Long -> Ptr Double -> IO CInt
easy_getinfo_double CurlH
p Long
tg Ptr Double
pd
case CInt
rc of
0 -> do
Double
d <- Ptr Double -> IO Double
forall a. Storable a => Ptr a -> IO a
peek Ptr Double
pd
InfoValue -> IO InfoValue
forall (m :: * -> *) a. Monad m => a -> m a
return (Double -> InfoValue
IDouble Double
d)
_ -> String -> IO InfoValue
forall (m :: * -> *) a. MonadFail m => String -> m a
fail ("getInfo{"String -> ShowS
forall a. [a] -> [a] -> [a]
++String
loc String -> ShowS
forall a. [a] -> [a] -> [a]
++ "}: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ CurlCode -> String
forall a. Show a => a -> String
show (CInt -> CurlCode
toCode CInt
rc))
getInfoSList :: Curl -> String -> Long -> IO InfoValue
getInfoSList :: Curl -> String -> Long -> IO InfoValue
getInfoSList h :: Curl
h loc :: String
loc tg :: Long
tg =
(Ptr (Ptr CString) -> IO InfoValue) -> IO InfoValue
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr (Ptr CString) -> IO InfoValue) -> IO InfoValue)
-> (Ptr (Ptr CString) -> IO InfoValue) -> IO InfoValue
forall a b. (a -> b) -> a -> b
$ \ ps :: Ptr (Ptr CString)
ps -> do
CInt
rc <- Curl -> (IORef OptionMap -> CurlH -> IO CInt) -> IO CInt
forall a. Curl -> (IORef OptionMap -> CurlH -> IO a) -> IO a
curlPrim Curl
h ((IORef OptionMap -> CurlH -> IO CInt) -> IO CInt)
-> (IORef OptionMap -> CurlH -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \_ p :: CurlH
p -> CurlH -> Long -> Ptr (Ptr CString) -> IO CInt
easy_getinfo_slist CurlH
p Long
tg Ptr (Ptr CString)
ps
case CInt
rc of
0 -> do
Ptr CString
p <- Ptr (Ptr CString) -> IO (Ptr CString)
forall a. Storable a => Ptr a -> IO a
peek Ptr (Ptr CString)
ps
[String]
ls <- Ptr CString -> IO [String]
forall b. Ptr b -> IO [String]
unmarshallList Ptr CString
p
InfoValue -> IO InfoValue
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> InfoValue
IList [String]
ls)
_ -> String -> IO InfoValue
forall (m :: * -> *) a. MonadFail m => String -> m a
fail ("getInfo{"String -> ShowS
forall a. [a] -> [a] -> [a]
++String
loc String -> ShowS
forall a. [a] -> [a] -> [a]
++ "}: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ CurlCode -> String
forall a. Show a => a -> String
show (CInt -> CurlCode
toCode CInt
rc))
where
unmarshallList :: Ptr b -> IO [String]
unmarshallList ptr :: Ptr b
ptr
| Ptr b
ptr Ptr b -> Ptr b -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr b
forall a. Ptr a
nullPtr = [String] -> IO [String]
forall (m :: * -> *) a. Monad m => a -> m a
return []
| Bool
otherwise = do
CString
ps <- Ptr b -> Int -> IO CString
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr b
ptr 0
String
s <- if CString
ps CString -> CString -> Bool
forall a. Eq a => a -> a -> Bool
== CString
forall a. Ptr a
nullPtr then String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return "" else CString -> IO String
peekCString CString
ps
Ptr b
nx <- Ptr b -> Int -> IO (Ptr b)
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr b
ptr (Ptr Any -> Int
forall a. Storable a => a -> Int
sizeOf Ptr Any
forall a. Ptr a
nullPtr)
[String]
ls <- Ptr b -> IO [String]
unmarshallList Ptr b
nx
[String] -> IO [String]
forall (m :: * -> *) a. Monad m => a -> m a
return (String
sString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
ls)
foreign import ccall
"curl_easy_getinfo_long" easy_getinfo_long :: CurlH -> Long -> Ptr Long -> IO CInt
foreign import ccall
"curl_easy_getinfo_string" easy_getinfo_str :: CurlH -> Long -> Ptr CString -> IO CInt
foreign import ccall
"curl_easy_getinfo_double" easy_getinfo_double :: CurlH -> Long -> Ptr Double -> IO CInt
foreign import ccall
"curl_easy_getinfo_slist" easy_getinfo_slist :: CurlH -> Long -> Ptr (Ptr (Ptr CChar)) -> IO CInt