Skip to content

Commit 01a7405

Browse files
Added support for IP2Proxy Web Service
1 parent 41b8fc4 commit 01a7405

6 files changed

Lines changed: 222 additions & 5 deletions

File tree

ChangeLog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Revision history for ip2proxy
22

3+
## 3.2.0 -- 2021-10-07
4+
5+
* Added support for IP2Proxy Web Service.
6+
37
## 3.1.0 -- 2021-07-06
48

59
* Added provider field and exception handling for incorrect BIN database.

IP2Proxy.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ getMeta = do
117117
The 'getModuleVersion' function returns a string containing the module version.
118118
-}
119119
getModuleVersion :: String
120-
getModuleVersion = "3.1.0"
120+
getModuleVersion = "3.2.0"
121121

122122
{-|
123123
The 'getPackageVersion' function returns a string containing the package version.

IP2ProxyWebService.hs

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
{-# LANGUAGE OverloadedStrings,TemplateHaskell #-}
2+
{-|
3+
Module : IP2ProxyWebService
4+
Description : IP2Proxy Haskell package
5+
Copyright : (c) IP2Location, 2021
6+
License : MIT
7+
Maintainer : sales@ip2location.com
8+
Stability : experimental
9+
10+
This Haskell package allows users to query an IP address to determine if it was being used as open proxy, web proxy, VPN anonymizer and TOR exits.
11+
12+
IP2Proxy Web Service API subscription at https://www.ip2location.com/web-service/ip2proxy
13+
-}
14+
module IP2ProxyWebService (WSResult(..), WSConfig, openWS, lookUp, getCredit) where
15+
16+
import Control.Exception
17+
import System.Exit
18+
import Data.Aeson as DA
19+
import Data.Aeson.TH
20+
import Network.HTTP.Client
21+
import Network.HTTP.Client.TLS (tlsManagerSettings)
22+
import Network.HTTP.Types.Status (statusCode)
23+
import Data.Maybe
24+
import Network.URI.Encode as URIE
25+
-- import Text.Regex.Base
26+
-- import Text.Regex.TDFA
27+
28+
-- | Contains the web service configuration.
29+
data WSConfig = WSConfig {
30+
-- | Web service API key
31+
apiKey :: String,
32+
-- | API package
33+
apiPackage :: String,
34+
-- | Use SSL
35+
useSSL :: Bool
36+
} deriving (Show)
37+
38+
-- | Contains the web service results.
39+
data WSResult = WSResult {
40+
-- | Response status or error
41+
response :: String,
42+
-- | Country code
43+
countryCode :: Maybe String,
44+
-- | Country name
45+
countryName :: Maybe String,
46+
-- | Region name
47+
regionName :: Maybe String,
48+
-- | City name
49+
cityName :: Maybe String,
50+
-- | ISP name
51+
isp :: Maybe String,
52+
-- | Domain
53+
domain :: Maybe String,
54+
-- | Usage type
55+
usageType :: Maybe String,
56+
-- | Autonomous System Number
57+
asn :: Maybe String,
58+
-- | Autonomous System
59+
as :: Maybe String,
60+
-- | Proxy last seen in days
61+
lastSeen :: Maybe String,
62+
-- | Proxy type
63+
proxyType :: Maybe String,
64+
-- | Threat type
65+
threat :: Maybe String,
66+
-- | Whether is a proxy
67+
isProxy :: Maybe String,
68+
-- | VPN provider name
69+
provider :: Maybe String
70+
} deriving (Show, Eq)
71+
72+
$(deriveJSON defaultOptions ''WSResult)
73+
74+
checkparams :: String -> String -> IO String
75+
checkparams apikey apipackage = do
76+
return "OK"
77+
--- regex part commented out due to cabal dependency issues
78+
-- let apikeyok = apikey =~ ("^[0-9A-Z]{10}$" :: String) :: Bool
79+
-- if apikeyok == False
80+
-- then die(show "Invalid API key.")
81+
-- else do
82+
-- let apipackageok = apipackage =~ ("^PX[0-9]+$" :: String) :: Bool
83+
-- if apipackageok == False
84+
-- then die(show "Invalid package name.")
85+
-- else return "OK"
86+
87+
{-|
88+
The 'openWS' function initializes the web service configuration.
89+
It takes 3 arguments; the web service API key, the API package to call & whether to use SSL.
90+
-}
91+
openWS :: String -> String -> Bool -> IO WSConfig
92+
openWS apikey apipackage usessl = do
93+
paramok <- checkparams apikey apipackage
94+
return (WSConfig apikey apipackage usessl)
95+
96+
{-|
97+
The 'lookUp' function returns an WSResult containing proxy data for an IP address.
98+
It takes 2 arguments; the web service configuration from 'openWS' function (WSConfig record) & either IPv4 or IPv6 address (String).
99+
-}
100+
lookUp :: WSConfig -> String -> IO WSResult
101+
lookUp myconfig ip = do
102+
let key = apiKey myconfig
103+
let package = apiPackage myconfig
104+
let usessl = useSSL myconfig
105+
106+
paramok <- checkparams key package
107+
let protocol = if usessl == True
108+
then "https"
109+
else "http"
110+
manager <- newManager tlsManagerSettings
111+
httprequest <- parseRequest $ protocol ++ "://api.ip2proxy.com/?key=" ++ key ++ "&package=" ++ package ++ "&ip=" ++ (URIE.encode ip)
112+
httpresponse <- httpLbs httprequest manager
113+
let json = responseBody httpresponse
114+
let Just result = DA.decode json :: Maybe WSResult
115+
return result
116+
117+
{-|
118+
The 'getCredit' function returns an WSResult containing web service credit balance for the API key.
119+
It takes 1 argument; the web service configuration from 'openWS' function (WSConfig record).
120+
-}
121+
getCredit :: WSConfig -> IO WSResult
122+
getCredit myconfig = do
123+
let key = apiKey myconfig
124+
let package = apiPackage myconfig
125+
let usessl = useSSL myconfig
126+
127+
paramok <- checkparams key package
128+
let protocol = if usessl == True
129+
then "https"
130+
else "http"
131+
manager <- newManager tlsManagerSettings
132+
httprequest <- parseRequest $ protocol ++ "://api.ip2proxy.com/?key=" ++ key ++ "&check=true"
133+
httpresponse <- httpLbs httprequest manager
134+
let json = responseBody httpresponse
135+
let Just result = DA.decode json :: Maybe WSResult
136+
return result

README.md

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,18 @@ This Haskell package allows user to query an IP address if it was being used as
55
* Free IP2Proxy BIN Data: https://lite.ip2location.com
66
* Commercial IP2Proxy BIN Data: https://www.ip2location.com/database/ip2proxy
77

8+
As an alternative, this package can also call the IP2Proxy Web Service. This requires an API key. If you don't have an existing API key, you can subscribe for one at the below:
9+
10+
https://www.ip2location.com/web-service/ip2proxy
811

912
## Installation
1013

1114
```bash
1215
cabal install IP2Proxy
1316
```
1417

18+
## QUERY USING THE BIN FILE
19+
1520
## Methods
1621
Below are the methods supported in this package.
1722

@@ -37,7 +42,7 @@ Below are the methods supported in this package.
3742
|getThreat|Return the threat type of the proxy.|
3843
|getProvider|Return the provider of the proxy.|
3944

40-
## Example
45+
## Usage
4146

4247
```haskell
4348
import IP2Proxy
@@ -97,3 +102,47 @@ main = do
97102
result <- isProxy myfile meta ip
98103
putStrLn $ "is_proxy: " ++ result
99104
```
105+
106+
## QUERY USING THE IP2PROXY PROXY DETECTION WEB SERVICE
107+
108+
## Methods
109+
Below are the methods supported in this package.
110+
111+
|Method Name|Description|
112+
|---|---|
113+
|openWS| Expects 3 input parameters:<ol><li>IP2Proxy API Key.</li><li>Package (PX1 - PX11)</li></li><li>Use HTTPS or HTTP</li></ol> |
114+
|lookUp|Query IP address. This method returns a WSResult record containing the proxy info. <ul><li>countryCode</li><li>countryName</li><li>regionName</li><li>cityName</li><li>isp</li><li>domain</li><li>usageType</li><li>asn</li><li>as</li><li>lastSeen</li><li>threat</li><li>proxyType</li><li>isProxy</li><li>provider</li><ul>|
115+
|getCredit|This method returns the web service credit balance in a WSResult record.|
116+
117+
## Usage
118+
119+
```haskell
120+
import IP2ProxyWebService
121+
import Data.Maybe
122+
123+
main :: IO ()
124+
main = do
125+
let apikey = "YOUR_API_KEY"
126+
let apipackage = "PX11"
127+
let usessl = True
128+
let ip = "37.252.228.50"
129+
wsconfig <- openWS apikey apipackage usessl
130+
result <- lookUp wsconfig ip
131+
putStrLn $ "response: " ++ (response result)
132+
putStrLn $ "countryCode: " ++ (fromMaybe ("-") $ (countryCode result))
133+
putStrLn $ "countryName: " ++ (fromMaybe ("-") $ (countryName result))
134+
putStrLn $ "regionName: " ++ (fromMaybe ("-") $ (regionName result))
135+
putStrLn $ "cityName: " ++ (fromMaybe ("-") $ (cityName result))
136+
putStrLn $ "isp: " ++ (fromMaybe ("-") $ (isp result))
137+
putStrLn $ "domain: " ++ (fromMaybe ("-") $ (domain result))
138+
putStrLn $ "usageType: " ++ (fromMaybe ("-") $ (usageType result))
139+
putStrLn $ "asn: " ++ (fromMaybe ("-") $ (asn result))
140+
putStrLn $ "as: " ++ (fromMaybe ("-") $ (as result))
141+
putStrLn $ "lastSeen: " ++ (fromMaybe ("-") $ (lastSeen result))
142+
putStrLn $ "proxyType: " ++ (fromMaybe ("-") $ (proxyType result))
143+
putStrLn $ "threat: " ++ (fromMaybe ("-") $ (threat result))
144+
putStrLn $ "isProxy: " ++ (fromMaybe ("-") $ (isProxy result))
145+
putStrLn $ "provider: " ++ (fromMaybe ("-") $ (provider result))
146+
result <- getCredit wsconfig
147+
putStrLn $ "Credit Balance: " ++ (response result)
148+
```

ip2proxy.cabal

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ name: ip2proxy
1010
-- PVP summary: +-+------- breaking API changes
1111
-- | | +----- non-breaking API additions
1212
-- | | | +--- code changes with no API change
13-
version: 3.1.0
13+
version: 3.2.0
1414

1515
-- A short (one-line) description of the package.
1616
synopsis: IP2Proxy Haskell package for proxy detection.
@@ -51,7 +51,7 @@ cabal-version: >=1.10
5151

5252
library
5353
-- Modules exported by the library.
54-
exposed-modules: IP2Proxy
54+
exposed-modules: IP2Proxy, IP2ProxyWebService
5555

5656
-- Modules included in this library but not exported.
5757
-- other-modules:
@@ -60,7 +60,7 @@ library
6060
-- other-extensions:
6161

6262
-- Other library packages from which modules are imported.
63-
build-depends: base >=4.9 && <=4.15, bytestring >=0.10 && <0.12, binary >=0.8.4 && <0.9, iproute >=1.7 && <1.8
63+
build-depends: base >=4.9 && <=4.15, bytestring >=0.10 && <0.12, binary >=0.8.4 && <0.9, iproute >=1.7 && <1.8, aeson >=1.5 && <1.6, http-types >=0.12 && <0.13, http-client >=0.6 && <0.7, http-client-tls >=0.3 && <0.4, uri-encode >=1.5 && <1.6
6464

6565
-- Directories containing source files.
6666
-- hs-source-dirs:

testws.hs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import IP2ProxyWebService
2+
import Data.Maybe
3+
4+
main :: IO ()
5+
main = do
6+
let apikey = "YOUR_API_KEY"
7+
let apipackage = "PX11"
8+
let usessl = True
9+
let ip = "37.252.228.50"
10+
wsconfig <- openWS apikey apipackage usessl
11+
result <- lookUp wsconfig ip
12+
putStrLn $ "response: " ++ (response result)
13+
putStrLn $ "countryCode: " ++ (fromMaybe ("-") $ (countryCode result))
14+
putStrLn $ "countryName: " ++ (fromMaybe ("-") $ (countryName result))
15+
putStrLn $ "regionName: " ++ (fromMaybe ("-") $ (regionName result))
16+
putStrLn $ "cityName: " ++ (fromMaybe ("-") $ (cityName result))
17+
putStrLn $ "isp: " ++ (fromMaybe ("-") $ (isp result))
18+
putStrLn $ "domain: " ++ (fromMaybe ("-") $ (domain result))
19+
putStrLn $ "usageType: " ++ (fromMaybe ("-") $ (usageType result))
20+
putStrLn $ "asn: " ++ (fromMaybe ("-") $ (asn result))
21+
putStrLn $ "as: " ++ (fromMaybe ("-") $ (as result))
22+
putStrLn $ "lastSeen: " ++ (fromMaybe ("-") $ (lastSeen result))
23+
putStrLn $ "proxyType: " ++ (fromMaybe ("-") $ (proxyType result))
24+
putStrLn $ "threat: " ++ (fromMaybe ("-") $ (threat result))
25+
putStrLn $ "isProxy: " ++ (fromMaybe ("-") $ (isProxy result))
26+
putStrLn $ "provider: " ++ (fromMaybe ("-") $ (provider result))
27+
result <- getCredit wsconfig
28+
putStrLn $ "Credit Balance: " ++ (response result)

0 commit comments

Comments
 (0)