Incoming JSON string seems to overflow buffer

I'm having a problems getting news headlines from a NY Times API. I get connected OK but I cannot consistantly retrieve the JSON string it sends. At one point I printed out the string on the serial monitor and then compared it to receiving that string in a web browser. They matched and the string length was something like 58,000 bytes - pretty large. When I repeat the request I usually get partial string like 30,000 bytes. I assume that there is a buffer problem on the incoming data. I've seen message hints that BUFFERSIZE can be changed in WifiClientSecure.h, but that doesn't exist nor does a method called setBufferSizes(writge, read).

Here is the function I've created and have tried reading the incomming data byte by byte and also using readString(). Neither works and readString() doesn't seem to appear in WifiSecureClient.cpp, but it compiles without an error.

Any suggestions appreciated.

Thanks,
Theron Wierenga

void getNewsFromInternet()
{
  // New key from NY Times Jan 2024
  // https://api.nytimes.com/svc/topstories/v2/science.json?api-key=d7GNBsyUwMa7tGDAGLtYZFjLHB7SqTbM

   const char* server = "api.nytimes.com";
   WiFiClientSecure client;
   client.setInsecure();
   const int httpPort = 443; // 80 is for HTTP / 443 is for HTTPS!
   int httpCode;
  
  Serial.println("\nStarting connection to server...");
  httpCode = client.connect(server, 443);
  Serial.println(httpCode);
  if (httpCode == 0)
    Serial.println("Connection failed!");
  else {
    Serial.println("Connected to server!");
    // Make a HTTP request:
    client.println("GET /svc/topstories/v2/science.json?api-key=d7GNBsyUwMa7tGDAGLtYZFjLHB7SqTbM HTTP/1.1");
    client.println("Host: api.nytimes.com");
    client.println("Connection: close");
    client.println("User-Agent: ArduinoWiFi/1.0"); // This is an example User-Agent; you can set it to anything relevant
    client.println();

    while (client.connected()) {
      String line = client.readStringUntil('\n');
      if (line == "\r") {
        Serial.println("headers received");
        break;
      }
    }
    // if there are incoming bytes available
    // from the server, read them and print them:
    while (client.available()) {
      news_payload = client.readString();
      // c = client.read();
      // Serial.write(c);
      // news_payload += c;
    }
    Serial.println(news_payload);
    Serial.print("news_payload length = ");
    Serial.println(news_payload.length());
    client.stop();
  }
}

If you were to only do this


 // if there are incoming bytes available
 // from the server, read them and print them:
 while (client.available()) Serial.write(client.read());

Instead of building up the string ( with possible heap memory issues)

Would you see the whole answer ?

It would need to be:
while (client.available()) Serial.write(c = client.read());
news_payload += c;

Tried it and this doesn't help.

Theron

No…

the point was to not save the json in memory for the moment - just to see if you get it all from the web request or if you already lost data because of the way the web client works.

I believe it all comes down from the server, but so fast that the ESP32 can't keep up.

Theron

probably shouldn't be sharing your api key with the public.

What evidence do you have for this ?
This sounds unlikely with TCP-IP…

The evidence is that I get different string lengths on what comes down and looking at the end of the string it doesn't have a correct json ending.

Here's my latest attempt, I've changed it to read into a char array.

// Retrieve news headlines from newsapi.org
// *****************************************************************************************************************
void getNewsFromInternet()
{
   const char* server = "newsapi.org";
   WiFiClientSecure client;
   client.setInsecure();
   const int httpPort = 443; // 80 is for HTTP / 443 is for HTTPS!
   int httpCode, count = 0;
   news_payload = "        ";
  
  Serial.println("\nStarting connection to server...");
  httpCode = client.connect(server, 443);
  Serial.println(httpCode);
  if (httpCode == 0)
    Serial.println("Connection failed!");
  else {
    Serial.println("Connected to server!");
    // Make a HTTP request:
    client.println("GET /v2/top-headlines?country=us&apiKey=myKey HTTP/1.1");
    client.println("Host: newsapi.org");
    client.println("Connection: close");
    client.println("User-Agent: ArduinoWiFi/1.0"); // This is an example User-Agent; you can set it to anything relevant
    client.println();

    while (client.connected()) {
      String line = client.readStringUntil('\n');
      if (line == "\r") {
        Serial.println("headers received");
        break;
      }
    }
    // if there are incoming bytes available
    // from the server, read them and print them:
    count = 0;
    while (client.available()) {
      n_payload[count++] = client.read();
      // news_payload += c;
    }
    n_payload[count] = 0x00;
    // Convert to String  
    news_payload = String(n_payload);
    Serial.print("news_payload = ");
    Serial.println(news_payload);
    Serial.println(news_payload.length());
    Serial.println(count);
    client.stop();
  }
}

Can you post your serial output?

news_payload = {"status":"ok","totalResults":69,"articles":[{"source":{"id":null,"name":"CBS Sports"},"author":"","title":"Purdue vs. Wisconsin live stream, watch online, TV channel, prediction, pick, spread, basketball game odds - CBS Sports","description":"A big battle in the Big Ten between two conference powers awaits Sunday in Madison","url":"https://www.cbssports.com/college-basketball/news/purdue-vs-wisconsin-live-stream-watch-online-tv-channel-prediction-pick-spread-basketball-game-odds/","urlToImage":"https://sportshub.cbsistatic.com/i/r/2023/12/17/23032f9e-0435-445f-8719-aacc7b5d9a8f/thumbnail/1200x675/639ca4f9c639810f84f689ba84e86bbc/usatsi-22120755-1.jpg","publishedAt":"2024-02-04T17:45:00Z","content":"The Big Ten's biggest game so far this s

749

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.