I'm new to C++, I am trying to consume the ip-api.com API to fetch a geolocation based on an IP number. But I can't make a request correctly. What can I change in this code to get the JSON response correctly?
string GetLocation() {
DWORD size = 0;
DWORD wrt;
LPCWSTR down = L"Downloader";
string msg = "";
/*wstring ipConvert(ipAdr().begin(), ipAdr().end());
LPCWSTR ip = ipConvert.c_str();*/
string url = "http://ip-api.com/json/168.197.155.244";
wstring urlConvert(url.begin(), url.end());
LPCWSTR urlFinal = L"http://ip-api.com/json/168.197.155.244";
LPCWSTR headers = L"Content-Type: application/json\r\n";
HINTERNET open = InternetOpen(down, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
HINTERNET connect = InternetConnect(open, urlFinal, NULL, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
HINTERNET request = HttpOpenRequest(connect, NULL, urlFinal, NULL, NULL, 0, 0, 0);
HttpAddRequestHeaders(request, headers, -1, HTTP_ADDREQ_FLAG_ADD);
HttpSendRequest(request, NULL, 0, NULL, 0);
InternetQueryDataAvailable(request, &size, 0, 0);
char* buff = new char[size + 1];
memset(buff, 0, size + 1);
InternetReadFile(request, buff, size, &wrt);
msg += buff;
InternetCloseHandle(open);
InternetCloseHandle(connect);
InternetCloseHandle(request);
return msg;
}
Aside from your complete lack of any error handling, the main issue with your code is that you can't pass a URL to
InternetConnect()andHttpOpenRequest(), as you are doing.You need to break up the URL into its constituent pieces (see
InternetCrackUrl()) - namely: scheme, hostname, port, and path - and then pass the approach pieces to each function as needed:InternetConnect()wants the server's hostname and port (ie"ip-api.com"and"80"), and theINTERNET_FLAG_SECUREflag when connecting to an HTTPS server.HttpOpenRequest()wants the resource's path on the server (ie"/json/168.197.155.244").Alternatively, you can use
InternetOpenUrl()instead. In which case, you don't need to useHttpOpenRequest()andHttpSendRequest()at all (and BTW, your use ofHttpAddRequestHeaders()can be removed completely, as you are not sending any data to the server, so there is no need to add aContent-Typeheader to the request). See Handling Uniform Resource Locators in WinInet's documentation for more details about that.