ip2location-io 1.5.1 → 1.5.2
raw patch · 4 files changed
+101/−5 lines, 4 filesdep ~network-uridep ~splitdep ~textPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: network-uri, split, text
API changes (from Hackage documentation)
+ HostedDomain: ErrorInfo :: Int -> String -> ErrorInfo
+ HostedDomain: ErrorObj :: ErrorInfo -> ErrorObj
+ HostedDomain: HostedError :: ErrorObj -> HostedResult
+ HostedDomain: HostedResponse :: ResponseObj -> HostedResult
+ HostedDomain: ResponseObj :: String -> Int -> Int -> Int -> Int -> [String] -> ResponseObj
+ HostedDomain: [domains] :: ResponseObj -> [String]
+ HostedDomain: [error] :: ErrorObj -> ErrorInfo
+ HostedDomain: [error_code] :: ErrorInfo -> Int
+ HostedDomain: [error_message] :: ErrorInfo -> String
+ HostedDomain: [ip] :: ResponseObj -> String
+ HostedDomain: [page] :: ResponseObj -> Int
+ HostedDomain: [per_page] :: ResponseObj -> Int
+ HostedDomain: [total_domains] :: ResponseObj -> Int
+ HostedDomain: [total_pages] :: ResponseObj -> Int
+ HostedDomain: data ErrorInfo
+ HostedDomain: data ErrorObj
+ HostedDomain: data HostedResult
+ HostedDomain: data ResponseObj
+ HostedDomain: instance Data.Aeson.Types.FromJSON.FromJSON HostedDomain.ErrorInfo
+ HostedDomain: instance Data.Aeson.Types.FromJSON.FromJSON HostedDomain.ErrorObj
+ HostedDomain: instance Data.Aeson.Types.FromJSON.FromJSON HostedDomain.HostedResult
+ HostedDomain: instance Data.Aeson.Types.FromJSON.FromJSON HostedDomain.ResponseObj
+ HostedDomain: instance GHC.Generics.Generic HostedDomain.ErrorInfo
+ HostedDomain: instance GHC.Generics.Generic HostedDomain.ErrorObj
+ HostedDomain: instance GHC.Generics.Generic HostedDomain.HostedResult
+ HostedDomain: instance GHC.Generics.Generic HostedDomain.ResponseObj
+ HostedDomain: instance GHC.Show.Show HostedDomain.ErrorInfo
+ HostedDomain: instance GHC.Show.Show HostedDomain.ErrorObj
+ HostedDomain: instance GHC.Show.Show HostedDomain.HostedResult
+ HostedDomain: instance GHC.Show.Show HostedDomain.ResponseObj
+ HostedDomain: lookUpHosted :: Config -> String -> Int -> IO HostedResult
Files
- ChangeLog.md +4/−0
- Configuration.hs +1/−1
- HostedDomain.hs +92/−0
- ip2location-io.cabal +4/−4
ChangeLog.md view
@@ -1,5 +1,9 @@ # Revision history for ip2location.io +## 1.5.2 -- 2026-11-06++* Fixed unexported module.+ ## 1.5.1 -- 2026-07-24 * Updated dependencies.
Configuration.hs view
@@ -28,4 +28,4 @@ -} open :: String -> IO Config open apikey = do - return (Config apikey "sdk-haskell-iplio" "1.5.1") + return (Config apikey "sdk-haskell-iplio" "1.5.2")
+ HostedDomain.hs view
@@ -0,0 +1,92 @@+{-# LANGUAGE DeriveGeneric,OverloadedStrings,DuplicateRecordFields #-} +{-| +Module : HostedDomain +Description : IP2Location.io Haskell package +Copyright : (c) IP2Location, 2026 +License : MIT +Maintainer : sales@ip2location.com +Stability : experimental + +This module allows users to query an IP address to get hosted domains info. + +IP2Location.io API subscription at https://www.ip2location.io +-} +module HostedDomain (HostedResult(..), ResponseObj(..), ErrorObj(..), ErrorInfo(..), lookUpHosted) where + +import Control.Exception +import System.Exit +import Data.Aeson as DA +import Data.Aeson.Types (Result(..), Parser) +import Network.HTTP.Client +import Network.HTTP.Client.TLS (tlsManagerSettings) +import Network.HTTP.Types.Header (hUserAgent) +import qualified Data.ByteString.Char8 as BS +import Network.HTTP.Types.Status (statusCode) +import Network.URI.Encode as URIE +import Configuration +import GHC.Generics (Generic) +import Control.Applicative ((<|>)) + +-- | Main response type +data ResponseObj = ResponseObj { + ip :: String, + total_domains :: Int, + page :: Int, + per_page :: Int, + total_pages :: Int, + domains :: [String] +} deriving (Show, Generic) + +-- | Define the error detail structure +data ErrorInfo = ErrorInfo { + error_code :: Int, + error_message :: String +} deriving (Show, Generic) + +-- | Define the error structure +data ErrorObj = ErrorObj { + error :: ErrorInfo +} deriving (Show, Generic) + +-- | Define the wrapper type for Response or Error +data HostedResult + = HostedResponse ResponseObj + | HostedError ErrorObj + deriving (Show, Generic) + +-- Derive FromJSON instances +instance FromJSON ResponseObj +instance FromJSON ErrorInfo +instance FromJSON ErrorObj +instance FromJSON HostedResult where + parseJSON v = + (HostedResponse <$> parseJSON v) <|> (HostedError <$> parseJSON v) + +{-| + The 'lookUpHosted' function returns an HostedResult containing hosted domains data for an IP address + It takes 3 arguments; the API configuration, either IPv4 or IPv6 address (String), page +-} +lookUpHosted :: Config -> String -> Int -> IO HostedResult +lookUpHosted myconfig ip page = do + let format = "json" + let mySource = source myconfig + let myVersion = version myconfig + let myKey = apiKey myconfig + + let url = "https://domains.ip2whois.com/domains?key=" ++ (URIE.encode myKey) ++ "&source=" ++ mySource ++ "&source-version=" ++ myVersion ++ "&format=" ++ format ++ "&ip=" ++ (URIE.encode ip) ++ "&page=" ++ show page + manager <- newManager tlsManagerSettings + + httprequest <- parseRequest url + + let request = httprequest { + requestHeaders = + [(hUserAgent, BS.pack (mySource ++ "/" ++ myVersion))] + } + + httpresponse <- httpLbs request manager + + let json = responseBody httpresponse + + case eitherDecode json of + Right result -> return result + Left err -> die("ERROR: " ++ err)
ip2location-io.cabal view
@@ -10,7 +10,7 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 1.5.1+version: 1.5.2 -- A short (one-line) description of the package. synopsis: IP2Location.io Haskell package for IP geolocation and domain WHOIS.@@ -51,7 +51,7 @@ library -- Modules exported by the library.- exposed-modules: IPGeolocation, DomainWhois, Configuration+ exposed-modules: IPGeolocation, DomainWhois, HostedDomain, Configuration -- Modules included in this library but not exported. -- other-modules: @@ -60,8 +60,8 @@ -- other-extensions: -- Other library packages from which modules are imported.- build-depends: base >=4.9 && <4.23, bytestring >=0.10 && <0.13, aeson >=1.5 && <2.4, http-types >=0.12 && <0.13, http-client >=0.6 && <0.8, http-client-tls >=0.3 && <0.5, uri-encode >=1.5 && <1.6, split <=0.2.5, text, network-uri- + build-depends: base >=4.9 && <4.23, bytestring >=0.10 && <0.13, aeson >=1.5 && <2.4, http-types >=0.12 && <0.13, http-client >=0.6 && <0.8, http-client-tls >=0.3 && <0.5, uri-encode >=1.5 && <1.6, split >=0.2.3 && <0.3, text >=1.2 && <2.2, network-uri >=2.6 && <2.7+ -- Directories containing source files. -- hs-source-dirs: