HTTP Request (w/ URL and InputStream) working intermittently

I’m using juce::URL and juce::InputStream to retrieve user data after successfully acquiring an API Key from a REST API server using the same methods.

Interestingly, while the acquisition of a new API key is consistently successful, I encounter 401 errors (indicating unauthorized access) most of the time when I use that key to fetch information. This issue happens only on my JUCE code - when I examine the endpoint on my browser and input the API Key, it functions flawlessly every time, even with API Keys generated by the JUCE code. Furthermore, this issue is not confined to a specific platform; it occurs on Android, Windows, iOS, and MacOS. In addition to that, using an API Key for a different user is also not allowed.

It is almost as if when I request information using JUCE methods, my machine is unable to request data successfully to that specific endpoint.

void queryGivenNameAndSurname ()
{
    juce::URL url("MY_URL");

    juce::String headers ("Authorization: apikey " + apiKey + "\n" +
                          "Accept: text/json"/* + "\n");

    juce::StringPairArray respHeaders;

    int statusCode = (int) HttpStatusCode::Empty;

    DBG ("APIKey used: " + apiKey);
    DBG ("Headers used: " + headers);

    auto options = GETOptions.withStatusCode (&statusCode)
                             .withExtraHeaders (headers)
                             .withHttpRequestCmd ("GET")
                             .withConnectionTimeoutMs (5000)
                             .withNumRedirectsToFollow (5)
                             .withResponseHeaders(&respHeaders);

    auto stream = url.createInputStream (options);

    if (stream != nullptr)
    {
        juce::String obtainedInfo = stream->readEntireStreamAsString();

        auto keyArray = respHeaders.getAllKeys();
        auto valueArray = respHeaders.getAllValues();

        DBG ("\nResponse Headers: \n");

        for (int i = 0; i < valueArray.size(); ++i)
        {
            auto key = keyArray.getReference (i);
            auto value = valueArray.getReference (i);

            DBG (key + " : " + value);
        }

        DBG ("\nThe result of fetching data is: ");
        DBG (statusCode);
        DBG (obtainedInfo);

        if (statusCode == (int) HttpStatusCode::OK)
        {
            givenName = extractJSONproperty (obtainedInfo, "GivenName");
            surname = extractJSONproperty (obtainedInfo, "Surname");

            DBG ("\nGiven Name is " + givenName + "\n" +
                 "Surname is "+ surname);
        }
    }
}

Example of a successful request:

APIKey used: b$[Kc{]8&5[Ku@;0C@>(w/w^|hkl@qL:

Headers used:

Authorization: apikey b$[Kc{]8&5[Ku@;0C@>(w/w^|hkl@qL:
Accept: text/json

Response Headers:

Server : Microsoft-IIS/10.0
Content-Type : text/json; charset=utf-8
Pragma : no-cache
x-powered-by : ASP.NET
x-aspnet-version : 4.0.30319
Date : Thu, 21 Mar 2024 16:02:25 GMT
Content-Length : 47
Cache-Control : no-cache
Expires : -1

The result of fetching data is:

200

{“GivenName”:“xxx”,“Surname”:“yyy”}

Given Name is xxx

Surname is yyy

the apiKey to be erased is: b$[Kc{]8&5[Ku@;0C@>(w/w^|hkl@qL:

Example of an unsuccessful Request:

APIKey used: 75o3a>p&IV>=)[*[$!T!gQ&n$TK5=I|+

Headers used:

Authorization: apikey 75o3a>p&IV>=)[*[$!T!gQ&n$TK5=I|+
Accept: text/json

Response Headers:

Server : Microsoft-IIS/10.0
Pragma : no-cache
x-powered-by : ASP.NET
x-aspnet-version : 4.0.30319
Date : Thu, 21 Mar 2024 16:02:32 GMT
Www-Authenticate : apikey
Content-Length : 0
Cache-Control : no-cache
Expires : -1

The result of fetching data is:
401

The funny thing is that it does not matter whether I use an API key that has worked before (by skipping its erasure), or whether I use a new API Key from a different user; I am literally blocked to this endpoint for a while if I use JUCE code.

I have seen posts in which this issue is related to cookies - however, my response header contains no cookies and I have got no clear way of retrieving them.

More than anything I want to skip adding external library dependencies. IF I have to go the curl way, does anyone know if JUCE_USE_CURL actually adds the library directly to the Projucer? It does not seem to do anything.

cURL is only used for Linux builds.

1 Like

All fixed!

It seems our server provider was not caching correctly on some instances. If you encounter this problem, contact your API provider.