Webserver Problem after certain time / calls

Hi All,
by setting up a webserver our Arduino can be controlled externally using JSON formatting.
So far so good, its working most of the time but when testing the system for some time and sending messages forth and back, it stops working at some point.

My test setup is chrome web browser from which we can talk to our webserver. For example checking the general state is:
192.168.0.10/state
Setting power on is:
192.168.0.10/setPower/on
Where: "setPower" is the command and "on" is the parameter

By using Easy Auto Refresh Plugin for Chrome, I set the refresh to one second and after about 30minutes the system stops working. This is more or less linear, so when refresh is every 2 seconds, it takes about 60 mins.

What happens is that the reply is a 404 error. Just from our code this means that the command could not be matched to any of the known commands. But we do not send anything else.
If this happens, the arduino is still working fine an doing the rest of work but there is no chance to control it via Webserver.
What helps is to reset the arduino or to call
asm volatile ("jmp 0"); //Soft reset

Logging the print out from the console shows that at some point it suddenly starts to struggle. The print out looks like this for example :

Computing: state

Request answered
Handle command cmd and param:
state

Computing: state

Request answered
Handle command cmd and param:
state

Computing: state

Request answered
Hacmd and param:
state

Computing: Request answered

Hawered
cmd and param:
state

CompRequest answered

Hawered
wered
cmd and param:
state

#Request answered
Hawered
wered
wered
cmd and param:
staRequest answered
Hawered
wered
wered
wered

....,.

Now I have to figure out how to upload the code...

I am not allowed to upload a file so I am pasting my code here, please let me know if there is any better way to share it:

#include <Arduino.h>

#include <Ethernet.h>

#include <TimeLib.h>

#include <Adafruit_Sensor.h>

#include <DHT.h>

#include <EEPROM-Storage.h>

// Network

EthernetServer server(80);                           

IPAddress defaultIP({192, 168, 0, 10});             

#define STRING_BUFFER_SIZE 128      

byte mac[] = {0x13, 0x03, 0x0C, 0x0C, 0x0C, 0x0C};

// ++++++++++++++++++++ +++ ++++++++++++ Setup ++++++++++++++++++++ +++ ++++++++++++

void setup() {

  Serial.begin(9600);

  server.begin();

  delay(1000);

  Ethernet.begin(mac, defaultIP);

  delay(1000);

  Serial.print(F("server is at "));

  Serial.println(Ethernet.localIP());

  setTime(0);

}

// ++++++++++++++++++++ +++ ++++++++++++ Loop ++++++++++++++++++++ +++ ++++++++++++

void loop() {

  delay(500);

  handleTraffic();

}

// ++++++++++++++++++++ +++ ++++++++++++ Network ++++++++++++++++++++ +++ ++++++++++++

void handleCommand(EthernetClient client, char* cmd, char* param) {

  Serial.println("Handle command cmd and param: ");

  Serial.println(cmd);

  Serial.println(param);

  

  if (strcmp(cmd, "state") == 0) {

    Serial.println(F("### Computing: state"));

    sendStatusJSON(client, false);

  }

  else if (strcmp(cmd, "setPower") == 0) {

    Serial.println(F("### Computing: power"));

    if(strcmp(param, "on")==0){

        //setOn();  

        sendJSON (client, F("statePower"), F("\"On\""));

    }

    else if(strcmp(param, "off")==0){

        //setOff();

        sendJSON (client, F("statePower"), F("\"Off\""));

    }

    else if(strcmp(param, "standby")==0){

        //setStandBy();

        sendJSON (client, F("statePower"), F("\"standby\""));

    }

    

  }

  else if (strcmp(cmd, "resetIP") == 0) {

    //resetIP();

    sendJSON (client, F("cmd"), F("\"Trying to reset IP address\""));

  }

  else if (strcmp(cmd, "setIP") == 0) {

    Serial.println(F("### Computing: setIP"));

    sendJSON (client, F("cmd"), F("\"Trying to change IP address\""));

    //storedIP = parseIP(param);

    //Ethernet.setLocalIP(storedIP);

    Serial.print(F("server is at "));

    Serial.println(Ethernet.localIP());

  }

  else if (strcmp(cmd, "setIPProj") == 0) {

    Serial.println(F("### Computing: setIP Projector"));

    sendJSON (client, F("cmd"), F("\"Changing my record of IP address of Projector\""));

    //storedIP_Projector = parseIP(param);

  }

  else {

    send404(client);

  }

}

// ++++++++++++++++++++ +++ ++++++++++++ Send Answers ++++++++++++++++++++ +++ ++++++++++++

void send404(EthernetClient client) {

  client.println(F("HTTP/1.1 404 OK"));

  client.println(F("Content-Type: text/html"));

  client.println(F("Access-Control-Allow-Headers: *"));

  client.println(F("Access-Control-Allow-Origin: *"));

  client.println(F("Access-Control-Allow-Methods: *"));

  client.println(F("Connnection: close"));

  client.println();

  client.println(F("<!DOCTYPE HTML>"));

  client.println(F("<html><body>404</body></html>"));

}

void sendJSON(EthernetClient client, String description, String value) {

  client.println(F("HTTP/1.1 200 OK"));

  client.println(F("Content-Type: application/json"));

  client.println(F("Access-Control-Allow-Headers: *"));

  client.println(F("Access-Control-Allow-Origin: *"));

  client.println(F("Access-Control-Allow-Methods: *"));

  client.println(F("Connnection: close"));

  client.println();

  client.println(F("{"));

  client.print(F("\t\"")); client.print(description); client.print(F("\": "));

  client.print(value);

  client.println();

  client.println(F("}"));

  client.println(F("\n"));

  return;

}

void sendStatusJSON(EthernetClient client, boolean expert) {

  client.println(F("HTTP/1.1 200 OK"));

  client.println(F("Content-Type: application/json"));

  client.println(F("Access-Control-Allow-Headers: *"));

  client.println(F("Access-Control-Allow-Origin: *"));

  client.println(F("Access-Control-Allow-Methods: *"));

  client.println(F("Connnection: close"));

  client.println();

  client.println(F("{"));

  client.print(F("\t\"state-.-.-.-.-.\": "));

  client.println(F(","));

  client.println();

  client.println(F("}"));

  client.println(F("\n"));

  return;

}

// ++++++++++++++++++++ +++ ++++++++++++ Webserver ++++++++++++++++++++ +++ ++++++++++++

char** parse(char* str) {

  char ** messages;

  messages = (char**)malloc(sizeof(char *));

  char *p;

  p = strtok(str, " ");

  unsigned int i = 0;

  while (p != NULL) {

    p = strtok(NULL, "/");

    char *sp;

    boolean last = false;

    sp = strchr(p, ' ');

    if (sp != NULL) {

      *sp++ = '\0';

      last = true;

    }

    messages[i] = p;

    i++;

    if (last) {

      break;

    }

    messages = (char**)realloc(messages, sizeof(char *) * i + 1);

  }

  messages[i] = '\0';

  return messages;

}

int countSegments(char* str) {

  int p = 0;

  int count = 0;

  while (str[p] != '\0') {

    if (str[p] == '/') {

      count++;

    }

    p++;

  }

  count--;

  return count;

}

void handleTraffic() {

  char buffer[STRING_BUFFER_SIZE];

  EthernetClient client = server.available();

  if (client) {

    boolean currentLineIsBlank = true;

    while (client.connected()) {

      if (client.available()) {

        char c;

        int bufindex = 0; // reset buffer

        buffer[0] = client.read();

        buffer[1] = client.read();

        bufindex = 2;

        while (buffer[bufindex - 2] != '\r' && buffer[bufindex - 1] != '\n') {

          c = client.read();

          if (bufindex < STRING_BUFFER_SIZE) {

            buffer[bufindex] = c;

          }

          bufindex++;

        }

        bufindex = 0;

        int nSegments = countSegments(buffer);

        char **pathsegments = parse(buffer);

        if (c == '\n' && currentLineIsBlank) {

          handleCommand(client, pathsegments[0], pathsegments[1]);

          break;

        }

        if (c == '\n') {

          currentLineIsBlank = true;

        } else if (c != '\r') {

          currentLineIsBlank = false;

        }

      }

    }

    delay(100);

    client.stop();

    Serial.println(F("Request answered"));

  }

}

And not a String in sight.
You use
messages = (char**)malloc(sizeof(char ));
and
messages = (char
*)realloc(messages, sizeof(char *) * i + 1);

But I cannot see anywhere you release the memory.

You may as well use String that does the allocation/reallocation for you.
See Taming Arduino Strings re passing String by reference (String &)
Although you will need to do some minor rewrites to your parser :frowning:

Also if this is ESP32 or ESP8266 you may just need to reboot every now and again to clean up the underlying Wifi library
see Out-Of-Memory on ESP32 and ESP8266 – Add Periodic Automatic Reboots for the code.