InternetConnection becomes 0 when trying to run a HTTP GET


#1

I'll list my questions first, the information of the problem is posted below.

  1. Why doesn't my code work and what should I do to fix it? The InternetConnect object in juce_win32_Network.cpp becomes 0.
  2. 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 (lpszHostNamenPort, 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();
}

#2

Just to check; What target(s)? Do you have to get permission from the OS(s) to access the IP connection? (firewall/permission requests settings? )


#3

Yes, I am pretty sure that I have the proper permissions in place. This is a local server I set up myself, running Node.js in Ubuntu, so it is nothing fancy. I have not fiddled with any firewall settings on the server side or the client side and the data is easily accessible in a browser. The client is nothing but some static HTML forms interacting with a database, no https or login possible.

However, while running home from work just now, I realized that the truncation of the URL from "192.168.98.2:3000/get_qa_json?device_ip_address=%22192.168.98.2%22" to "3000/get_qa_json?device_ip_address=%22192.168.98.2%22", i.e. without "192.168.98.2" might be because "http:" is tried removed at some point. If the code then expects "http:" to be present in the URL, maybe it just truncates up to the first colon it meets and then removes any slashes. Maybe a bit far fetched, but I can try adding "http://" to the URL tomorrow. 


#4

So adding http:// to the URL fixed the issue and I am now able to get the data using

juce::URL qaJsonUrl("http://192.168.98.2:3000"); // "192.168.98.2:3000" didn't work.
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();
    return result;
}

#5

Your calling code does not seem to include the protocol in the URL. A fully valid URL must include the "http://" bit.