Skip to content

Commit 1f5d904

Browse files
committed
Implemented requestIpApiCom
1 parent ccac2dc commit 1f5d904

13 files changed

+122
-27
lines changed

.travis.yml

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ addons:
1313
- make
1414
- g++
1515
- pkg-config
16+
- libcurl4-openssl-dev
1617

1718
# Build steps
1819
script:

README.md

+23
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,27 @@ C++. Call request to another services for get location coordinates by IP-address
66

77
Example:
88
```
9+
WSJCppGeoIPResult res = WSJCppGeoIP::requestToIpApiCom("1.1.1.1");
10+
if (res.hasError()) {
11+
std::cout << "FAILED: " << res.getErrorDescription() << std::endl;
12+
} else {
13+
std::cout << "Service Name: " << res.getServiceName() << std::endl;
14+
std::cout << "IP Address: " << res.getIpAddress() << std::endl;
15+
std::cout << "Country: " << res.getCountry() << std::endl;
16+
std::cout << "Region Name: " << res.getRegionName() << std::endl;
17+
std::cout << "City: " << res.getCity() << std::endl;
18+
std::cout << "Latitude: " << res.getLatitude() << std::endl;
19+
std::cout << "Longitude: " << res.getLongitude() << std::endl;
20+
}
21+
```
22+
23+
Output:
24+
```
25+
Service Name: ip-api.com
26+
IP Address: 1.1.1.1
27+
Country: Australia
28+
Region Name: New South Wales
29+
City: Sydney
30+
Latitude: -33.8688
31+
Longitude: 151.209
932
```

src.wsjcpp/CMakeLists.txt

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ set (WSJCPP_LIBRARIES "")
1414
set (WSJCPP_INCLUDE_DIRS "")
1515
set (WSJCPP_SOURCES "")
1616

17-
# wsjcpp/wsjcpp-core:v0.0.4
18-
list (APPEND WSJCPP_INCLUDE_DIRS "./src.wsjcpp/wsjcpp_wsjcpp_core/")
19-
list (APPEND WSJCPP_SOURCES "./src.wsjcpp/wsjcpp_wsjcpp_core/wsjcpp_core.cpp")
20-
list (APPEND WSJCPP_SOURCES "./src.wsjcpp/wsjcpp_wsjcpp_core/wsjcpp_core.h")
17+
# wsjcpp-core:v0.0.4
18+
list (APPEND WSJCPP_INCLUDE_DIRS "./src.wsjcpp/wsjcpp_core/")
19+
list (APPEND WSJCPP_SOURCES "./src.wsjcpp/wsjcpp_core/wsjcpp_core.cpp")
20+
list (APPEND WSJCPP_SOURCES "./src.wsjcpp/wsjcpp_core/wsjcpp_core.h")
2121

2222
# nlohmann/json:v3.7.3
2323
list (APPEND WSJCPP_INCLUDE_DIRS "./src.wsjcpp/nlohmann_json/")

src.wsjcpp/wsjcpp_wsjcpp_core/wsjcpp.hold.yml renamed to src.wsjcpp/wsjcpp_core/wsjcpp.hold.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ wsjcpp_version: v0.0.1
22
cmake_cxx_standard: 11
33
cmake_minimum_required: 3.0
44

5-
name: wsjcpp/wsjcpp-core
5+
name: wsjcpp-core
66
version: v0.0.4
77
description: Basic Utils for wsjcpp
88
issues: https://github.com/wsjcpp/wsjcpp-core/issues

src.wsjcpp/wsjcpp_wsjcpp_core/wsjcpp_core.cpp renamed to src.wsjcpp/wsjcpp_core/wsjcpp_core.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ std::string WSJCppCore::createUuid() {
413413

414414
// ---------------------------------------------------------------------
415415

416-
bool WSJCppCore::isIPv4(std::string& str) {
416+
bool WSJCppCore::isIPv4(const std::string& str) {
417417
int n = 0;
418418
std::string s[4] = {"", "", "", ""};
419419
for (int i = 0; i < str.length(); i++) {
@@ -443,7 +443,7 @@ bool WSJCppCore::isIPv4(std::string& str) {
443443

444444
// ---------------------------------------------------------------------
445445

446-
bool WSJCppCore::isIPv6(std::string& str) {
446+
bool WSJCppCore::isIPv6(const std::string& str) {
447447
unsigned char buf[sizeof(struct in6_addr)];
448448
bool isValid = inet_pton(AF_INET6, str.c_str(), buf);
449449
return isValid;

src.wsjcpp/wsjcpp_wsjcpp_core/wsjcpp_core.h renamed to src.wsjcpp/wsjcpp_core/wsjcpp_core.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ class WSJCppCore {
4848

4949
static void initRandom();
5050
static std::string createUuid();
51-
static bool isIPv4(std::string& str);
52-
static bool isIPv6(std::string& str);
51+
static bool isIPv4(const std::string& str);
52+
static bool isIPv6(const std::string& str);
5353
};
5454

5555

src/main.cpp

+16-6
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,24 @@ int main(int argc, const char* argv[]) {
2525
vArgs.push_back(std::string(argv[i]));
2626
}
2727

28-
/*if (vArgs.size() != 3) {
29-
std::cout << "Usage: " << vArgs[0] << " <string1> <string2>" << std::endl;
28+
if (vArgs.size() != 2) {
29+
std::cout << "Usage: " << vArgs[0] << " <ip-adderss>" << std::endl;
3030
return -1;
3131
}
3232

33-
std::string s1 = vArgs[1];
34-
std::string s2 = vArgs[2];
35-
int nDistance = WSJCppLevenshtein::distance(s1,s2);
36-
std::cout << "" << nDistance << std::endl;*/
33+
std::string sIpAddress = vArgs[1];
34+
WSJCppGeoIPResult res = WSJCppGeoIP::requestToIpApiCom(sIpAddress);
35+
if (res.hasError()) {
36+
std::cout << "FAILED: " << res.getErrorDescription() << std::endl;
37+
} else {
38+
std::cout << "Service Name: " << res.getServiceName() << std::endl;
39+
std::cout << "IP Address: " << res.getIpAddress() << std::endl;
40+
std::cout << "Country: " << res.getCountry() << std::endl;
41+
std::cout << "Region Name: " << res.getRegionName() << std::endl;
42+
std::cout << "City: " << res.getCity() << std::endl;
43+
std::cout << "Latitude: " << res.getLatitude() << std::endl;
44+
std::cout << "Longitude: " << res.getLongitude() << std::endl;
45+
}
46+
// std::cout << "" << nDistance << std::endl;
3747
return 0;
3848
}

src/wsjcpp_geoip.cpp

+53-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "wsjcpp_geoip.h"
22
#include <json.hpp>
33
#include <wsjcpp_core.h>
4+
#include <curl/curl.h>
45

56
// ----------------------------------------------------------------------
67

@@ -136,13 +137,62 @@ nlohmann::json WSJCppGeoIPResult::toJson() {
136137

137138
// ----------------------------------------------------------------------
138139

140+
size_t WSJCppGeoIP_CallbackFunc_DataToString(char *data, size_t size, size_t nmemb, std::string *writerData) {
141+
if (writerData == NULL)
142+
return 0;
143+
writerData->append(data, size*nmemb);
144+
return size * nmemb;
145+
}
146+
147+
// ----------------------------------------------------------------------
148+
139149
WSJCppGeoIPResult WSJCppGeoIP::requestToIpApiCom(const std::string &sIpAddress) {
140150
std::string sServiceName = "ip-api.com";
151+
152+
// TODO check ip reserved range
141153
std::string TAG = "requestToIpApiCom";
154+
if (!WSJCppCore::isIPv4(sIpAddress) && !WSJCppCore::isIPv6(sIpAddress)) {
155+
return WSJCppGeoIPResult("ipapi.com", sIpAddress, "Expected ip address");
156+
}
142157

143-
// TODO check is ip address v4 v6 in WSJCppCore
144-
// TODO check ip reserved range
145-
return WSJCppGeoIPResult("ipapi.com", sIpAddress, "Not implemented");
158+
std::string sUrl = "http://ip-api.com/json/" + sIpAddress;
159+
160+
std::string sUserAgent = "wsjcpp-geoip";
161+
CURL *curl;
162+
CURLcode res;
163+
curl = curl_easy_init();
164+
std::string sResponse = "";
165+
if (curl) {
166+
// curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); //only for https
167+
// curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); //only for https
168+
curl_easy_setopt(curl, CURLOPT_URL, sUrl.c_str());
169+
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WSJCppGeoIP_CallbackFunc_DataToString);
170+
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &sResponse);
171+
172+
curl_easy_setopt(curl, CURLOPT_USERAGENT, sUserAgent.c_str());
173+
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
174+
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L);
175+
// curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
176+
res = curl_easy_perform(curl);
177+
if (res != CURLE_OK) {
178+
std::string sError = "Curl failed, reason " + std::string(curl_easy_strerror(res));
179+
WSJCppLog::err(TAG, sError);
180+
// TODO remove file
181+
curl_easy_cleanup(curl);
182+
WSJCppGeoIPResult(sServiceName, sIpAddress, sError);
183+
} else {
184+
long response_code;
185+
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
186+
if (response_code != 200) {
187+
WSJCppLog::info(TAG, "end " + std::to_string(response_code));
188+
// TODO remove file
189+
curl_easy_cleanup(curl);
190+
}
191+
}
192+
// always cleanup
193+
curl_easy_cleanup(curl);
194+
}
195+
return WSJCppGeoIP::parseResponseIpApiCom(sIpAddress, sResponse);
146196
}
147197

148198
// ----------------------------------------------------------------------

unit-tests.wsjcpp/CMakeLists.txt

+18-7
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ set (WSJCPP_SOURCES "")
1111

1212
# Sources
1313

14-
# wsjcpp/wsjcpp-core
15-
list (APPEND WSJCPP_INCLUDE_DIRS "../src.wsjcpp/wsjcpp_wsjcpp_core/")
16-
list (APPEND WSJCPP_SOURCES "../src.wsjcpp/wsjcpp_wsjcpp_core/wsjcpp_core.cpp")
17-
list (APPEND WSJCPP_SOURCES "../src.wsjcpp/wsjcpp_wsjcpp_core/wsjcpp_core.h")
18-
list (APPEND WSJCPP_SOURCES "../src.wsjcpp/wsjcpp_wsjcpp_core/unit_tests.cpp")
19-
list (APPEND WSJCPP_SOURCES "../src.wsjcpp/wsjcpp_wsjcpp_core/unit_tests.h")
20-
list (APPEND WSJCPP_SOURCES "../src.wsjcpp/wsjcpp_wsjcpp_core/unit_tests_main.cpp")
14+
# wsjcpp-core:v0.0.4
15+
list (APPEND WSJCPP_INCLUDE_DIRS "../src.wsjcpp/wsjcpp_core/")
16+
list (APPEND WSJCPP_SOURCES "../src.wsjcpp/wsjcpp_core/wsjcpp_core.cpp")
17+
list (APPEND WSJCPP_SOURCES "../src.wsjcpp/wsjcpp_core/wsjcpp_core.h")
18+
list (APPEND WSJCPP_SOURCES "../src.wsjcpp/wsjcpp_core/unit_tests.cpp")
19+
list (APPEND WSJCPP_SOURCES "../src.wsjcpp/wsjcpp_core/unit_tests.h")
20+
list (APPEND WSJCPP_SOURCES "../src.wsjcpp/wsjcpp_core/unit_tests_main.cpp")
2121

2222
# nlohmann/json
2323
list (APPEND WSJCPP_INCLUDE_DIRS "../src.wsjcpp/nlohmann_json/")
@@ -34,6 +34,17 @@ list (APPEND WSJCPP_INCLUDE_DIRS "src")
3434
list (APPEND WSJCPP_SOURCES "./src/unit_test_parser_ip_api_com.h")
3535
list (APPEND WSJCPP_SOURCES "./src/unit_test_parser_ip_api_com.cpp")
3636

37+
# required-pkg-config
38+
## CURL
39+
FIND_PACKAGE(CURL)
40+
IF(CURL_FOUND)
41+
list (APPEND WSJCPP_INCLUDE_DIRS ${CURL_INCLUDE_DIR})
42+
list (APPEND WSJCPP_LIBRARIES ${CURL_LIBRARIES})
43+
ELSE(CURL_FOUND)
44+
MESSAGE(FATAL_ERROR "Could not find the CURL library and development files.")
45+
ENDIF(CURL_FOUND)
46+
47+
3748
include_directories(${WSJCPP_INCLUDE_DIRS})
3849

3950
add_executable ("unit-tests" ${WSJCPP_SOURCES})

wsjcpp.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ required-pkg-config:
1818
- CURL
1919

2020
dependencies:
21-
- name: "wsjcpp/wsjcpp-core"
21+
- name: "wsjcpp-core"
2222
version: "v0.0.4"
2323
url: "https://github.com/wsjcpp/wsjcpp-core:master"
2424
origin: "https://github.com/"
25-
installation-dir: "./src.wsjcpp/wsjcpp_wsjcpp_core"
25+
installation-dir: "./src.wsjcpp/wsjcpp_core"
2626
- name: "nlohmann/json"
2727
version: "v3.7.3"
2828
url: "https://github.com/wsjcpp/json:develop"

0 commit comments

Comments
 (0)