I'll list my questions first, the information of the problem is posted below.
- Why doesn't my code work and what should I do to fix it? The InternetConnect object in juce_win32_Network.cpp becomes 0.
- What are the best practice for performing such HTTP request in a cross platform approach? By this I only mean that I have to run these HTTP requests on several platforms (at least Windows, Linux, Mac, iOS, Android). Should threading be involved somehow?
I am trying to run a simple HTTP GET to get JSON data from a local server. The server spits out the required JSON if I go to 192.168.98.2:3000/get_qa_json?device_ip_address="192.168.98.2" in a browser, hence it should be quite easy to fetch this data using the juce::URL class. However, I am running into trouble when the code hits this part in juce_win32_Network.cpp (yup, I am currently running this in Windows (8)):
connection = InternetConnect (sessionHandle, uc.lpszHostName, uc.nPort,
uc.lpszUserName, uc.lpszPassword,
isFtp ? (DWORD) INTERNET_SERVICE_FTP
: (DWORD) INTERNET_SERVICE_HTTP,
0, 0);
At this point the variable connection becomes 0, which makes the connection unavailable, and I am unable to go into this part of the code to see what happens. The variables have the following values:
- sessionHandle: has a value (0xx00cc0004), should be ok as far as I can tell. It is a callback of void* datatype.
- uc: most of its members are 0 (lpszHostName, nPort, lpszUserName and lpszPassword are all 0 or empty), but lpszUrlPath is set to 3000/get_qa_json?device_ip_address=%22192.168.98.2%22, i.e. the first part of the URL is truncated. However, lpszUrlPath does not seem to be used in the creation of the connection anyway.
- isFtp: is false, so that part of the InternetConnect should become INTERNET_SERVICE_HTTP.
I am not really able to follow all the steps in the code to determine why the uc variable (datatype URL_COMPONENTS) is almost empty, except that it is in fact set to empty in juce_win32_Network.cpp --> createConnection like this:
const int fileNumChars = 65536;
const int serverNumChars = 2048;
const int usernameNumChars = 1024;
const int passwordNumChars = 1024;
HeapBlock<TCHAR> file (fileNumChars), server (serverNumChars),
username (usernameNumChars), password (passwordNumChars);
URL_COMPONENTS uc = { 0 };
uc.dwStructSize = sizeof (uc);
uc.lpszUrlPath = file;
uc.dwUrlPathLength = fileNumChars;
uc.lpszHostName = server;
uc.dwHostNameLength = serverNumChars;
uc.lpszUserName = username;
uc.dwUserNameLength = usernameNumChars;
uc.lpszPassword = password;
uc.dwPasswordLength = passwordNumChars;
if (InternetCrackUrl (address.toWideCharPointer(), 0, 0, &uc))
openConnection (uc, sessionHandle, progressCallback, progressCallbackContext);
What is the HeapBlock doing and how does it get its data?
Here is my current calling code. I guess something should be enhanced here.
// Attempt 1
//juce::URL qaJsonUrl("192.168.98.2:3000/get_qa_json?device_ip_address=\"192.168.98.2\"");
// Attempt 2
juce::URL qaJsonUrl("192.168.98.2:3000");
qaJsonUrl = qaJsonUrl.withNewSubPath("get_qa_json");
qaJsonUrl = qaJsonUrl.withParameter("device_ip_address", "192.168.98.2");
juce::ScopedPointer<juce::InputStream> inputStream = qaJsonUrl.createInputStream(false); // GET request
if (inputStream)
{
juce::String result = inputStream->readEntireStreamAsString();
}
