Skip to content

Commit

Permalink
Added support for IP2Proxy Web Service
Browse files Browse the repository at this point in the history
  • Loading branch information
ip2location committed Oct 7, 2021
1 parent 41b8fc4 commit 01a7405
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 5 deletions.
4 changes: 4 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Revision history for ip2proxy

## 3.2.0 -- 2021-10-07

* Added support for IP2Proxy Web Service.

## 3.1.0 -- 2021-07-06

* Added provider field and exception handling for incorrect BIN database.
Expand Down
2 changes: 1 addition & 1 deletion IP2Proxy.hs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ getMeta = do
The 'getModuleVersion' function returns a string containing the module version.
-}
getModuleVersion :: String
getModuleVersion = "3.1.0"
getModuleVersion = "3.2.0"

{-|
The 'getPackageVersion' function returns a string containing the package version.
Expand Down
136 changes: 136 additions & 0 deletions IP2ProxyWebService.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
{-# LANGUAGE OverloadedStrings,TemplateHaskell #-}
{-|
Module : IP2ProxyWebService
Description : IP2Proxy Haskell package
Copyright : (c) IP2Location, 2021
License : MIT
Maintainer : [email protected]
Stability : experimental
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.
IP2Proxy Web Service API subscription at https://www.ip2location.com/web-service/ip2proxy
-}
module IP2ProxyWebService (WSResult(..), WSConfig, openWS, lookUp, getCredit) where

import Control.Exception
import System.Exit
import Data.Aeson as DA
import Data.Aeson.TH
import Network.HTTP.Client
import Network.HTTP.Client.TLS (tlsManagerSettings)
import Network.HTTP.Types.Status (statusCode)
import Data.Maybe
import Network.URI.Encode as URIE
-- import Text.Regex.Base
-- import Text.Regex.TDFA

-- | Contains the web service configuration.
data WSConfig = WSConfig {
-- | Web service API key
apiKey :: String,
-- | API package
apiPackage :: String,
-- | Use SSL
useSSL :: Bool
} deriving (Show)

-- | Contains the web service results.
data WSResult = WSResult {
-- | Response status or error
response :: String,
-- | Country code
countryCode :: Maybe String,
-- | Country name
countryName :: Maybe String,
-- | Region name
regionName :: Maybe String,
-- | City name
cityName :: Maybe String,
-- | ISP name
isp :: Maybe String,
-- | Domain
domain :: Maybe String,
-- | Usage type
usageType :: Maybe String,
-- | Autonomous System Number
asn :: Maybe String,
-- | Autonomous System
as :: Maybe String,
-- | Proxy last seen in days
lastSeen :: Maybe String,
-- | Proxy type
proxyType :: Maybe String,
-- | Threat type
threat :: Maybe String,
-- | Whether is a proxy
isProxy :: Maybe String,
-- | VPN provider name
provider :: Maybe String
} deriving (Show, Eq)

$(deriveJSON defaultOptions ''WSResult)

checkparams :: String -> String -> IO String
checkparams apikey apipackage = do
return "OK"
--- regex part commented out due to cabal dependency issues
-- let apikeyok = apikey =~ ("^[0-9A-Z]{10}$" :: String) :: Bool
-- if apikeyok == False
-- then die(show "Invalid API key.")
-- else do
-- let apipackageok = apipackage =~ ("^PX[0-9]+$" :: String) :: Bool
-- if apipackageok == False
-- then die(show "Invalid package name.")
-- else return "OK"

{-|
The 'openWS' function initializes the web service configuration.
It takes 3 arguments; the web service API key, the API package to call & whether to use SSL.
-}
openWS :: String -> String -> Bool -> IO WSConfig
openWS apikey apipackage usessl = do
paramok <- checkparams apikey apipackage
return (WSConfig apikey apipackage usessl)

{-|
The 'lookUp' function returns an WSResult containing proxy data for an IP address.
It takes 2 arguments; the web service configuration from 'openWS' function (WSConfig record) & either IPv4 or IPv6 address (String).
-}
lookUp :: WSConfig -> String -> IO WSResult
lookUp myconfig ip = do
let key = apiKey myconfig
let package = apiPackage myconfig
let usessl = useSSL myconfig

paramok <- checkparams key package
let protocol = if usessl == True
then "https"
else "http"
manager <- newManager tlsManagerSettings
httprequest <- parseRequest $ protocol ++ "://api.ip2proxy.com/?key=" ++ key ++ "&package=" ++ package ++ "&ip=" ++ (URIE.encode ip)
httpresponse <- httpLbs httprequest manager
let json = responseBody httpresponse
let Just result = DA.decode json :: Maybe WSResult
return result

{-|
The 'getCredit' function returns an WSResult containing web service credit balance for the API key.
It takes 1 argument; the web service configuration from 'openWS' function (WSConfig record).
-}
getCredit :: WSConfig -> IO WSResult
getCredit myconfig = do
let key = apiKey myconfig
let package = apiPackage myconfig
let usessl = useSSL myconfig

paramok <- checkparams key package
let protocol = if usessl == True
then "https"
else "http"
manager <- newManager tlsManagerSettings
httprequest <- parseRequest $ protocol ++ "://api.ip2proxy.com/?key=" ++ key ++ "&check=true"
httpresponse <- httpLbs httprequest manager
let json = responseBody httpresponse
let Just result = DA.decode json :: Maybe WSResult
return result
51 changes: 50 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ This Haskell package allows user to query an IP address if it was being used as
* Free IP2Proxy BIN Data: https://lite.ip2location.com
* Commercial IP2Proxy BIN Data: https://www.ip2location.com/database/ip2proxy

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:

https://www.ip2location.com/web-service/ip2proxy

## Installation

```bash
cabal install IP2Proxy
```

## QUERY USING THE BIN FILE

## Methods
Below are the methods supported in this package.

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

## Example
## Usage

```haskell
import IP2Proxy
Expand Down Expand Up @@ -97,3 +102,47 @@ main = do
result <- isProxy myfile meta ip
putStrLn $ "is_proxy: " ++ result
```

## QUERY USING THE IP2PROXY PROXY DETECTION WEB SERVICE

## Methods
Below are the methods supported in this package.

|Method Name|Description|
|---|---|
|openWS| Expects 3 input parameters:<ol><li>IP2Proxy API Key.</li><li>Package (PX1 - PX11)</li></li><li>Use HTTPS or HTTP</li></ol> |
|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>|
|getCredit|This method returns the web service credit balance in a WSResult record.|

## Usage

```haskell
import IP2ProxyWebService
import Data.Maybe

main :: IO ()
main = do
let apikey = "YOUR_API_KEY"
let apipackage = "PX11"
let usessl = True
let ip = "37.252.228.50"
wsconfig <- openWS apikey apipackage usessl
result <- lookUp wsconfig ip
putStrLn $ "response: " ++ (response result)
putStrLn $ "countryCode: " ++ (fromMaybe ("-") $ (countryCode result))
putStrLn $ "countryName: " ++ (fromMaybe ("-") $ (countryName result))
putStrLn $ "regionName: " ++ (fromMaybe ("-") $ (regionName result))
putStrLn $ "cityName: " ++ (fromMaybe ("-") $ (cityName result))
putStrLn $ "isp: " ++ (fromMaybe ("-") $ (isp result))
putStrLn $ "domain: " ++ (fromMaybe ("-") $ (domain result))
putStrLn $ "usageType: " ++ (fromMaybe ("-") $ (usageType result))
putStrLn $ "asn: " ++ (fromMaybe ("-") $ (asn result))
putStrLn $ "as: " ++ (fromMaybe ("-") $ (as result))
putStrLn $ "lastSeen: " ++ (fromMaybe ("-") $ (lastSeen result))
putStrLn $ "proxyType: " ++ (fromMaybe ("-") $ (proxyType result))
putStrLn $ "threat: " ++ (fromMaybe ("-") $ (threat result))
putStrLn $ "isProxy: " ++ (fromMaybe ("-") $ (isProxy result))
putStrLn $ "provider: " ++ (fromMaybe ("-") $ (provider result))
result <- getCredit wsconfig
putStrLn $ "Credit Balance: " ++ (response result)
```
6 changes: 3 additions & 3 deletions ip2proxy.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ name: ip2proxy
-- PVP summary: +-+------- breaking API changes
-- | | +----- non-breaking API additions
-- | | | +--- code changes with no API change
version: 3.1.0
version: 3.2.0

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

library
-- Modules exported by the library.
exposed-modules: IP2Proxy
exposed-modules: IP2Proxy, IP2ProxyWebService

-- Modules included in this library but not exported.
-- other-modules:
Expand All @@ -60,7 +60,7 @@ library
-- other-extensions:

-- Other library packages from which modules are imported.
build-depends: base >=4.9 && <=4.15, bytestring >=0.10 && <0.12, binary >=0.8.4 && <0.9, iproute >=1.7 && <1.8
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

-- Directories containing source files.
-- hs-source-dirs:
Expand Down
28 changes: 28 additions & 0 deletions testws.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import IP2ProxyWebService
import Data.Maybe

main :: IO ()
main = do
let apikey = "YOUR_API_KEY"
let apipackage = "PX11"
let usessl = True
let ip = "37.252.228.50"
wsconfig <- openWS apikey apipackage usessl
result <- lookUp wsconfig ip
putStrLn $ "response: " ++ (response result)
putStrLn $ "countryCode: " ++ (fromMaybe ("-") $ (countryCode result))
putStrLn $ "countryName: " ++ (fromMaybe ("-") $ (countryName result))
putStrLn $ "regionName: " ++ (fromMaybe ("-") $ (regionName result))
putStrLn $ "cityName: " ++ (fromMaybe ("-") $ (cityName result))
putStrLn $ "isp: " ++ (fromMaybe ("-") $ (isp result))
putStrLn $ "domain: " ++ (fromMaybe ("-") $ (domain result))
putStrLn $ "usageType: " ++ (fromMaybe ("-") $ (usageType result))
putStrLn $ "asn: " ++ (fromMaybe ("-") $ (asn result))
putStrLn $ "as: " ++ (fromMaybe ("-") $ (as result))
putStrLn $ "lastSeen: " ++ (fromMaybe ("-") $ (lastSeen result))
putStrLn $ "proxyType: " ++ (fromMaybe ("-") $ (proxyType result))
putStrLn $ "threat: " ++ (fromMaybe ("-") $ (threat result))
putStrLn $ "isProxy: " ++ (fromMaybe ("-") $ (isProxy result))
putStrLn $ "provider: " ++ (fromMaybe ("-") $ (provider result))
result <- getCredit wsconfig
putStrLn $ "Credit Balance: " ++ (response result)

0 comments on commit 01a7405

Please sign in to comment.