Reputation: 597
I want to get the user IPv4
and/or IPv6
to use on GeoIp2.
How to get it?
----- EDIT --------
Like if the user access my site i want to check what is their IP Address once i get that I want to use the GeoIp2 to locate them.
the example below has a default IPv4 and IPv6 address:
{-# LANGUAGE OverloadedStrings #-}
import Data.GeoIP2
import Data.IP (IP(..))
main = do
geodb <- openGeoDB "GeoLite2-City.mmdb"
let ip = IPv4 "23.253.242.70"
print $ (findGeoData geodb "en" ip :: Maybe GeoResult)
let ip2 = IPv6 "2001:4800:7817:104:be76:4eff:fe04:f608"
print $ (findGeoData geodb "en" ip2 :: Maybe GeoResult)
hope that helps
Upvotes: 2
Views: 521
Reputation: 7707
This should work:
import Network.Wai (remoteHost) -- From the wai package
import Data.IP -- From the iproute package
import Network.Socket.Internal (SockAddr(..)) -- From the network package
sockAddrToIP :: SockAddr -> IP
sockAddrToIP sockAddr = case sockAddr of
SockAddrInet _port hostAddress -> IPv4 $ fromHostAddress hostAddress
SockAddrInet6 _port _flowInfo hostAddress6 _scopeID -> IPv6 $ fromHostAddress6 hostAddress6
-- I don't know how to handle these, they might not apply to the web?
SockAddrUnix _ -> error "Couldn't get IP address"
SockAddrCan _ -> error "Couldn't get IP address"
getHomeR :: Handler Html
getHomeR = do
host <- remoteHost <$> waiRequest
let ip = sockAddrToIP host
traceShowM $ "Remote host is " ++ show host
traceShowM $ "IP is " ++ show ip
-- (Finish implementing the handler here)
When I run this locally, I get:
"Remote host is 127.0.0.1:54575"
"IP is 127.0.0.1"
I actually don't know much about networking or IP addresses or anything, but the types line up and the code appears to be working. If someone could verify that SockAddrUnix
and SockAddrCan
can be ignored, that'd be good.
Upvotes: 4